函数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
从结果我们可以看出来,
匹配是从右往左进行的,这一点我专门加了重心坐标才看出来。