一、区域特征之矩不变量
矩是概率与统计中的一个概念,是随机变量的一种数字特征。矩函数在图像分析中有着广泛的应用,如模式识别、目标分类、图像编码与重构等。
把图像的像素坐标视为二维随机变量 (X,Y),就可以用矩来描述灰度图像的特征。
图像矩是对特征进行参数描述的一种算法,通常描述了图像形状的全局特征,并提供了大量的关于该图像不同类型的几何特性信息,比如大小、位置、方向及形状等。
当图像发生平移时,几何距也会发生变化;中心矩
具有平移不变性,但在图像旋转时会发生变化;归一化中心距不仅具有平移不变性,而且具有比例不变性(尺度不变性)。
Hu 利用二阶和三阶归一化中心距构造了 7 个不变矩 M1~M7, 在连续图像下具有平移、灰度、尺度、旋转不变性, 是高度浓缩的图像特征。不变矩能够描述图像的整体性质,从而在边缘提取、图像匹配及目标识别中得到了广泛的应用。
二、函数
- OpenCV 提供了函数 cv2.moments() 计算图像矩 Mu,函数 cv2.HuMoments() 计算目标轮廓的 Hu 不变矩。
cv.moments(array[, binaryImage]) → Mu
cv.HuMoments(Mu[, hu]) → Hu
函数 cv2.moments() 以字典(Dict)形式返回图像的矩。
函数 cv2.HuMoments() 以列表(List)形式返回目标轮廓的 Hu 不变矩。
参数说明:
- array:是一幅单通道 8-bits 图像,或一个二维浮点数组(如轮廓列表 contours 中的一个轮廓)
- binaryImage:指示输入图像是否二值图像
- 返回值 Mu 是字典格式,包括 24个键值对。
- 返回值 Hu 是一个列表(List),包括 7 个不变矩 M1~M7,浮点数。
具体定义和计算公式为:

- 不变矩 M1~M7 又称矩不变量, 在连续图像下具有平移、灰度、尺度、旋转不变性, 是高度浓缩的图像特征。
三 、例程
- 14.14:区域特征之不变矩
import cv2
import numpy as np
from matplotlib import pyplot as plt
# # 14.14 特征描述之不变矩
gray = cv2.imread(r"E:/OpenCV/bgra.png", flags=0) # 灰度图像
height, width = gray.shape # (568, 568)
# 图像的平移,缩放,旋转和镜像
grayList = []
grayList.append(gray) # [0],原始图像
mat = np.float32([[1, 0, 50], [0, 1, 50]])
grayList.append(cv2.warpAffine(gray, mat, (height, width))) # [1],图像平移
top, bottom, left, right = height//4, height//4, width//4, width//4
grayResize = cv2.resize(gray, (width//2, height//2)) # 图像缩放 (284, 284)
replicate = cv2.copyMakeBorder(grayResize, top, bottom, left, right, cv2.BORDER_CONSTANT, value=0)
grayList.append(replicate) # [2],图像缩放并填充至原来尺寸 (568, 568)
grayList.append(cv2.flip(gray, 1)) # [3],图像镜像,水平翻转
mar = cv2.getRotationMatrix2D((width//2, height//2), angle=45, scale=1) # 图像中心作为旋转中心
rotate = cv2.warpAffine(gray, mar, (height, width)) # 旋转变换,默认为黑色填充
grayList.append(rotate) # [4],图像旋转 45度
grayList.append(cv2.rotate(gray, cv2.ROTATE_90_COUNTERCLOCKWISE)) # [5],图像逆时针旋转90度
print(gray.shape, grayResize.shape, replicate.shape, rotate.shape,len(grayList))
plt.figure(figsize=(9, 6))
for i in range(len(grayList)):
moments = cv2.moments(grayList[i]) # 返回几何矩 mpq, 中心矩 mupq 和归一化矩 nupq
huM = cv2.HuMoments(moments) # 计算 Hu 不变矩
plt.subplot(2,3,i+1), plt.axis('off'), plt.imshow(grayList[i], 'gray')
# print("Moments of gray:\n", moments)
print("HuMoments of gray:\n", np.log10(np.abs(huM.T)).round(4))
plt.show()
(128, 128) (64, 64) (128, 128) (128, 128) 6
HuMoments of gray:
[[ -2.8742 -8.1679 -11.923 -10.9382 -23.7512 -15.0558 -22.3691]]
HuMoments of gray:
[[ -2.8736 -8.2349 -13.0984 -10.9881 -23.1486 -16.5837 -23.221 ]]
HuMoments of gray:
[[ -2.8747 -8.17 -11.9226 -10.94 -23.7714 -15.0585 -22.3717]]
HuMoments of gray:
[[ -2.8742 -8.1679 -11.923 -10.9382 -23.7512 -15.0558 -22.3691]]
HuMoments of gray:
[[ -2.8921 -8.1006 -11.13 -11.0349 -22.4787 -15.0852 -22.163 ]]
HuMoments of gray:
[[ -2.8742 -8.1679 -11.923 -10.9382 -23.7512 -15.0558 -22.3691]]

四、资料
youcans_的博客:
https://blog.csdn.net/youcans/article/details/125704724