cv2.matchShapes
通过hub矩来判断两个对象的一致性,有cv2.CONTOURS_MATCH_I1,cv2.CONTOURS_MATCH_I1,cv2.CONTOURS_MATCH_I1三种方法。
cv2.createShapeContextDistanceExtractor()
用于计算形状场景距离,通过使用形状上下文算法在计算距离时,在每个点上附加一个形状上下文描述符,每个点都能够捕获剩余点相对于它的分布特征,从而提供全局鉴别特征。
cv2.createHausdorffDistanceExtractor()
计算图形A内的每一个点,寻找其距离图像B的最短距离,将这个最短距离作为Hausdroff直接距离D1,计算图形B内的每一个点,寻找其距离图像A的最短距离,将这个最短距离作为Hausdroff直接距离D2,将上述D1、D2中的较大者作为Hausdroff距离,容易受极端值的影响。
img1 = cv2.imread("E:/work/images/gb.jpg", 0)
_, img1 = cv2.threshold(img1,100, 255, cv2.THRESH_BINARY_INV)
c1, f1 = cv2.findContours(img1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img1, c1[0], -1, 127, 2)
img2 = cv2.imread("E:/work/images/k.PNG", 0)
_, img2 = cv2.threshold(img2,100, 255, cv2.THRESH_BINARY_INV)
c2, f2 = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img2, c2[0], -1, 127, 2)
img3 = cv2.imread("E:/work/images/gb_src.jpg", 0)
_, img3 = cv2.threshold(img3,100, 255, cv2.THRESH_BINARY_INV)
c3, f3 = cv2.findContours(img3, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img3, c3[0], -1, 127, 2)
sc = cv2.createShapeContextDistanceExtractor()
hd = cv2.createHausdorffDistanceExtractor()
sc_value = sc.computeDistance(c1[0], c1[0])
sc_value1 = sc.computeDistance(c1[0], c3[0])
sc_value2 = sc.computeDistance(c1[0], c2[0])
hd_value = hd.computeDistance(c1[0], c1[0])
hd_value1 = hd.computeDistance(c1[0], c3[0])
hd_value2 = hd.computeDistance(c1[0], c2[0])
ms1 = cv2.matchShapes(c1[0], c1[0], 1, 0.0)
ms2 = cv2.matchShapes(c1[0], c3[0], 1, 0.0)
ms3 = cv2.matchShapes(c1[0], c2[0], 1, 0.0)
print(sc_value)
print(sc_value1)
print(sc_value2)
print(hd_value)
print(hd_value1)
print(hd_value2)
print(ms1)
print(ms2)
print(ms3)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.imshow("img3", img3)
cv2.waitKey()
cv2.destroyAllWindows()
# 输出结果为:
0.0
0.2830809950828552
0.4213451147079468
0.0
383.0822448730469
83.43260955810547
0.0
0.01665152572582304
1.189807028420355
通过结果可知, createHausdorffDistanceExtractor()的结果不准确,对于另外的场景createHausdorffDistanceExtractor()的效果还是可以的,容易受极端值的影响,使用时根据场景来适当选择合适的算法。
输入输出图像,如下:
img1:
img2:
img3: