函数cv.matchShape()可以帮我们比较两个形状或轮廓的相似度。如果返回值越小,匹配越好。
它是根据Hu矩来计算的。Hu矩是归一化中心矩的线性组合,之所以这样做是为了能够获取代表图像的某个特征的矩函数。这些矩函数对某些变化如缩放,旋转,镜像映射(除了h1)具有不变形。
具体代码:
def matchshape_demo(): #性状匹配 img1 = cv.imread('img/contour_target.png') img2 = cv.imread('img/contours1.png') gray1 = cv.cvtColor(img1, cv.COLOR_BGR2GRAY) ret, thresh1 = cv.threshold(gray1, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU) cv.imshow('thresh1', thresh1) gray2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY) ret, thresh2 = cv.threshold(gray2, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU) cv.imshow('thresh2', thresh2) copyImage1, contours1, hierarchy1 = cv.findContours(thresh1, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) copyImage2, contours2, hierarchy2 = cv.findContours(thresh2, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) cnt1 = contours1[0] for i, cnt in enumerate(contours2): print(i) #找到性状的重心 M = cv.moments(cnt) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print(cx, cy) cv.circle(img2, (cx, cy), 5, (255,255,255), -1) #性状匹配 ret = cv.matchShapes(cnt1, cnt, 1, 0.0) print(ret) cv.imshow('img'+str(i), gray2)
结果:
上面是我们匹配的图像,
0
650 156
0.2982116195106314
1
370 147
0.3064981073672026
2
119 134
1.7208456881689926e-15
650 156
0.2982116195106314
1
370 147
0.3064981073672026
2
119 134
1.7208456881689926e-15
从结果我们可以看出来,
匹配是从右往左进行的,这一点我专门加了重心坐标才看出来。