24.11 轮廓矩

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

图像的矩特征

矩函数在图像分析中有着广泛的应用,如模式识别、目标分类、目标识别与方位估计、图像的编码与重构等。从一幅图像计算出来的矩集,不仅可以描述图像形状的全局特征,而且可以提供大量关于该图像不同的几何特征信息,如大小,位置、方向和形状等。

矩的概念

矩是概率与统计中的一个概念,是随机变量的一种数字特征。矩的定义如下:

X 为随机变量,c 为常数,k 为正整数。则量  称为𝑋关于𝑐点的𝑘阶矩。

比较重要的有两种情况:

  1. c=0 ,此时  称为𝑋关于𝑐点的𝑘阶原点矩。
  2. c=E(X) ,此时  称为𝑋关于𝑐点的𝑘阶中心矩。
图像中的矩特征

对于一幅图像,我们把像素的坐标看成是一个二维随机变量(𝑋,𝑌),那么一幅灰度图像可以用二维灰度密度函数来表示,因此可以用矩来描述灰度图像的特征。

空间矩/几何矩

空间矩的实质是图像的质量。计算公式如下所示:

大小为M×N 的数字图像f(x,y) 的二维(p+1) 阶定义为:


对应的中心距


其中,p q 指空间矩的阶数,I(x,y) 是对应位置的灰度值。

可以通过一阶矩和0阶矩计算图像的重心:



中心距

中心矩体现的是图像强度的最大和最小方向,具有平移不变性,计算方法如下式所示:


归一化的中心矩

归一化的中心矩具有尺度不变性和平移不变性,计算方法如下示:


Hu矩

Hu矩是由Hu1962年提出的,具有平移、旋转和尺度不变性,Hu利用二阶和三阶中心矩构建了七个不变矩,具体定义如下:








OpenCV中有直接计算图像矩的API,分为两个函数:moments()函数用于计算中心矩,HuMoments()函数用于由中心矩计算Hu矩。

函数

cv2.moment()中心距
函数原型:moment=cv2.moments(array, binaryImage=false )

参数:

  1. array 输入数组,可以是点集,也可以是灰度图像、二维数组,例如提取的轮廓结果。
  2. binaryImage 默认是false,若为True,则所有非零的像素都会按值1对待,也就是说相当于对图像进行了二值化处理,阈值为1,此参数仅对图像有效。

返回值

  1. moment: 返回数组的中心矩
cv2.HuMoment() Hu矩
函数原型:huMoment=cv2.HuMoments(moment)

参数:

  1. moment 图像的中心距。

返回值

  1. huMoment: 返回数组的Hu

示例1

import cv2
import numpy as np
img = cv2.imread('C:\\Users\\xxx\\Downloads\\contourImg.png')    #读取图像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转为灰度值图
ret, binary = cv2.threshold(gray,200,255,cv2.THRESH_BINARY) #转为二值图
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) #寻找轮廓
n=len(contours)       #轮廓个数
contoursImg=[]

cv2.imshow("original",img)  #显示原图

#### 逐一在全黑背景上绘制并显示轮廓
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])   #显示轮廓

#### 逐一计算轮廓的矩特征
for i in range(n):
    moment=cv2.moments(contours[i])
    print(f"轮廓{i}的矩:\n{moment}")
cv2.waitKey()
cv2.destroyAllWindows()

运行结果为:

示例2

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 1 图像读取
img = cv2.imread('C:/Users/xxx/Downloads/arrow.png')
imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 2 计算图像的Hu矩
imgmn = cv2.moments(imgray)
imghu = cv2.HuMoments(imgmn)
print("图像Hu矩结果:\n",imghu)

# 3 计算轮廓的Hu矩
# 3.1 转换为二值图
ret,thresh = cv2.threshold(imgray,127,255,0)
# 3.2 轮廓提取
contours, hierarchy = cv2.findContours(thresh,1,2)
# 3.3 计算轮廓的Hu矩
cnt = contours[0]
mn = cv2.moments(cnt)
hu = cv2.HuMoments(mn)
print("轮廓Hu矩结果:\n",hu)

运行结果为:

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐