12.2 矩特征


比较两个轮廓最简单的方法是比较二者的轮廓矩。轮廓矩代表了一个轮廓、一幅图像、一 组点集的全局特征。矩信息包含了对应对象不同类型的几何特征,例如大小、位置、角度、形 状等。矩特征被广泛地应用在模式识别、图像识别等方面。


1. 矩的计算:moments函数

OpenCV 提供了函数 cv2.moments()来获取图像的 moments 特征。通常情况下,我们将使用 函数 cv2.moments()获取的轮廓特征称为“轮廓矩”。轮廓矩描述了一个轮廓的重要特征,使用 轮廓矩可以方便地比较两个轮廓。
函数 cv2.moments()的语法格式为:
retval = cv2.moments( array[, binaryImage] )
式中有两个参数:

  • array:可以是点集,也可以是灰度图像或者二值图像。当 array 是点集时,函数会把这 些点集当成轮廓中的顶点,把整个点集作为一条轮廓,而不是把它们当成独立的点来看 待。
  • binaryImage:该参数为 True 时,array 内所有的非零值都被处理为 1。该参数仅在参数 array 为图像时有效。

【例 12.4】使用函数 cv2.moments()提取一幅图像的特征。

import cv2
import numpy as np

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter12/moments.bmp")
cv2.imshow("orginal",img)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

n = len(contours)
contoursImg = []
for i in range(n):
    temp = np.zeros(img.shape,np.uint8)
    contoursImg.append(temp)
    contoursImg[i] = cv2.drawContours(contoursImg[i],contours,i,(255,255,255),3)
    cv2.imshow("contours="+str(i),contoursImg[i])

print("观察各个轮廓的距(moments):")
for i in range(n):
    print("轮廓"+str(i)+"的距:\n",cv2.moments(contours[i]))

print("观察各个轮廓的面积:")
for i in range(n):
    print("轮廓"+str(i)+"的面积:%d"%cv2.moments(contours[i])['m00'])


cv2.waitKey()
cv2.destroyAllWindows()

2. 计算轮廓的长度:arcLength函数

函数 cv2.arcLength()用于计算轮廓的长度,其语法格式为:
retval = cv2.arcLength( curve, closed )
式中返回值 retval 是轮廓的长度(周长)。 上式中有两个参数:

  • curve 是轮廓。
  • closed 是布尔型值,用来表示轮廓是否是封闭的。该值为 True 时,表示轮廓是封闭的。

【例 12.7】将一幅图像内长度大于平均值的轮廓显示出来。

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter12/contours0.bmp")
cv2.imshow("orginal",img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#! 获取轮廓
ret,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

#! 计算各轮廓的长度之和,平均长度
n = len(contours)   #? 获取轮廓的个数
cntLen = [] #? 存储各轮廓的长度
for i in range(n):
    cntLen.append(cv2.arcLength(contours[i],True))
    print("第"+str(i)+"个轮廓的长度为:%d"%cntLen[i])

cntLenSum = np.sum(cntLen)  #? 各轮廓的长度之和
cntLenAvr = cntLenSum/n     #? 轮廓长度的平均值
print("轮廓的总长度为:%d"%cntLenSum)
print("轮廓的平均长度为:%d"%cntLenAvr)

#! 显示长度超过平均值的轮廓
contoursImg = []
for i in range(n):
    temp = np.zeros(img.shape,np.uint8)
    contoursImg.append(temp)
    contoursImg[i] = cv2.drawContours(contoursImg[i],contours,i,(255,255,255),3)
    if cntLen[i] > cntLenAvr:
        cv2.imshow("contours["+str(i)+"]",contoursImg[i])

cv2.waitKey()
cv2.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

暮棂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值