基于OpenCV的轮廓检测(1)

2023-05-16

1.目标

  • 理解什么叫做轮廓
  • 学习如何寻找轮廓以及可视化轮廓
  • 找出轮廓的不同特征,如面积、周长、质心、边框等
  • 将看到许多与轮廓相关的函数。

2.什么叫做轮廓

轮廓可以简单地解释为连接所有连续点(沿着边界)的曲线,具有相同的颜色或者亮度。轮廓是形状分析和目标检测与识别的有效工具。

  • 为了获得更好的准确性,使用二值图像。因此,在找到轮廓之前,应用阈值或canny边缘检测。
  • 从OpenCV 3.2开始,findContours()不再修改源图像。
  • 在OpenCV中,寻找轮廓就像从黑色背景中寻找白色物体。记住,要找到的物体应该是白色,背景应该是黑色。

让我们看看如何找到二值图像的轮廓:

import numpy as np
import cv2 as cv

im = cv.imread('star.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

在cv.findContours()函数中有三个参数,第一个是源图像,第二个是轮廓检索模式,第三个是轮廓逼近方法。它输出轮廓和层次结构。
Contours是图像中所有轮廓的Python列表。每个单独的轮廓都是一个Numpy数组,它是物体边界点的(x,y)坐标。

3.如何画轮廓?

为了画出轮廓,使用cv.drawContours函数。它也可以用来绘制任何形状,只要您有其边界点。它的第一个参数是source image,
第二个参数是应该作为Python列表传递的轮廓,第三个参数是轮廓的索引(在绘制单独的轮廓时很有用。要绘制所有的轮廓,传递-1),
剩下的参数是颜色,厚度等。

  • 画所有轮廓
cv.drawContours(im, contours, -1, (0, 255, 0), 3)
  • 要画一条单独的轮廓线,画第4条轮廓线:
cv.drawContours(im, contours, 3, (0, 255, 0), 3)
  • 但大多数情况下,下面的方法是有用的:
cnt = contours[4]
cv.drawContours(im, [cnt], 0, (0, 255, 0), 3)

4.轮廓近似法
这是cv.findContours函数的第三个参数。它实际上表示什么?
上面,我们说过,轮廓是具有相同强度的形状的边界。它存储形状边界的(x,y)坐标。但是它能存储所有的坐标吗?这是由轮廓近似法确定的。
如果你传递cv.CHAIN_APPROX_NONE,存储所有边界点。但实际上我们需要所有的点吗?例如,你找到了一条直线的轮廓。
你需要直线上所有的点来表示这条直线吗?不,我们只需要这条线的两个端点。这就是cv.CHAIN_APPROX_SIMPLE做的事。它去除所有冗余点并压缩轮廓,从而节省内存。
请添加图片描述

5.Moments

图像矩可以帮助你计算一些特征,如物体的质心,物体的面积等。
函数cv.moments()给出了一个包含所有计算得到的矩值的字典。见下文:

img = cv.imread('star.jpg', 0)
ret2, thresh = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
contours, hierarchy2 = cv.findContours(thresh, 1, 2)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
M = cv.moments(cnt)
print(M)

从这个Moments,你可以提取有用的数据例如面积,质心等。质心获取如下,

cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

6.轮廓面积

轮廓面积由函数cv.contourArea()或矩M[‘m00’]给出。

area = cv.contourArea(cnt)

7.轮廓周长

它也被称为弧长。可以使用cv.arcLength()函数。第二个参数指定形状是闭合轮廓(如果传递True),还是只是曲线。

perimeter = cv.arcLength(cnt, closed=True)

8.轮廓近似

它将一个轮廓形状近似为另一个形状,其顶点数量较少,这取决于我们指定的精度。它是Douglas-Peucker算法的一个实现。
为了理解这一点,假设您试图在图像中找到一个正方形,但由于图像中的一些问题,您没有得到一个完全的正方形,
而是一个“糟糕的形状”(如下面的第一张图像所示)。现在你可以用这个函数来近似这个形状。在这里,第二个参数称为epsilon,
它是轮廓到逼近轮廓的最大距离。

epsilon = 0.1 * cv.arcLength(cnt, True)
approx = cv.approxPolyDP(cnt, epsilon, True)

下图第二幅图中,绿线显示了 epsilon=弧长10%的近似曲线。第三个图片显示epsilon=弧长1%的近似曲线。第三个参数指定曲线是否闭合。
请添加图片描述

9.Convex Hull(凸包)

凸包看起来类似于轮廓逼近,但它不是(两者可能提供相同的结果在某些情况下)。在这里,cvv.convexhull()函数检查曲线的凸性
缺陷并对其进行修正。一般来说,凸曲线是指总是凸起的曲线,或者至少是平坦的曲线。如果内部有凸起,则称为凸性缺陷。
例如,检查下面的图像。红线表示手的凸包。双向箭头表示凸缺陷,即凸包与轮廓的局部最大偏差。
请添加图片描述

关于它的语法有一点需要讨论

hull = cv.convexHull(points[, hull[, clockwise[, returnPoints]]])

参数说明:

  • points表示轮廓
  • hull是输出,通常我们会避开它。
  • clockwise方向标志。如果为真,则输出凸包为顺时针方向。否则,它是逆时针方向的。
  • returnPoints:默认情况下,True。然后它返回凸包点的坐标。如果为False,则返回与凸包点对应的轮廓点索引。

因此,要得到上图中的凸包,以下代码足够的:

hull = cv.convexHull(cnt)

但是如果你想找到凸性缺陷,你需要传递returnPoints = False。为了理解它,我们将以上面的矩形图像为例。
首先我发现它的轮廓是cnt。当returnPoints = True,我得到了以下值:[[234 202]],[[51 202]],[[51 79]],
[[234 79]],这是矩形的四个角点。现在如果对returnPoints = False做同样的事情,我得到以下结果:[[129],[67],[0],[142]]。
这些是轮廓上相应点的索引。例如,检查第一个值:cnt[129] =[[234,202]],它与第一个结果相同(以此类推)

10.检查凸性

有一个函数来检查曲线是否是凸的, cv.isContourConvex()。它只返回True还是False。

k = cv.isContourConvex(cnt)

11.边框

有两种类型的边框

11.a 直边界矩形

它是一个直边界矩形,它不考虑对象的旋转。所以矩形的面积不会最小。由cv.boundingRect()函数实现。

# 设(x,y)为矩形的左上角坐标,(w,h)为矩形的宽和高。
x, y, w, h = cv.boundingRect(cnt)
print(x, y, w, h)
cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv.imshow("img", img)
cv.waitKey()

11.b 旋转矩形

在这里,边界矩形是用最小面积绘制的,所以它也考虑了旋转。使用的函数是cv.minarerect()。
它返回一个Box2D结构的数据,具体细节如下——(中心(x, y),(宽度、高度),转动角)。但是要画这个矩形,

# 我们需要矩形的4个角。它是通过函数cv.boxPoints()获得的。
rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)
box = np.int0(box)
cv.drawContours(img, [box], 0, (0, 0, 255), 2)

两个矩形都显示在一个单独的图像中。绿色矩形显示普通边界矩形。红色矩形是旋转后的矩形。
请添加图片描述

12.最小闭合圆

接下来,我们使用函数cv.minEnclosingCircle()来查找对象的外圆。它是以最小面积完全覆盖物体的圆。

(x, y), radius = cv.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)
cv.circle(img, center, radius, (0, 255, 0), 2)

请添加图片描述

13.拟合椭圆

下一个是将椭圆拟合到对象。它返回内接旋转矩形椭圆。

print("cnt:", cnt)
ellipse = cv.fitEllipse(cnt)
cv.ellipse(img, ellipse, (0, 255, 0), 2)

请添加图片描述

14.拟合直线

类似地,我们可以将一条直线拟合到点集上。下面的图像包含一组白色的点。我们可以把它近似成一条直线。

rows, cols = img.shape[:2]
[vx, vy, x, y] = cv.fitLine(cnt, cv.DIST_L2, 0, 0.01, 0.01)
lefty = int((-x * vy / vx) + y)
righty = int(((cols - x) * vy / vx) + y)
cv.line(img, (cols - 1, righty), (0, lefty), (0, 255, 0), 2)

cv.imshow("line", img)
cv.waitKey()

请添加图片描述

参考目录

https://docs.opencv.org/4.x/d5/d45/tutorial_py_contours_more_functions.html
https://docs.opencv.org/4.x/dd/d49/tutorial_py_contour_features.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于OpenCV的轮廓检测(1) 的相关文章

  • Opencv未找到所有轮廓

    我试图找到该图像的轮廓 但是该方法查找轮廓只返回1轮廓 轮廓突出显示image 2 我正在努力寻找all外部轮廓就像这些圆圈 里面有数字 我究竟做错了什么 我可以做什么来实现它 image 1 image 2 以下是我的代码的相关部分 th
  • 在 RGB 图像上绘制多类语义分割透明叠加

    我有语义分割掩码的结果 值在 0 1 之间 需要大津阈值来确定什么是积极的 我想直接在 RGB 图像上绘制 在 RGB 图像上每个预测类具有不同的随机颜色 我使用以下内容绘制了具有单一颜色的单个蒙版 是否有一个包或简单的策略可以为多类别做到
  • Python:opencv warpPerspective 既不接受 2 个也不接受 3 个参数

    我发现单应矩阵如下特征匹配 单应性教程 https docs opencv org 3 4 1 d1 de0 tutorial py feature homography html using M mask cv2 findHomograp
  • 如何设置K-means openCV c++的初始中心

    我正在尝试使用 OpenCv 和 Kmeans 对图像进行分割 我刚刚实现的代码如下 include opencv2 objdetect objdetect hpp include opencv2 highgui highgui hpp i
  • 使用opencv计算深度视差图

    我无法使用 opencv 从视差图计算深度 我知道两个立体图像中的距离是用以下公式计算的z baseline focal disparity p 但我不知道如何使用地图计算视差 我使用的代码如下 为我提供了两个图像的视差图 import n
  • 如何使用 Python 将我的 GoPro Hero 4 相机直播连接到 openCV?

    我在尝试从我的新 GoPro Hero 4 相机捕获实时流并使用 openCV 对其进行一些图像处理时遇到麻烦 这是我的试用 创建的窗口上没有显示任何内容 import cv2 import argparse import time imp
  • 多视图几何

    我从相距一定距离的两台相同品牌的相机捕获了两张图像 捕获了相同的场景 我想计算两个相机之间的现实世界旋转和平移 为了实现这一点 我首先提取了两张图像的 SIFT 特征并进行匹配 我现在有基本矩阵也单应性矩阵 然而无法进一步进行 有很多混乱
  • 无法在 Windows 7 机器中使用 OpenCV 2.4.3、Python 2.7 打开“.mp4”视频文件

    我目前正在进行一个涉及读取 mp4 视频文件的项目 我遇到的问题是它在Windows 7机器上使用Python 2 7 32位 OpenCV 2 4 3 cv2 pyd 代码片段如下 try video cv2 VideoCapture v
  • 如何将输出视频保存到 OpenCV 中的文件中

    我想将输出视频保存到文件中而不是显示它并尝试使用 cvcaptureimage 但仍然无法获得结果 include
  • 指纹奇异点检测

    我正在尝试确定指纹的核心点和增量点 我正在使用庞加莱指数方法 但我无法成功检测到这一点 而且我不明白为什么 First I divide the image in 15x15 blocks then I calculate the x an
  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • OpenCV 2.3 与 VS 2008 - 鼠标事件

    强制性 我是新手 有一份涉及编程的工作 并且我一边工作一边自学 不用说 作为一名老师 我经常犯彻底的错误 我现在所处的位置 我创建了 Graph 类 它 令人惊讶的是 制作了图表 但现在我想通过单击鼠标来修改图形 但我似乎无法让鼠标处理程序
  • 如何使用 python、openCV 计算图像中的行数

    我想数纸张 所以我正在考虑使用线条检测 我尝试过一些方法 例如Canny HoughLines and FLD 但我只得到处理过的照片 我不知道如何计算 有一些小线段就是我们想要的线 我用过len lines or len contours
  • 使用 OpenCV 改进特征点匹配

    我想匹配立体图像中的特征点 我已经用不同的算法找到并提取了特征点 现在我需要一个良好的匹配 在本例中 我使用 FAST 算法进行检测和提取 BruteForceMatcher用于匹配特征点 匹配代码 vector lt vector
  • 从包含带边框的表格的图像中提取表格结构

    我正在尝试提取下表中的单元格位置 应用自适应阈值处理后 我能够获得细胞位置周围的轮廓 并且 HoughLines 获得垂直和水平结构元素 这是我的代码 img cv2 imread os path join img path file im
  • OpenCV 跟踪器:模型未在函数 init 中初始化

    在视频的第一帧 我运行一个对象检测器 它返回对象的边界框 如下所示
  • cv2.VideoWriter:请求一个元组作为 Size 参数,然后拒绝它

    我正在使用 OpenCV 4 0 和 Python 3 7 创建延时视频 构造 VideoWriter 对象时 文档表示 Size 参数应该是一个元组 当我给它一个元组时 它拒绝它 当我尝试用其他东西替换它时 它不会接受它 因为它说参数不是
  • 是否可以在 PyScript 中使用 OpenCV 模块?

    我想使用 opencv 模块 但无法导入 OpenCV 那么我该如何解决这个问题呢 顺便说一句 Pyodide 支持 OpenCV 示例代码 https i stack imgur com ahwex jpg 尚不支持 OpenCV 此时O
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • “没有名为‘cv2’的模块”,但已安装

    我已经安装了包含 opencv 贡献的 whl 文件 因为我想使用 SIFT 算法 我在 conda 环境中使用 pip 安装了它 所以当我在 conda list 中提示时 它会向我显示 opencv python 3 4 5 contr

随机推荐

  • 大电流的走线和过孔

    工程师在设计的时候 xff0c 很容易忽略走线宽度的问题 xff0c 因为在数字设计时 xff0c 走线宽度不在 考虑范围里面 通常情况下 xff0c 都会尝试用最小的线宽去设计走线 xff0c 这时 xff0c 在大电流时 xff0c 将
  • c++ 实现基本数据结构代码

    数据结构是计算机科学的一个重要的分支 xff0c 主要研究如何有效地存储和组织数据以便于快速访问和操作 常见的数据结构有 xff1a 数组 xff1a 是一种线性的数据结构 xff0c 可以通过索引来访问数组中的元素 链表 xff1a 是一
  • Jetson开发实战记录(二):Jetson Xavier NX版本区别以及烧录系统

    Jetson开发实战记录 xff08 二 xff09 xff1a Jetson Xavier NX版本区别以及烧录系统 一 Jetson Xavier NX类型1 SD卡槽的版本 xff08 官方版本 xff09 2 带eMMC存储芯片的版
  • ZYNQ7000(AX7020)移植Linux操作系统(二):u-boot的编译和启动

    总述 我们已经在 PC 上已经安装了 Ubuntu 客户操作系统 xff0c 以及在 Ubuntu 操作系统里安装了 SDK 2015 4 工具 要想在 Zynq 平台上运行 Ubuntu 操作系统 xff0c 必项预先制作作镜像文件 xf
  • 10个让你的 Python 代码更具 pythonic 风格的示例

    10个让你的 Python 代码更具 pythonic 风格的示例 1 变量交换 2 函数返回元组 xff08 自动打包 解包 xff09 3 多重比较 4 多重比较 5 列表推导式 6 将 Python 字典当做缓存 7 关键字参数 8
  • 进程的调度算法

    先来先服务调度算法 xff1a 先来先服务调度算法是一种最简单的调度算法 xff0c 也称为先进先出或严格排队方案 当每个进程就绪后 xff0c 它加入就绪队列 当前正运行的进程停止执行 xff0c 选择在就绪队列中存在时间最长的进程运行
  • 华为云服务器购买及使用指南

    前言 作者参与牛客网的买服务器返现活动 xff0c 以某个奇妙的价格价格购入了一个一年的华为云服务器 xff0c 具体多少钱就不透露了 xff0c 不然会被当作广告性能参数如下 xff1a 购买 偶然看到这个活动 xff0c 然后点进去 x
  • JS 简单的事件

    实现鼠标滑过按钮时显示文本 xff0c 滑出时隐藏文本 span class token doctype lt DOCTYPE html gt span span class token tag span class token tag s
  • 在ROS中实现darknet_ros(YOLO V3)检测以及训练自己的数据集

    目录 1 darknet ros介绍 2 darknet ros原始项目编译测试 3 yolov3训练自己的数据集 4 使用自己训练好的数据集 1 darknet ros介绍 Darknet概述 https blog csdn net u0
  • apache options index 设置问题

    禁止显示Apache目录列表 Indexes FollowSymLinks 如何修改目录的配置以禁止显示Apache 目录列表 缺省情况下如果你在浏览器输入地址 xff1a http localhost 8080 如果你的文件根目录里有in
  • Centos7.7安装vncserver虚拟网络控制台

    虚拟网络控制台 xff08 VNC xff09 是一个图形桌面共享软件 xff0c 允许您使用键盘和鼠标远程控制另一台计算机 系统环境 服务端 xff1a Centos7 7 Minimal客户端 xff1a Windows10客户端VNC
  • C语言实现TCP通信

    如果想要自己写一个服务器和客户端 xff0c 我们需要掌握一定的网络编程技术 xff0c 个人认为 xff0c 网络编程中最关键的就是这个东西 socket 套接字 socket 套接字 xff1a 简单来讲 xff0c socket就是用
  • 详细的 win10+VS+Cuda10 环境配置,图文

    为完成CUDA 和OPEN CL的任务 xff0c 这两天配置了基于WIN10和VS2012 2015的环境 发觉网上很多配置CUDA的都是老版本 xff0c 而且过程过于繁琐 xff0c 我重新整理并分享之 我分了3篇记录 xff0c 另
  • Pytorch基础知识(13)对抗样本

    在前面的章节中 xff0c 我们已经看到了深度学习模型在解决各种计算机视觉任务方面的强大能力 我们在不同的数据集上训练和测试多个模型 现在 xff0c 我们将把注意力转向这些模型的健壮性 在本章中 xff0c 我们将介绍对抗样本 对抗样本是
  • ubuntu18.04修改docker0的IP

    当docker的IP与宿主机的IP在同一网段时候 xff0c 会产生错误 xff0c 例如同为172 17 直接修改 etc docker daemon json文件 xff0c 重启时候还是报错 查看docker日志 xff0c 可以看到
  • Flask 项目中使用 bootstrap

    flask 的插件中有一个 flask bootstrap 项目 但是用起来不怎么方便 如果大家感兴趣的话 还是直接在项目中引入 bootstrap flask 项目的目录结构 项目名称 app static span class hljs
  • MediaPipe基础(9)手指计数

    本文实现手指计数 xff0c 可以实现0 5的计数 链接 xff1a https span class token punctuation span span class token operator span pan span class
  • OpenCV基础(19)使用 OpenCV 和 Python 检测 ArUco 标记

    在本教程中 xff0c 您将学习如何使用 OpenCV 和 Python 检测图像和实时视频流中的 ArUco 标记 1 使用 OpenCV 和 Python 检测 ArUco 标记 在本教程的第一部分 xff0c 您将了解 OpenCV
  • 目标跟踪(7)使用 OpenCV 进行简单的对象跟踪

    1 简述 目标跟踪的过程是 1 获取对象检测的初始集 例如边界框坐标的输入集 2 为每个初始检测创建唯一的ID3 然后跟踪每一个在视频中移动的对象 xff0c 保持唯一ID的分配 此外 xff0c 对象跟踪允许我们为每个跟踪对象应用唯一 I
  • 基于OpenCV的轮廓检测(1)

    1 目标 理解什么叫做轮廓学习如何寻找轮廓以及可视化轮廓找出轮廓的不同特征 xff0c 如面积 周长 质心 边框等将看到许多与轮廓相关的函数 2 什么叫做轮廓 轮廓可以简单地解释为连接所有连续点 xff08 沿着边界 xff09 的曲线 x