当前位置: 首页 > news >正文

【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+参考文档+项目部署】

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第一题

来源&#xff1a;十四届蓝桥杯STEMA考试Python真题试卷第二套编程第一题 题目描述&#xff1a; 给定一个字符串&#xff0c;输出字符串中最后一个字符。 输入描述&#xff1a; 输入一个字符串 输出描述&#xff1a; 输出字符串中最后一个字符 样例输入&#xff1a; hgf 样…...

【Windows修改Docker Desktop(WSL2)内存分配大小】

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

阿里云-部署CNI flannel集群网络

环境 1.一台阿里云作为k8s-master:8.130.XXX.231&#xff08;阿里云私有IP&#xff09; 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图标?

一般我们做网站的话&#xff0c;都会制作一个独特的ico图标&#xff0c;命名为favicon.ico。这个ico图标一般会出现在浏览器网页标题前面。如下图红色箭头所示&#xff1a; 部分博客导航大全也会用到所收录网站的ico图标。比如boke123导航新收录的网站就不再使用网站首页缩略图…...

Linux云计算个人学习总结(一)

windows计算机基础 一、概述 1&#xff0e;计算机基本原则&#xff1a;计算机是执行输入、运算、输出的原则。软件是指命令和数据的结合&#xff0c;计算机中所有的内容皆为数字。 2.计算机的类型 计算器 手机 cps等都属于计算机。 3.计算机的发展 第一代计算机电子管时代&…...

DCRNN解读(论文+代码)

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

雷池社区版新版本功能防绕过人机验证解析

前两天&#xff0c;2024.10.31&#xff0c;雷池社区版更新7.1版本&#xff0c;其中有一个功能&#xff0c;新增请求防重放 更新记录&#xff1a;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 仔细研究了这个需求&#xff0c;…...

一文详解开源ETL工具Kettle!

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

《IMM交互式多模型滤波MATLAB实践》专栏目录,持续更新……

专栏链接&#xff1a;https://blog.csdn.net/callmeup/category_12816762.html 专栏介绍 关于IMM的例程 双模型EKF&#xff1a; 【逐行注释】基于CV/CT模型的IMM|MATLAB程序|源代码复制后即可运行&#xff0c;无需下载三模型EKF&#xff1a; 【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开发&#xff0c;为更多平台小程序开发提供坚实可靠的底层架构基础。后台UI全部重写&#xff0c;兼容手机端管理。 全新架构、会员卡、钟点房、商城、点餐、商户独立管理...

32位汇编——通用寄存器

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

vue3项目中实现el-table分批渲染表格

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

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...