【youcans 的 OpenCV 例程200篇】198.基于不变矩的形状相似性检测

OpenCV 例程200篇 总目录-202206更新


【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. 根据形状相似度检测结果进行分析:
    (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)形状相似度检测结果在一定程度上可以反映形状的相似程度,但该指标并不完全可靠。

  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.轮廓的基本属性

猜你喜欢

转载自blog.csdn.net/youcans/article/details/125090346