简体   繁体   中英

Why cv.matchShape is NOT invariant to translation as it claims?

I have two contours to match (think of them as any arbitrary 2D closed curves). opencv claims to have matchShapes function that is invariant under translation, rotation and scale. But it seems to me that this is not the case, when I add shift (10, 5) to one of the curves, the function returns a different result, let alone if I did something whackier. Why is that?

matchShape

Reproducible example:

t = np.arange(0, np.pi, 0.001)
x, y = np.cos(t), np.sin(t)
xy = np.stack([x, y], -1)
print(cv.matchShapes(xy, xy, 1, 0))
print(cv.matchShapes(xy, xy + (2, 10), 1, 0))

The objects you send to cv.matchShapes() need to be contour objects which are different to a straight up 2D numpy array. The following code converts your curves to a plot,

在此处输入图像描述

then to an image & the contours of the 2 curves are found.

在此处输入图像描述

Finally cv.matchShapes() is run.

The output: 0 for the self match & 6.637412841570267e-12 for the match with the translated curve, a pretty accurate match under translation.

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

fig  = plt.figure()
ax   = fig.add_subplot(111)
t    = np.arange(0, np.pi, 0.001)
x, y = np.cos(t), np.sin(t)
ax.plot(x, y)

x_new = x + 2
y_new = y + 10
ax.plot(x_new, y_new, 'b')

[s.set_visible(False) for s in ax.spines.values()]
[t.set_visible(False) for t in ax.get_xticklines()]
[t.set_visible(False) for t in ax.get_yticklines()]
ax.axis('off')

plt.savefig('xy.jpg')

xy_img          = cv.imread('xy.jpg',  cv.IMREAD_COLOR)
xy_cpy          = cv.cvtColor(xy_img,   cv.COLOR_BGR2GRAY)
(threshold, bw) = cv.threshold(xy_cpy, 127, 255, cv.THRESH_BINARY)
contours, hier  = cv.findContours(bw, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)
contours        = contours[0:-1] # remove box surounding whole image

print(cv.matchShapes(contours[0], contours[0], method=cv.CONTOURS_MATCH_I1, parameter=0))
print(cv.matchShapes(contours[0], contours[1], method=cv.CONTOURS_MATCH_I1, parameter=0))

cv.namedWindow("xy")
cv.drawContours(xy_img, contours, -1, (0, 255, 0), 3)
cv.imshow("xy", xy_img)

cv.waitKey()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM