09 OpenCV图形检测

news2024/11/18 7:48:48

1 轮廓描边

cv2.findContours() 函数是OpenCV中用于寻找轮廓的函数之一。它可以用于在二值图像中查找并检测出所有的物体轮廓,以及计算出这些轮廓的各种属性,例如面积、周长、质心等。
cv2.findContours() 函数的语法如下:

contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

其中,参数含义如下:

  • image:输入二值图像。
  • mode:轮廓检索模式。有三种可选模式:cv2.RETR_EXTERNAL,表示只检测外部轮廓;cv2.RETR_LIST,表示检测所有轮廓,并将它们存储在列表中;cv2.RETR_TREE,表示检测所有轮廓,并构建轮廓的完整层次结构。
  • method:轮廓近似方法。有四种可选方法:cv2.CHAIN_APPROX_NONE,表示存储所有的轮廓点;cv2.CHAIN_APPROX_SIMPLE,表示仅存储轮廓的终点坐标;cv2.CHAIN_APPROX_TC89_L1cv2.CHAIN_APPROX_TC89_KCOS,表示使用Teague的链逼近算法来压缩轮廓点。
  • contours:可选参数,用于存储检测到的轮廓。如果提供了该参数,则函数会将轮廓存储在该参数中。
  • hierarchy:可选参数,用于存储轮廓的层次结构信息。如果提供了该参数,则函数会将层次结构信息存储在该参数中。
  • offset:可选参数,指定检测到的轮廓点的偏移量。默认为 (0, 0)

cv2.findContours() 函数会返回两个值:contourshierarchy。其中,contours 是一个包含所有检测到的轮廓的Python列表,每个轮廓都是由一组点构成的Numpy数组。而 hierarchy 是一个包含轮廓的层次结构信息的Numpy数组。

因为输入图像必须是二值图像,所以需要先将彩色图像转变为灰度图像,再转换为二值图像,才能输入进参数值中。

下面尝试对前面文章的主图进行描边:

import cv2  
  
# 读入图像  
img = cv2.imread('test.png')  
  
# 将图像转换为灰度图像  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  
# 对灰度图像进行二值化处理  
ret, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)  
  
# 查找轮廓  
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  
  
# 在图像上绘制轮廓  
cv2.drawContours(img, contours, -1, (0, 0, 255), 1)  
  
# 显示结果  
cv2.imshow('Original', img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

image.png
这段代码首先使用 cv2.imread() 函数读入图像,然后使用 cv2.cvtColor() 函数将该图像转换为灰度图像。接着,我们对灰度图像进行了二值化处理,并使用 cv2.findContours() 函数查找图像中的轮廓。最后使用 cv2.drawContours() 函数将所有轮廓绘制在原始图像上,并使用 cv2.imshow() 函数显示处理后的图像。

2 轮廓拟合

轮廓拟合可以将凹凸不平的轮廓以平滑曲线进行连接。常用的有矩形拟合cv2.boundingRect和圆形拟合cv2.minEnclosingCircle。二者都是在cv2.findContours()的基础上进行拟合。

2.1 最小外接矩形

cv2.boundingRect() 函数可以用于计算轮廓的最小外接矩形,即将轮廓拟合到一个矩形框中,并返回该矩形框的左上角坐标以及宽度和高度。该函数的语法如下:

x, y, w, h = cv2.boundingRect(contour)

其中,contour 是一个Numpy数组,表示待计算的轮廓。函数返回的 xy 分别表示最小外接矩形的左上角坐标,而 wh 则分别表示矩形的宽度和高度

2.2 最小外接圆

cv2.minEnclosingCircle() 函数可以用于计算轮廓的最小外接圆,即将轮廓拟合到一个圆形中,并返回该圆的圆心坐标和半径。该函数的语法如下:

(x, y), radius = cv2.minEnclosingCircle(contour)

其中,contour 是一个Numpy数组,表示待计算的轮廓。函数返回的 (x, y) 是最小外接圆的圆心坐标,而 radius 则是圆的半径。

2.3 示例代码

import cv2  
  
# 读入图像  
img = cv2.imread('test.png')  
  
# 将图像转换为灰度图像  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  
# 对灰度图像进行二值化处理  
ret, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)  
  
# 查找轮廓  
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  
  
# 绘制最小外接矩形和最小外接圆  
for contour in contours:  
    # 计算最小外接矩形  
    x, y, w, h = cv2.boundingRect(contour)  
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)  
  
    # 计算最小外接圆  
    (x, y), radius = cv2.minEnclosingCircle(contour)  
    center = (int(x), int(y))  
    radius = int(radius)  
    cv2.circle(img, center, radius, (0, 255, 0), 2)  
  
# 显示结果  
cv2.imshow('Original', img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

最终,基本上每个文章都被画上了矩形框与圆形框。
image.png

3 凸包

OpenCV中的凸包是一个用于计算给定点集的凸包形状的函数。凸包是一个包围给定点集的最小凸多边形或凸多面体。凸多边形或凸多面体的特点是其边缘不会凹陷(可以理解为不会有大于180°的角),而是向外弯曲,使得所有点都位于其内部或边缘上。

在OpenCV中,可以使用cv2.convexHull()函数来计算给定点集的凸包。该函数接受一个点集作为输入,并返回凸包形状的点集。该函数使用的算法称为Graham-Scan算法,该算法在O(n log n)时间内计算给定点集的凸包。
示例代码如下:

import cv2  
  
# 读入图像  
img = cv2.imread('test.png')  
  
# 将图像转换为灰度图像  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  
# 对灰度图像进行二值化处理  
ret, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)  
  
# 查找轮廓  
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  
  
# 绘制凸包  
for contour in contours:  
    hull = cv2.convexHull(contour)  
    cv2.polylines(img, [hull], True, (0, 0, 255), 2)  
  
# 显示结果  
cv2.imshow('Original', img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

image.png

4 Canny边缘检测

Canny边缘检测是一种广泛使用的方法,用于检测图像中的边缘。在OpenCV中,可以使用cv2.Canny()函数来执行Canny边缘检测。

cv2.Canny()函数使用以下步骤来检测图像中的边缘:

  1. 降噪:使用高斯滤波器对输入图像进行模糊处理,以减少图像中的噪声。
  2. 计算梯度:对模糊图像使用Sobel算子来计算图像中每个像素的梯度。这可以帮助识别像素值变化最剧烈的位置,即可能的边缘。
  3. 非极大值抑制:在图像中沿着梯度方向找到局部最大值,将它们保留为可能的边缘点,而抑制其他非最大值的像素点。
  4. 双阈值检测:根据两个阈值(高阈值和低阈值)将可能的边缘点分类为强边缘和弱边缘。如果像素值大于高阈值,则被标记为强边缘;如果像素值在低阈值和高阈值之间,则被标记为弱边缘。如果像素值低于低阈值,则被抑制。
  5. 边缘连接:在图像中连接强边缘,并删除与弱边缘不相连的弱边缘。

通过调整高阈值和低阈值,可以影响Canny边缘检测的结果。较高的阈值将产生更少的强边缘,而较低的阈值将产生更多的弱边缘。通常建议将高阈值设置为低阈值的3到2倍之间。

下面的代码展示了阈值对边缘检测的影响:

import cv2  
img = cv2.imread("test.png")  # 读取原图  
r1 = cv2.Canny(img, 25, 50)  # 使用不同的阈值进行边缘检测  
r2 = cv2.Canny(img, 100, 200)  
r3 = cv2.Canny(img, 200, 400)  
  
cv2.imshow("img", img)  
cv2.imshow("r1", r1)  # 显示边缘检测结果  
cv2.imshow("r2", r2)  
cv2.imshow("r3", r3)  
cv2.waitKey()  
cv2.destroyAllWindows()

image.png

5 霍夫变换

霍夫变换(Hough Transform)是一种常见的图像处理技术,用于检测图像中的各种形状。在OpenCV中,可以使用cv2.HoughLines()和cv2.HoughCircles()函数来执行霍夫变换。

5.1 检测直线

cv2.HoughLines()函数用于检测二维平面上的直线。该函数接受二值化图像和一些可选参数作为输入,并返回检测到的直线的端点坐标。在进行霍夫变换之前,需要使用cv2.Canny()函数对输入图像进行边缘检测。函数将返回一个二维数组,其中每一行表示检测到的一条直线的两个端点坐标。
cv2.HoughLines()函数语法如下:

lines = cv2.HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None)

其中,参数含义如下:

  • image:输入的二值化图像,即通过cv2.Canny()等函数得到的边缘图像。
  • rho:表示距离精度,以像素为单位。通常取值为1。
  • theta:表示角度精度,以弧度为单位。通常取值为np.pi/180,表示以1度为单位。
  • threshold:表示在霍夫空间中的最小投票数,用于确定一条直线是否存在。通常取值范围为0到图像宽高之和的一半。
  • lines:可选输出参数,用于存储检测到的直线,以numpy.ndarray格式返回。
  • srn:可选参数,表示霍夫梯度中径向和角度分辨率之间的参数,通常取默认值0。
  • stn:可选参数,表示霍夫梯度中两个角度之间的分辨率,通常取默认值0。
  • min_thetamax_theta:可选参数,表示需要检测的直线的角度范围,以弧度为单位。

该函数将返回一个包含检测到的直线的端点坐标的numpy.ndarray数组。数组中每一行表示检测到的一条直线,包括两个端点的rho和theta值。

霍夫变换是一种计算密集型算法,处理大型图像时可能需要一定的计算时间。此外,霍夫变换对输入图像的质量要求较高,因此必须在边缘检测和二值化等预处理步骤上进行仔细的参数调整和图像优化,以获得最佳结果。
检测图像中存在直线的代码:

import cv2  
import numpy as np  
  
img = cv2.imread("test.png")  # 读取原图  
o = img.copy()  # 复制原图  
o = cv2.medianBlur(o, 5)  # 使用中值滤波进行降噪  
gray = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)  # 从彩色图像变成单通道灰度图像  
binary = cv2.Canny(o, 50, 150)  # 绘制边缘图像  
# 检测直线,精度为1,全角度,阈值为100,线段最短100,最小间隔为30  
lines = cv2.HoughLinesP(binary, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=30)  
for line in lines:  
    x1, y1, x2, y2 = line[0]  # 读取直线两个端点的坐标  
    cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)  # 在原始图像上绘制直线  
cv2.imshow("canny", binary)   
cv2.imshow("img", img)  
cv2.waitKey()  
cv2.destroyAllWindows()

image.png

5.2 检测圆形

cv2.HoughCircles()函数用于检测圆形。该函数接受二值化图像、检测算法的参数以及圆的最小和最大半径作为输入,并返回检测到的圆的圆心坐标和半径。函数将返回一个三维数组,其中每个元素表示检测到的一个圆形,包括圆心坐标和半径。
cv2.HoughCircles()函数语法如下:

circles = cv2.HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None)

其中:

  • image:输入的二值化图像,即通过cv2.Canny()等函数得到的边缘图像。
  • method:表示霍夫变换检测圆形的方法。目前支持两种方法:cv2.HOUGH_GRADIENT和cv2.HOUGH_GRADIENT_ALT。
  • dp:表示霍夫梯度中心之间的累加器分辨率的反比例系数。通常取值为1,表示与图像像素一样的分辨率。
  • minDist:表示圆形之间的最小距离,以像素为单位。通常取值为圆形直径的两倍左右。
  • circles:可选输出参数,用于存储检测到的圆形,以numpy.ndarray格式返回。
  • param1:表示边缘检测的高阈值,用于辅助检测图像中的圆形。通常取值为100。
  • param2:表示霍夫变换中的累加器阈值,用于确定检测到的圆形是否存在。通常取值为30到50之间。
  • minRadiusmaxRadius:可选参数,表示需要检测的圆形的半径范围,以像素为单位。

该函数将返回一个包含检测到的圆形的圆心坐标和半径的numpy.ndarray数组。数组中每一行表示检测到的一个圆形,包括三个参数:圆心坐标x、y和半径r。

代码使用与检测直线非常相似,这里就不写示例代码了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

张杰清唱高启强专属BGM简直就是天作之合,千万别点进来看

张杰清唱高启强专属BGM简直就是天作之合,千万别点进来看,#张杰#BGM#音乐 张杰演唱的《听》狂飙高启强自从出现在抖音上更是火得不可思议,它成为了不少年轻人喜爱的BGM,尤其是用它作为专属BGM的抖音视频更是受到网友的一致好评。 …

详解如何在ChatGPT内构建一个Python解释器

这篇文章主要为大家详细介绍了如何在ChatGPT内构建一个Python解释器,文中的示例代码讲解详细,具有一定的学习价值,需要的可以参考一下目录引用:Art Kulakov 《How to Build a Python Interpreter Inside ChatGPT》这个灵感来自于一…

Day892.MySql读写分离过期读问题 -MySQL实战

MySql读写分离过期读问题 Hi,我是阿昌,今天学习记录的是关于MySql读写分离过期读问题的内容。 一主多从架构的应用场景:读写分离,以及怎么处理主备延迟导致的读写分离问题。 一主多从的结构,其实就是读写分离的基本…

Java SE(1)——JDK安装,基本数据类型和运算

JDK安装,基本数据类型和运算 一 Java语言的初体验 1.JDK下载地址 Oracle官网: Java Downloads | Oracle,根据需要,下载最新或历史版本。 2.运行Java文件 编写一个简单的 HelloWorld.java 文件 public class HelloWorld{publ…

提供网络可测试的接口【公共Webservice】

提供网络可测试的接口 1、腾讯QQ在线状态 WEB 服务 Endpoint: qqOnlineWebService Web 服务 Disco: http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?disco WSDL: http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl 腾讯QQ在线状态 WEB 服…

【每日一题】 将一句话单词倒置,标点不倒置

用C语言将一句话的单词倒置,标点不倒置。 比如输入: i like shanghai. 输出得到: shanghai. like i 这道题目有很多种做法,既可以用递归,也可以分成两部分函数来写,本文就详细来讲解分装为两个函数的做法。…

如何从0开始搭建Vue组件库

前言: 组件设计是通过对功能及视觉表达中元素的拆解、归纳、重组,并基于可被复用的目的,形成规范化的组件,通过多维度组合来构建整个设计方案,將这些组件整理在一起,便形成组件库。本文我们主要讲述基于 V…

微服务学习:SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

目录 一、高级篇 二、面试篇 实用篇 day05-Elasticsearch01 安装elasticsearch 1.部署单点es 2.部署kibana 一、高级篇 二、面试篇 实用篇 day05-Elasticsearch01 安装elasticsearch 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器,因此需要…

高校房产管理系统用到了哪些技术?

数图互通高校房产管理系统是基于公司自主研发的FMCenterV5.0平通过在中国100多所高校的成功实施和迭代,形成了一套成熟、完善、全生命周期的房屋资源管理解决方案。台,是针对中国高校房产的管理特点和管理要求,研发的一套标准产品&#xff1b…

【代码随想录训练营】【Day17】第六章|二叉树|110.平衡二叉树|257. 二叉树的所有路径|404.左叶子之和

平衡二叉树 题目详细:LeetCode.110 由题可知:一个平衡二叉树需要满足,其每个节点的左右两个子树的高度差的绝对值不超过 1 。 我们可以依照题意,直接来一波模拟: 利用层序遍历(或其他遍历方法&#xff…

@所有人,OceanBase DevCon • 2023来啦

本文by:即将与大家见面的 OceanBase 2010 年,OceanBase 第一个版本诞生。在过去的十三年里,我们的产品技术,从支付宝走向众多企业,跟随着开源和云的成长,逐渐成为开发者喜欢的数据库。 2023 年 3 月 25 日…

MySQL的日志详解

目录 一.介绍 日志分类 二.错误日志 三.二进制日志—binlog 概述 日志格式 操作 四.查询日志 五.慢查询日志 一.介绍 在任何一种数据库中,都会有各种各样的日志,记录着数据库工作的方方面面,以帮助数据库管理员追踪数据库曾经发生过的…

IP路由基础

——IP路由基础(IA)—— ​​​​​​​HCIA全套笔记已经上线(arpAAAvlanTrunk链路聚合vlan间通信ACL广域网技术以太网交换...........)_孤城286的博客-CSDN博客 目录 ——IP路由基础(IA)—— (1&#…

【Debug】Centos 7 下部署 ElasticSearch 及 Kibana 时踩过的坑

Windows 电脑安装的 Centos 7 都是 X86_64版本, 但是 MAC 电脑 M1 芯片安装的是 arm 64 版本的 Centos 7, 这就导致有些镜像的安装可能会出现问题. 如果拉取速度比较慢, 修改镜像源, 如我的镜像源如下: 执行创建或修改镜像源指令: vim /etc/docker/daemon.json, 然后将下面的内…

【CMU15-445数据库】bustub Project #2:B+ Tree(上)

(最近两个月学校项目有亿点忙,鸽得有点久,先来把 Project 2 补上) 本节实验文档地址:Project #2 - BTree Project 2 要实现的是数据结构课上都会讲的一个经典结构 B 树,但是相信大多数的同学(…

vue中,给一个URL地址,利用FileSaver.js插件下载文件到本地

①首先下载 FileSaver.js 插件 npm install file-saver --save ②在需要的.vue页面引入 import { saveAs } from file-saver 在HTML中引入 <script src"https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> //Fil…

k8s 安装dashboard

前言 上一篇中将k8s简单部署安装上了&#xff0c;这篇接着安装下dashboard。 具体步骤 下载yaml文件 wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml注意&#xff1a;这里使用的版本是v2.5.0&#xff0c;这个要和k8s的版…

褪去大厂光环下的功能测试,出去面试自动化居然一问三不知......不淘汰你淘汰谁呢

在一家公司待久了技术能力反而变弱了&#xff0c;原来的许多知识都会慢慢遗忘&#xff0c;这种情况并不少见。 一个京东员工发帖吐槽&#xff1a;感觉在大厂快待废了&#xff0c;出去面试问自己接口环境搭建、pytest测试框架&#xff0c;自己做点工太久都忘记了。平时用的时候…

CCF-CSP真题《202212-2 训练计划》思路+python题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202212-2试题名称&#xff1a;训练计划时间限制&#xff1a;1.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题背景 西西艾弗岛荒野求生大赛还有 n 天开幕&#xf…

总结Anisble中的任务执行控制并练习

文章目录一、循环1.简单循环2.循环散列或字典列表二、条件三、触发器四、处理失败任务1.ignore_errors2.force_handlers3.changed_when4.failed_when5.block五、 练习建立大小为1500M名为/dev/sdb1的设备利用ansible循环安装且开启vsftpd&#xff0c;apache&#xff0c;dns&…