基于OpenCV的轮廓检测(1)

这篇具有很好参考价值的文章主要介绍了基于OpenCV的轮廓检测(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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做的事。它去除所有冗余点并压缩轮廓,从而节省内存。
基于OpenCV的轮廓检测(1)

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%的近似曲线。第三个参数指定曲线是否闭合。
基于OpenCV的轮廓检测(1)

9.Convex Hull(凸包)

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

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

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)

两个矩形都显示在一个单独的图像中。绿色矩形显示普通边界矩形。红色矩形是旋转后的矩形。
基于OpenCV的轮廓检测(1)

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)

基于OpenCV的轮廓检测(1)

13.拟合椭圆

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

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

基于OpenCV的轮廓检测(1)

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()

基于OpenCV的轮廓检测(1)

参考目录

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文章来源地址https://www.toymoban.com/news/detail-486367.html

到了这里,关于基于OpenCV的轮廓检测(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • OpenCV实例(九)基于深度学习的运动目标检测(一)YOLO运动目标检测算法

    OpenCV实例(九)基于深度学习的运动目标检测(一)YOLO运动目标检测算法

    2012年,随着深度学习技术的不断突破,开始兴起基于深度学习的目标检测算法的研究浪潮。 2014年,Girshick等人首次采用深度神经网络实现目标检测,设计出R-CNN网络结构,实验结果表明,在检测任务中性能比DPM算法优越。同时,何恺明等人针对卷积神经网络(Convolutional Neura

    2024年02月13日
    浏览(9)
  • 基于opencv深度学习,交通目标检测,行人车辆检测,人流统计,交通流量检测

    基于opencv深度学习,交通目标检测,行人车辆检测,人流统计,交通流量检测

    文章目录 0 前言+ 1. 目标检测概况+ 1.1 什么是目标检测?+ 1.2 发展阶段 2. 行人检测+ 2.1 行人检测简介+ 2.2 行人检测技术难点+ 2.3 行人检测实现效果+ 2.4 关键代码-训练过程 最后 设计项目案例演示地址: 链接 毕业设计代做一对一指导项目方向涵盖: 1.1 什么是目标检测? 目标检

    2024年02月04日
    浏览(10)
  • OpenCV实战(31)——基于级联Haar特征的目标检测

    在机器学习基础一节中,我们介绍了机器学习的一些基本概念,并通过使用不同类别的样本来构建分类器。但这种方法训练分类器需要存储所有样本的表示,然后通过查看最近标记点(最近邻居)来预测新实例的标签。对于大多数机器学习方法,训练是一个迭代过程,在此过程

    2024年02月09日
    浏览(9)
  • OpenCV(三十二):轮廓检测

    OpenCV(三十二):轮廓检测

    1.轮廓概念介绍         在计算机视觉和图像处理领域中,轮廓是指在图像中表示对象边界的连续曲线。它是由一系列相邻的点构成的,这些点在边界上连接起来形成一个封闭的路径。 轮廓层级:        轮廓层级(Contour Hierarchy)是指在包含多个轮廓的图像中,轮廓之间的

    2024年02月07日
    浏览(12)
  • OpenCV 图像轮廓检测

    OpenCV 图像轮廓检测

            本文是OpenCV图像视觉入门之路的第15篇文章,本文详细的介绍了图像轮廓检测的各种操作,例如:轮廓检索模式、轮廓逼近算子等操作。         图像轮廓是具有相同颜色或灰度的连续点的曲线,轮廓在形状分析和物体的检测和识别中很有用。图像轮廓的作用

    2024年01月25日
    浏览(9)
  • opencv图像轮廓检测

    opencv图像轮廓检测

    效果展示: 代码部分:

    2024年02月12日
    浏览(12)
  • openCV实战-系列教程7:轮廓检测2与模板匹配(轮廓检测/轮廓特征/轮廓近似/轮廓边界矩阵/轮廓边界圆/模版匹配)、原理解析、源码解读

    openCV实战-系列教程7:轮廓检测2与模板匹配(轮廓检测/轮廓特征/轮廓近似/轮廓边界矩阵/轮廓边界圆/模版匹配)、原理解析、源码解读

    打印一个图片可以做出一个函数: 前面我们计算了这个图片的轮廓:  它的轮廓信息保存在了contours中,取出第一个轮廓,计算相关参数: 打印结果: 8500.5  437.9482651948929 这是分别求出了周长和面积,这里的True表示的是否是闭合的。    如图,第一个图是原图,如果将它的

    2024年02月10日
    浏览(7)
  • 【案例分析】基于OpenCV的篮球目标检测追踪与进球预测

    【案例分析】基于OpenCV的篮球目标检测追踪与进球预测

    目前,模式识别中的运动视觉分析处在高速发展阶段,诸如国家863计划的无标记仿人乒乓球机器人[1]等项目,均表现出该领域的发展前景。其核心是利用计算机视觉技术从图像序列中检测、跟踪、识别人或物,并对其行为进行理解与描述。 此外,对于飞行物体的轨迹追踪与预

    2024年02月04日
    浏览(39)
  • OpenCV图像处理——轮廓检测

    OpenCV图像处理——轮廓检测

    2024年02月13日
    浏览(9)
  • opencv(七)Canny边缘检测和图像轮廓检测

    opencv(七)Canny边缘检测和图像轮廓检测

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 1、检测步骤 1)使用高斯滤波器,以平滑图像,滤掉噪声。 2)计算图像中每个像素点的梯度强度和方向 3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应 4)应用双阈值(

    2024年02月04日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包