【OpenCV学习笔记23】- OpenCV中的轮廓 - 轮廓特征

这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。
如果有喜欢我笔记的请麻烦帮我关注、点赞、评论。谢谢诸位。

学习笔记:
学习笔记目录里面会收录我关于OpenCV系列学习笔记博文,大家如果有什么不懂的可以通过阅读我的学习笔记进行学习。
【OpenCV学习笔记】- 学习笔记目录

内容

  • 找到轮廓的不同特征,如面积、周长、质心、边界框等
  • 您将看到许多与轮廓相关的功能。

1.矩

图像矩可帮助您计算一些特征,例如物体的质心、物体的面积等。查看关于 图像矩的维基百科页面

函数 cv2.moments() 给出所有计算出的矩值的字典。

示例代码:

# OpenCV中的轮廓
# 2. 轮廓特征
# 矩
import cv2

img = cv2.imread('../image/3.9.1.png', 0)
ret, thresh = cv2.threshold(img, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv2.moments(cnt)
print(M)

控制台/命令行打印:

{'m00': 30420.0, 'm10': 10373220.0, 'm01': 5992740.0, 'm20': 3676074480.0, 'm11': 2043524340.0, 'm02': 1223411280.0, 'm30': 1348207403400.0, 'm21': 724186672560.0, 'm12': 417183246480.0, 'm03': 257891573160.0, 'mu20': 138806460.0, 'mu11': 0.0, 'mu02': 42841500.0, 'mu30': 0.0, 'mu21': 0.0, 'mu12': 0.0, 'mu03': 0.0, 'nu20': 0.15, 'nu11': 0.0, 'nu02': 0.046296296296296294, 'nu30': 0.0, 'nu21': 0.0, 'nu12': 0.0, 'nu03': 0.0}

在图像矩中,您可以提取有用的数据,例如面积,质心等。质心由关系C给出在这里插入图片描述在这里插入图片描述。可以按照以下步骤进行:
示例代码:

# OpenCV中的轮廓
# 2. 轮廓特征
# 矩
import cv2

img = cv2.imread('../image/3.9.1.png', 0)
ret, thresh = cv2.threshold(img, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv2.moments(cnt)
# print(M)

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

控制台/命令行打印:

341
197

2.轮廓面积

轮廓区域由函数 cv2.contourArea() 或从力矩M[‘m00’]中给出。
示例代码:

area = cv2.contourArea(cnt)

3.轮廓周长

也称为弧长。可以使用 cv2.arcLength() 函数找到它。第二个参数指定形状是闭合轮廓(如果通过True)还是曲线。
示例代码:

perimeter = cv2.arcLength(cnt,True)

4.轮廓近似

根据我们指定的精度,它可以将轮廓形状近似为顶点数量较少的其他形状。它是 Douglas-Peucker 算法的实现。检查维基百科页面上的算法和演示。

为了理解这一点,假设您试图在图像中找到一个正方形,但是由于图像中的某些问题,您没有得到一个完美的正方形,而是一个“坏形状”(如下图所示)。现在,您可以使用此功能来近似形状。在这种情况下,第二个参数称为epsilon,它是从轮廓到近似轮廓的最大距离。它是一个精度参数。需要正确选择 epsilon 才能获得正确的输出。
示例代码:

# OpenCV中的轮廓
# 2. 轮廓特征
# 4.轮廓近似
import cv2

img = cv2.imread('../image/3.9.2.png')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("img", img)
cv2.waitKey(0)
# img = cv2.imread('../image/3.9.2.png', 0)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]

img2 = img.copy()

epsilon = 0.1 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
cv2.drawContours(img, approx, -1, (0, 255, 0), 3)
cv2.imshow("approx", img)
cv2.waitKey(0)

epsilon2 = 0.01 * cv2.arcLength(cnt, True)
approx2 = cv2.approxPolyDP(cnt, epsilon2, True)
cv2.drawContours(img2, approx2, -1, (0, 255, 0), 3)
cv2.imshow("approx2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

下面,在第二张图片中,绿线显示了 精度 epsilon = 10% 时的近似曲线。第三幅图显示了精度 epsilon = 1% 时的情况。第三个参数指定曲线是否闭合。
效果图:
在这里插入图片描述

5.凸包

凸包外观看起来与轮廓逼近相似,但并非如此(在某些情况下两者可能提供相同的结果)。在这里,cv2.convexHull() 函数检查曲线是否存在凸凹缺陷并对其进行校正。一般而言,凸曲线是始终凸出或至少平坦的曲线。如果在内部凸出,则称为凸度缺陷。例如,检查下面的手的图像。红线显示手的凸包。双向箭头标记显示凸度缺陷,这是船体与轮廓线之间的局部最大偏差。
在这里插入图片描述
关于它的语法,有一些事情需要讨论:

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

参数详细信息:

  • points: 就是我们传入的轮廓。
  • hull: 是输出,通常我们避免它。
  • clockwise:方向标记。如果为True,则输出凸包为顺时针方向。否则,其方向为逆时针方向。
  • returnPoints:默认情况下为True。然后返回船体点的坐标。如果为False,则返回与船体点相对应的轮廓点的索引。

因此,要获得如上图所示的凸包,以下内容就足够了:

hull = cv2.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]]与第一个结果相同(对于其他结果依此类推)。

当我们讨论凸度缺陷时,您将再次看到它。

6.检查凸度

cv2.isContourConvex() 是一个函数用来检查曲线是否为凸多边形。它只是返回True还是False。

k = cv2.isContourConvex(cnt)

7.边界矩形

有两种类型的边界矩形。

7.a. 直角矩形

它是一个直角矩形,不考虑对象的旋转。因此,边界矩形的面积将不会最小。它可以通过函数 cv2.boundingRect() 找到。

令(x,y)为矩形的左上角坐标,而(w,h)为矩形的宽度和高度。

x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

7.b.旋转矩形

在这里,边界矩形是用最小面积绘制的,因此它也考虑了旋转。使用的函数是 cv2.minAreaRect() 。它返回一个Box2D结构,其中包含以下细节-(中心(x,y),(宽度,高度),旋转角度)。但是要绘制此矩形,我们需要矩形的4个角。它是通过函数 cv2.boxPoints() 获得的.

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)

两个矩形都显示在单个图像中。绿色矩形显示法线边界矩形。红色矩形是旋转的矩形。
在这里插入图片描述

8.最小外圆

接下来,我们使用函数 cv2.minEnclosingCircle() 找到对象的外接圆。它是一个以最小面积完全覆盖对象的圆圈。

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

在这里插入图片描述

9.拟合椭圆

下一步是使椭圆适合对象。它返回椭圆所在的旋转矩形。

ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img,ellipse,(0,255,0),2)

在这里插入图片描述

10.拟合线

同样,我们可以将一条直线拟合到一组点。下图包含一组白点。我们可以近似一条直线。

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

在这里插入图片描述

  • 30
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要下载OpenCV学习的运动目标(前景)检测源码,可以按照以下步骤进行。 首先,访问OpenCV的官方网站(https://opencv.org/)或GitHub的OpenCV仓库(https://github.com/opencv/opencv),找到源代码的下载选项。 在官方网站上,可以选择下载最新版本的OpenCV,或者根据特定版本的需求进行选择。在GitHub上,可以浏览仓库的不同分支和版本标签,并选择下载相应的源代码。 一旦选择了合适的源码下载选项,点击下载按钮进行下载。下载完成后,将源代码文件解压缩至本地目录。 接下来,在下载的源代码文件夹,找到与运动目标检测相关的示例代码或项目。这些示例代码通常位于“samples”或“examples”文件夹,可以根据名称或说明找到与运动目标检测相关的示例。 打开示例代码文件,使用合适的集成开发环境(IDE)或文本编辑器加载源代码。确保已正确配置编译环境和OpenCV库文件。 阅读示例代码的注释和文档,理解实现运动目标检测的算法和方法。 对于初学者,建议阅读和运行示例代码,以更好地理解和学习运动目标检测的概念和实践。根据需要,可以根据示例代码进行修改和调整,以满足特定的需求。 总之,要下载OpenCV学习的运动目标(前景)检测源码,首先选择合适的源代码下载选项,然后解压缩源代码文件夹,找到与运动目标检测相关的示例代码或项目,最后阅读和运行示例代码以学习和实践运动目标检测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜七天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值