9.1 轮廓特征

# Image Moments

可帮助您计算一些特征,例如对象的质心、对象的面积等。参考 Image Moments上的维基百科页面函数 cv.moments() 给出了所有计算出的矩值的字典。如下:

import numpy as np
import cv2 as cv
img = cv.imread('star.jpg',0)
ret,thresh = cv.threshold(img,127,255,0)
contours,hierarchy = cv.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv.moments(cnt)
print( M )

在这里插入图片描述
cv.moments()计算多边形或光栅化形状的三阶以内的所有力矩。该函数计算矢量形状或光栅化形状的 3 阶矩。结果在结构 cv::Moments 中返回。

1.质心

#  质心计算公式
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
#  打印质心坐标
print(cx, cy)
#  在图片中描绘质心,红色
img[cx-10:cx+10, cy-10:cy+10] = (255, 0, 0)
#  展示图片
plt.imshow(img), plt.axis("off")
plt.show()

结果图片如下(质心为红色小点):
在这里插入图片描述

2.周长和面积

周长:它也称为弧长。可以使用 cv.arcLength() 函数找到它。第二个参数指定形状是闭合轮廓(为 True时),还是只是曲线(为False时)。
面积:轮廓面积由函数 cv.contourArea() 或从moments中的M[‘m00’] 给出。

#  定义周长和面积列表
area = []
perimeter = []
for i in range(len(contours)):
	#  储存周长和面积
    area.append(cv.contourArea(contours[i]))
    perimeter.append(cv.arcLength(contours[i], True))
#  对得到的周长和面积进行升序排序
sorted_area = np.sort(area)
sorted_perimeter = np.sort(perimeter)
print("sorted_area", sorted_area)
print("sorted_perimeter", sorted_perimeter)

在这里插入图片描述

3. 近似轮廓

根据我们指定的精度,它将轮廓形状近似为顶点数量较少的另一种形状。它是 Douglas-Peucker算法的实现。检查维基百科页面以获取算法和演示。为了理解这一点,假设您试图在图像中找到一个正方形,但由于图像中的一些问题,您没有得到一个完美的正方形,而是一个“坏形状”(如下面的第一张图片所示)。现在您可以使用此函数来近似形状。在此,第二个参数称为 epsilon,它是从轮廓到近似轮廓的最大距离。它是一个精度参数。需要明智地选择 epsilon 才能获得正确的输出。
参考以下示例:

img_c1, img_c2, img_c3 = img.copy(), img.copy(), img.copy()  # 复制一个图片脚本
cnt = contours[0]  # 选择第一个轮廓点向量
epsilon1 = 0.1 * cv.arcLength(cnt, True)  # 选择轮廓近似阈值,0.1*周长,封闭图形
approx1 = cv.approxPolyDP(cnt, epsilon1, True)  # 获得近似阈值轮廓
epsilon2 = 0.01 * cv.arcLength(cnt, True)
approx2 = cv.approxPolyDP(cnt, epsilon2, True)
img_contour = cv.drawContours(img_c1, [cnt], 0, (255, 0, 0), -1)  # 填充原图轮廓
img_contour = cv.drawContours(img_c1, [approx1], 0, (0, 255, 0), 3)  # 画出0.1近似轮廓
img_contour2 = cv.drawContours(img_c2, [cnt], 0, (255, 0, 0), -1)  # 填充原图轮廓
img_contour2 = cv.drawContours(img_c2, [approx2], 0, (0, 255, 0), 3)  # 画出0.01轮廓
# img_contour[cx-10:cx+10, cy-10:cy+10] = (255, 255, 255)
plt.subplot(131), plt.imshow(img, 'gray'), plt.title("Oringal")
plt.axis('off')
plt.subplot(132), plt.imshow(img_c1, ), plt.title("approx_contour")
plt.axis('off')
plt.subplot(133), plt.imshow(img_c2, ), plt.title("img_contour")
plt.axis('off')

plt.show()

下面,在第二张图中,绿线显示了 epsilon = 10% 弧长的近似曲线。第三张图显示了相同的 epsilon = 弧长的 1%。第三个参数指定曲线是否闭合。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值