【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…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
