【python】OpenCV—findContours(4.3)
文章目录
- 1、功能描述
- 2、代码实现
- 3、完整代码
- 4、结果展示
- 5、涉及到的库函数
- 5.1、cv2.Canny
- 5.2 cv2.boxPoints
- 6、参考
1、功能描述
找出图片中的轮廓,拟合轮廓外接椭圆和外接矩阵
2、代码实现
导入必要的库,固定好随机种子
import cv2 as cv
import numpy as np
import argparse
import random as rngrng.seed(12345)
读取输入图片,判定图片是否读入成功
parser = argparse.ArgumentParser(description='Code for Creating Bounding rotated boxes and ellipses for contours tutorial.')
parser.add_argument('--input', help='Path to input image.', default='1.png')
args = parser.parse_args()
src = cv.imread(cv.samples.findFile(args.input))if src is None:print('Could not open or find the image:', args.input)exit(0)
灰度化图片,并平滑
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3, 3))
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
创建滚动条,动态配置参数,随着滑动条的滑动实现不同的算法效果
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
算法核心函数 thresh_callback
,下面具体看看细节
def thresh_callback(val):global src_graythreshold = valsrc_gray = cv.GaussianBlur(src_gray, (3, 3), 0.1)canny_output = cv.Canny(src_gray, threshold, threshold * 2)
高斯模糊,canny 算子
contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)# Find the rotated rectangles and ellipses for each contourminRect = [None] * len(contours)minEllipse = [None] * len(contours)for i, c in enumerate(contours):minRect[i] = cv.minAreaRect(c)if c.shape[0] > 5:minEllipse[i] = cv.fitEllipse(c)# Draw contours + rotated rects + ellipses
找出轮廓,遍历轮廓,最小外接矩形框直接调用 cv2.minAreaRect
即可
如果轮廓多于 5 个点,cv2.fiEllipse
找椭圆
# Draw contours + rotated rects + ellipsesdrawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)for i, c in enumerate(contours):color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))# contourcv.drawContours(drawing, contours, i, color)# ellipseif c.shape[0] > 5:cv.ellipse(drawing, minEllipse[i], color, 2)# rotated rectanglebox = cv.boxPoints(minEllipse[i])# box = cv.boxPoints(minRect[i])box = np.intp(box) # np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)# box = np.int0(box) # normally either int32 or int64)cv.drawContours(drawing, [box], 0, color)cv.imshow('Contours', drawing)cv.imshow("Canny", canny_output)
绘制轮廓,轮廓外接矩阵,轮廓拟合出来的椭圆,随机颜色
注意 box = cv.boxPoints(minEllipse[i])
绘制的是椭圆的外接矩阵,而 box = cv.boxPoints(minRect[i])
绘制轮廓的外接矩阵被注释掉了
3、完整代码
import cv2 as cv
import numpy as np
import argparse
import random as rngrng.seed(12345)def thresh_callback(val):global src_graythreshold = valsrc_gray = cv.GaussianBlur(src_gray, (3, 3), 0.1)canny_output = cv.Canny(src_gray, threshold, threshold * 2)contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)# Find the rotated rectangles and ellipses for each contourminRect = [None] * len(contours)minEllipse = [None] * len(contours)for i, c in enumerate(contours):minRect[i] = cv.minAreaRect(c)if c.shape[0] > 5:minEllipse[i] = cv.fitEllipse(c)# Draw contours + rotated rects + ellipsesdrawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)for i, c in enumerate(contours):color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))# contourcv.drawContours(drawing, contours, i, color)# ellipseif c.shape[0] > 5:cv.ellipse(drawing, minEllipse[i], color, 2)# rotated rectanglebox = cv.boxPoints(minEllipse[i])# box = cv.boxPoints(minRect[i])box = np.intp(box) # np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)# box = np.int0(box) # normally either int32 or int64)cv.drawContours(drawing, [box], 0, color)cv.imshow('Contours', drawing)cv.imshow("Canny", canny_output)parser = argparse.ArgumentParser(description='Code for Creating Bounding rotated boxes and ellipses for contours tutorial.')
parser.add_argument('--input', help='Path to input image.', default='1.png')
args = parser.parse_args()
src = cv.imread(cv.samples.findFile(args.input))if src is None:print('Could not open or find the image:', args.input)exit(0)# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3, 3))
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
4、结果展示
Canny Thresh:0
Canny Thresh:5
Canny Thresh:15
Canny Thresh:25
Canny Thresh:35
Canny Thresh:45
Canny Thresh:100
Canny Thresh:150
Canny Thresh:200
Canny Thresh:255
5、涉及到的库函数
5.1、cv2.Canny
cv2.Canny
是 OpenCV 库中用于边缘检测的一个函数,它实现了 Canny 边缘检测算法。Canny 边缘检测是一种非常流行的边缘检测算法,由 John F. Canny 在 1986 年提出。这个算法旨在寻找图像中的最优边缘,它通过应用多尺度高斯滤波来减少噪声,然后计算图像梯度,接着通过非极大值抑制和滞后阈值化来检测边缘。
edges = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
- image:输入的灰度图像。在进行 Canny 边缘检测之前,通常需要先将图像转换为灰度图像。
- threshold1:第一个阈值,用于滞后阈值化中的低阈值。
- threshold2:第二个阈值,用于滞后阈值化中的高阈值。只有那些梯度值高于 threshold2 的像素才会被当作边缘,而梯度值位于 threshold1 和 threshold2 之间的像素只有在它们连接到高阈值边缘时才会被接受。
- edges:输出参数,用于存储检测到的边缘。如果不指定,则会自动创建一个同大小的输出图像。
- apertureSize:Sobel 算子的大小,默认为 3。这个参数影响梯度计算的精度,但增加大小也会增加计算时间。
- L2gradient:一个布尔值,指示是否使用更精确的 L2 范数来计算图像梯度幅值。默认值为 False,即使用 L1 范数(即简单地将梯度在 x 和 y 方向的分量相加)。
返回值:
- edges:一个二值图像,其中检测到的边缘像素被设置为白色(255),其他像素被设置为黑色(0)。
Canny 边缘检测的优点在于它能够有效地抑制噪声,并且检测到的边缘通常是连续的。然而,它的效果也依赖于所选的阈值,因此在实际应用中,可能需要根据具体情况调整 threshold1 和 threshold2 的值。
5.2 cv2.boxPoints
cv2.boxPoints
用于计算给定矩形旋转后的顶点坐标。这个函数在需要处理旋转矩形时非常有用,比如在图像中绘制旋转的边界框时。
points = cv2.boxPoints(box[, rotMat])
参数解释:
- box:表示矩形的参数。这可以是一个包含四个元素的元组或列表 (center_x, center_y, width, height),其中 (center_x, center_y) 是矩形中心的坐标,width 和 height 分别是矩形的宽度和高度(注意:这里的宽度和高度是按照矩形的原始大小,不考虑旋转)。在某些版本的 OpenCV 中,box 也可能是一个 cv2.RotatedRect 对象。
- rotMat:可选参数,表示旋转矩阵。这是一个 2x3 的浮点数数组,用于指定对矩形进行额外旋转的角度。如果未提供此参数,则矩形不会被额外旋转,只返回根据 box 参数计算出的四个顶点坐标。
返回值:
- points:一个包含四个点的 NumPy 数组,每个点都是一个包含两个元素的元组或列表 (x, y),表示旋转后矩形的顶点坐标。
需要注意的是,如果 box 是一个 cv2.RotatedRect 对象,那么它本身就包含了旋转信息(即旋转角度和中心点),此时 rotMat 参数将被忽略,因为 cv2.RotatedRect 已经定义了矩形的旋转状态。
示例代码:
import cv2
import numpy as np # 定义一个中心点、宽度、高度的矩形
center = (100, 100)
width = 200
height = 100
angle = 45 # 旋转角度(以度为单位) # 创建一个旋转矩形对象
rect = cv2.RotatedRect(center, (width, height), angle) # 获取旋转矩形的顶点
points = cv2.boxPoints(rect)
points = np.intp(points) # 将坐标转换为整数类型,以便在图像上绘制 # 创建一个黑色图像
image = np.zeros((256, 256, 3), dtype=np.uint8) # 在图像上绘制旋转矩形的边
for i in range(4): cv2.line(image, tuple(points[i]), tuple(points[(i+1)%4]), (255, 0, 0), 2)
# 显示图像
cv2.imshow('Rotated Rectangle', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在这个示例中,我们首先定义了一个矩形的中心点、宽度、高度和旋转角度,然后创建了一个 cv2.RotatedRect 对象来表示这个旋转矩形。接着,我们使用 cv2.boxPoints 函数来获取旋转矩形的顶点坐标,并在一个黑色图像上绘制了这个矩形的边。最后,我们显示了包含旋转矩形的图像。
6、参考
- 根据轮廓创建旋转框和椭圆
- 【python】OpenCV—findContours(4.2)
相关文章:

【python】OpenCV—findContours(4.3)
文章目录 1、功能描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数5.1、cv2.Canny5.2 cv2.boxPoints 6、参考 1、功能描述 找出图片中的轮廓,拟合轮廓外接椭圆和外接矩阵 2、代码实现 导入必要的库,固定好随机种子 import cv2 as cv import …...

前端通过nginx部署一个本地服务的方法
前端通过nginx部署一个本地服务的方法: 1.下载ngnix nginx 下载完成后解压缩后运行nginx.exe文件 2.打包你的前端项目文件 yarn build 把生成的dist文件复制出来,替换到nginx的html文件下 3.配置conf目录的nginx.conf文件 主要配置server监听 ser…...

Linux:防火墙和selinux对服务的影响
1-1selinux 1-1 SELinux是对程序、文件等权限设置依据的一个内核模块。由于启动网络服务的也是程序,因此刚好也 是能够控制网络服务能否访问系统资源的一道关卡。 1-2 SELinux是通过MAC的方式来控制管理进程,它控制的主体是进程,而目标则是…...

从 vue 源码看问题 — vue 如何进行异步更新?
前言 在上一篇 如何理解 vue 响应式? 中,了解到响应式其实是通过 Observer 类中调用 defineReactive() 即 Object.defineProperty() 方法为每个目标对象的 key(key 对应的 value 为非数组的) 设置 getter 和 setter 实现拦截&…...

【go从零单排】go中的基本数据类型和变量
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 基本类型 go中的string、int、folat都可以用连接boolen可以用逻辑表达式计算 package mainimport "fmt&quo…...

标签之文字排版,图片,链接,音视频(HTML) 基础版
目录 标签之文字排版,图片,链接,音视频知识点: 练习题一: 效果: 练习题二: 效果: 标签之文字排版,图片,链接,音视频知识点: 超文本:链接 标记:标签<> 双标签 单标签 <br>//换行 <hr>//水平线 向后tab 向前shifttab html注释<!----> css /**/ …...

基于SpringBoot+Gpt个人健康管家管理系统【提供源码+答辩PPT+参考文档+项目部署】
作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...
十四届蓝桥杯STEMA考试Python真题试卷第二套第一题
来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第一题 题目描述: 给定一个字符串,输出字符串中最后一个字符。 输入描述: 输入一个字符串 输出描述: 输出字符串中最后一个字符 样例输入: hgf 样…...

【Windows修改Docker Desktop(WSL2)内存分配大小】
记录一下遇到使用Docker Desktop占用内存居高不下的问题 自从使用了Docker Desktop,电脑基本每天都需要重启,内存完全不够用,从16g扩展到24,然后到40G,还是不够用;打开Docker Desktop 运行时间一长&#x…...

阿里云-部署CNI flannel集群网络
环境 1.一台阿里云作为k8s-master:8.130.XXX.231(阿里云私有IP) 2.Vmware 两个虚拟机分别作为 k8s-node1:192.168.40.131 k8s-node2:192.168.40.131 3.安装Docker 部署过程 k8s-master,k8s-node1,k8s-node2 初始操作 # 关闭防火墙 systemctl stop fi…...

favicon是什么文件?如何制作网站ico图标?
一般我们做网站的话,都会制作一个独特的ico图标,命名为favicon.ico。这个ico图标一般会出现在浏览器网页标题前面。如下图红色箭头所示: 部分博客导航大全也会用到所收录网站的ico图标。比如boke123导航新收录的网站就不再使用网站首页缩略图…...
Linux云计算个人学习总结(一)
windows计算机基础 一、概述 1.计算机基本原则:计算机是执行输入、运算、输出的原则。软件是指命令和数据的结合,计算机中所有的内容皆为数字。 2.计算机的类型 计算器 手机 cps等都属于计算机。 3.计算机的发展 第一代计算机电子管时代&…...

DCRNN解读(论文+代码)
一、引言 作者首先提出:空间结构是非欧几里得且有方向性的,未来的交通速度受下游交通影响大于上游交通。虽然卷积神经网络(CNN)在部分研究中用于建模空间相关性,但其主要适用于欧几里得空间(例如二维图像&a…...

雷池社区版新版本功能防绕过人机验证解析
前两天,2024.10.31,雷池社区版更新7.1版本,其中有一个功能,新增请求防重放 更新记录:hhttps://docs.waf-ce.chaitin.cn/zh/%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95 仔细研究了这个需求,…...

一文详解开源ETL工具Kettle!
一、Kettle 是什么 Kettle 是一款开源的 ETL(Extract - Transform - Load)工具,用于数据抽取、转换和加载。它提供了一个可视化的设计环境,允许用户通过简单的拖拽和配置操作来构建复杂的数据处理工作流,能够处理各种数…...

《IMM交互式多模型滤波MATLAB实践》专栏目录,持续更新……
专栏链接:https://blog.csdn.net/callmeup/category_12816762.html 专栏介绍 关于IMM的例程 双模型EKF: 【逐行注释】基于CV/CT模型的IMM|MATLAB程序|源代码复制后即可运行,无需下载三模型EKF: 【matlab代码】3个模型的IMM例程&…...
解决数据集中xml文件类别标签的首字母大小写不一致问题
import os import xml.etree.ElementTree as ET# 指定要处理的 XML 文件夹路径 xml_folder_path rD:\CVproject\ultralytics-main\datatrans\Annotationsdef capitalize_first_letter_in_xml(xml_file):# 解析 XML 文件tree ET.parse(xml_file)root tree.getroot()# 遍历所有…...

手边酒店多商户版V2源码独立部署_博纳软云
新版采用laraveluniapp开发,为更多平台小程序开发提供坚实可靠的底层架构基础。后台UI全部重写,兼容手机端管理。 全新架构、会员卡、钟点房、商城、点餐、商户独立管理...

32位汇编——通用寄存器
通用寄存器 什么是寄存器呢? 计算机在三个地方可以存储数据,第一个是把数据存到CPU中,第二个把数据存到内存中,第三个把数据存到硬盘上。 那这个所谓的寄存器,就是CPU中用来存储数据的地方。那这个寄存器有多大呢&a…...

vue3项目中实现el-table分批渲染表格
开篇 因最近工作中遇到了无分页情景下页面因大数据量卡顿的问题,在分别考虑并尝试了懒加载、虚拟滚动、分批渲染等各个方法后,最后决定使用分批渲染来解决该问题。 代码实现 表格代码 <el-table :data"currTableData"borderstyle"wi…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...