cv2.matchShapes () возвращает 0 в python

У меня проблема, потому что с cv2.matchShapes () возвращают 0, я использую OpenCV версии 4.2. Я пытаюсь сопоставить два одинаковых изображения, а также два разных изображения, но проблема в том, что он returns 0

введите описание изображения здесь введите описание изображения здесь

import cv2
img_1=cv2.imread('noise/1.png',0)
img_2=cv2.imread('noise/2.png',0)
ret, thresh = cv2.threshold(img_1, 127, 255, 0)
ret, thresh2 = cv2.threshold(img_2, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt1 = contours[0]
contours, hierarchy = cv2.findContours(thresh2, 2, 1)
cnt2 = contours[0]
ret = cv2.matchShapes(cnt1, cnt1, 1, 0.0)
print(ret)

или это

ret = cv2.matchShapes(cnt1, cnt2, 1, 0.0)
print(ret)

Всего 2 ответа


Ну, здесь что-то определенно не так. И это связано с:

cnt1 = contours[0]
# ...
cnt2 = contours[0]

Вы предполагаете, что найдено только два контура. Итак, если вы делаете:

import numpy as np

#....your code 

for c in contours1:
    img_test = np.zeros(img_1.shape)
    img_test  = cv2.drawContours(img_test , [c], -1, (1), thickness=-1)
    cv2.namedWindow("c", cv2.WINDOW_GUI_NORMAL)
    cv2.imshow("c", img_test )
    cv2.waitKey(0)

Вы получаете:

contour1

Как видите, найдено два контура. Если вы сделаете то же самое для contours2 вы получите:

contour2

Для второго изображения также есть два контура. Итак, в вашем коде вы делаете:

cnt1 = contours[0]
# ...
cnt2 = contours[0]

Таким образом, вы пытаетесь сопоставить первые контуры на обоих изображениях с, как вы можете видеть на изображениях выше, просто как точка. И именно поэтому вы получаете значение результата 0 -> Они одинаковы.

Итак, вам нужно помнить, что вы сравниваете правильные контуры. В этом случае вы можете видеть только контуры, которые можно проверить визуально, но у вас может быть несколько контуров, и вам нужно что-то придумать, чтобы отфильтровать их и выбрать, какие из них сравнивать. В этом случае вы знаете, так что вы могли бы сделать:

import cv2
import numpy as np
img_1 = cv2.imread(Ƈ.png', 0)
img_2 = cv2.imread(ƈ.png', 0)

ret, thresh = cv2.threshold(img_1, 127, 255, 0)
ret, thresh2 = cv2.threshold(img_2, 127, 255, 0)
contours1, hierarchy = cv2.findContours(thresh, 2, 1)

cnt1 = contours1[1]
contours2, hierarchy = cv2.findContours(thresh2, 2, 1)

cnt2 = contours2[1]
ret = cv2.matchShapes(cnt1, cnt2, 1, 0.0)

print(ret)

В этом случае вы будете сравнивать правильные контуры.

Выходы:

15.69319078874479

Надеюсь, поможет.


Попробуйте переименовать переменные, которые вы используете, чтобы они отличались друг от друга, чтобы не мешать существующим указателям:

c1, h1= cv2.findContours(thresh, 2, 1)
cnt1 = c1[0]
c2, h2 = cv2.findContours(thresh2, 2, 1)
cnt2 = c2[0]
ret = cv2.matchShapes(cnt1, cnt2, 1, 0.0)