【youcans 的 OpenCV 例程200篇】198.基于不变矩的形状相似性检测
3. 基于不变矩检测的图像识别
形状匹配也称为形状相似度检测,用于比较两个形状或两个轮廓。
函数 cv2.matchShapes() 基于 Hu 不变矩检测两个形状之间的相似度,因此图像的平移、旋转、灰度变化、尺度变化对相似度的影响都很小。
Hu 利用二阶和三阶归一化中心距构造了 7 个不变矩 M1~M7, 在连续图像下具有平移、灰度、尺度、旋转不变性, 是高度浓缩的图像特征。 不变矩能够描述图像的整体性质,从而在边缘提取、图像匹配及目标识别中得到了广泛的应用。
在实际的图像识别中,只有 M1 和 M2 的不变性比较好,而 M3~M7 的误差较大,识别率比较低。Hu不变矩对于物体的形状描述比较稳定,比较适合识别较大尺寸的物体,如水果的形状、车牌的字符等。
例程 12.8:基于不变矩的形状相似性检测
# 12.8 基于不变矩的形状相似性检测
img = cv2.imread("../images/Polygon01.png", flags=1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图像
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY_INV)
# 寻找二值化图中的轮廓
# binary, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # OpenCV3
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # OpenCV4~
# 绘制最外层轮廓
contourEx = img.copy() # OpenCV3.2 之前的早期版本,查找轮廓函数会修改原始图像
for i in range(len(contours)): # 绘制第 i 个轮廓
x, y, w, h = cv2.boundingRect(contours[i]) # 外接矩形
contourEx = cv2.drawContours(contourEx, contours, i, (205, 0, 0), thickness=-1) # 第 i 个轮廓,内部填充
contourEx = cv2.putText(contourEx, str(i), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255))
# 形状相似度检测
print("| 对比形状 | 相似度 | 变形方式 |")
print("| :--: | :--: | :--: |")
similarity = np.array([cv2.matchShapes(contours[10], contours[i], 1, 0.0) for i in range(len(contours))])
argSort = similarity.argsort() # 形状相似度 ret 从小到大排序 (相似度降低)
for i in range(len(contours)):
index = argSort[i]
print("| cnt[10] & cnt[{}] | {} | |".format(index, round(similarity[index],2)))
# 计算所有轮廓的 Hu 不变矩
print("| 轮廓编号 | M1 | M2 | M3 | M4 | M5 | M6 | M7 |")
print("| :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: |")
cntsHuM = np.empty((len(contours), 7), np.float)
for i in range(len(contours)):
moments = cv2.moments(contours[i]) # 返回字典,几何矩 mpq, 中心矩 mupq 和归一化矩 nupq
hum = cv2.HuMoments(moments) # 计算 Hu 不变矩
cntsHuM[i,:] = np.round(hum.reshape(hum.shape[0]), 2)
print("|{}|{:.2e}|{:.2e}|{:.2e}|{:.2e}|{:.2e}|{:.2e}|{:.2e}|".format(i, cntsHuM[i][0],
cntsHuM[i][1], cntsHuM[i][2], cntsHuM[i][3], cntsHuM[i][4], cntsHuM[i][5], cntsHuM[i][6]))
plt.figure(figsize=(9, 6))
plt.subplot(121), plt.axis('off'), plt.title("Origin")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.subplot(122), plt.axis('off'), plt.title("Contours")
plt.imshow(cv2.cvtColor(contourEx, cv2.COLOR_BGR2RGB))
plt.tight_layout()
plt.show()
形状相似度:
对比形状 | 相似度 | 变形方式 |
---|---|---|
cnt[10] & cnt[10] | 0.00 | 原图 |
cnt[10] & cnt[3] | 0.03 | 放大尺寸 |
cnt[10] & cnt[11] | 0.04 | 旋转角度 |
cnt[10] & cnt[4] | 0.04 | 缩小尺寸 |
cnt[10] & cnt[6] | 0.09 | 旋转 + 缩放 |
cnt[10] & cnt[9] | 0.40 | 尾部缩短 |
cnt[10] & cnt[7] | 0.52 | 尾部拉长 |
cnt[10] & cnt[8] | 0.55 | 头部放大 |
cnt[10] & cnt[2] | 0.59 | 不同形状 |
cnt[10] & cnt[5] | 0.69 | 形状变形 |
cnt[10] & cnt[1] | 1.48 | 缩放+尾部拉长 |
cnt[10] & cnt[0] | 1.89 | 扭曲 |
Hu 不变矩:
轮廓编号 | M1 | M2 | M3 | M4 | M5 | M6 | M7 |
---|---|---|---|---|---|---|---|
10 | 2.60e-01 | 3.00e-02 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | -0.00e+00 |
3 | 2.50e-01 | 3.00e-02 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 |
11 | 2.50e-01 | 3.00e-02 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | -0.00e+00 |
4 | 2.50e-01 | 3.00e-02 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 |
6 | 2.70e-01 | 4.00e-02 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 |
程序说明:
-
根据形状相似度检测结果进行分析:
(1) 相似度值越小则图形的相似性越高。本例的基准形状为轮廓 [10] ,与自身的相似度值为 0.0,表示是完全相同的形状。
(2) 轮廓 [10] 与轮廓 [3]、[11]、[4]、[6] 的相似度值也很小,表示与轮廓 [10] 的相似性很高。这些轮廓是由轮廓 [10] 进行放大、缩小、旋转、旋转+缩放产生的,表明图像的平移、缩放和旋转对相似度的影响都很小。
(3) 轮廓 [10] 与轮廓 [9]、[7]、[8]、[2]、[5] 的相似度值较小,表示与轮廓 [10] 的相似性较高。这些轮廓有的是由轮廓 [10] 进行尾部或头部拉伸、放大产生,有的进行了较大的变形。
(4) 轮廓 [10] 与轮廓 [1]、[0] 的相似度值很大,表示与轮廓 [10] 的相似性很低。实际上轮廓 [1] 也是对轮廓 [10] 的尾部拉伸和变形,轮廓 [0] 是对轮廓 [10] 的扭转。
综合以上结果分析,(1)图像的平移、缩放和旋转对相似度的影响很小;(2)形状相似度检测结果在一定程度上可以反映形状的相似程度,但该指标并不完全可靠。 -
轮廓 [10] 与轮廓 [3]、[11]、[4] 的 7 个不变矩 M1~M7 完全相同,这些轮廓是由轮廓 [10] 进行放大、缩小、旋转产生的,这验证了 Hu 不变矩具有具有平移、尺度、旋转不变性。
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125024042)
Copyright 2022 youcans, XUPT
Crated:2022-5-28
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】
194.寻找图像轮廓(cv.findContours)
195.绘制图像轮廓(cv.drawContours)
196.图像的矩和不变矩(cv.moments)
197.轮廓的基本特征
198.基于不变矩的形状相似性检测
199.轮廓的外接边界框
200.轮廓的基本属性