matchtemplate openCv2 python не соответствует похожему виду - PullRequest
0 голосов
/ 12 января 2020

У меня есть изображение, которое меняет его случайным образом, поэтому иногда OpenCV распознает объект, а иногда нет:

Мой код:

grey_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
grey_temp = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY)

w, h = grey_temp.shape[::-1]

res = cv2.matchTemplate(grey_img, grey_temp, cv2.TM_CCOEFF_NORMED)
print(res)

threshold = 0.8;
loc = np.where(res >= threshold)
print(loc)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (255,0,0), 3)

cv2.imshow('win', img)
cv2.waitKey()

Код Симлара с emguCv:

Mat background = CvInvoke.Imread(file, 
Emgu.CV.CvEnum.ImreadModes.AnyColor);//Convert Image to ReducedGrayscale2
Mat find = CvInvoke.Imread(compered, Emgu.CV.CvEnum.ImreadModes.AnyColor);
Mat match = CvInvoke.Imread(compered, Emgu.CV.CvEnum.ImreadModes.AnyColor);
CvInvoke.MatchTemplate(background, find, match, TemplateMatchingType.CcoeffNormed);         
double[] minValues, maxValues;
Point[] minLocations, maxLocations;
match.MinMax(out minValues, out maxValues, out minLocations, out maxLocations);
            if (maxValues[0] > 0.7)
            {
                Console.WriteLine("found");
                Rectangle match1 = new Rectangle(maxLocations[0],);
                match.Draw(match1, new Bgr(Color.Red), 3);
            }

        CvInvoke.Imshow("Image1", background);
        CvInvoke.WaitKey(0);

(Кстати, изменение порога не влияет)

Пример распознавания:

Recognition with low threshold

The template

Я хочу знать, есть ли у вас какая-то идея, как мне удается отслеживать один и тот же объект рисунка на фотографии без зависимости от цвета, оттенков серого или его местоположения ( у объекта есть некоторые схожие общие свойства, поэтому в человеческом глазу он называется легко отслеживаемым).

Я пытался проделать тот же прогресс с emguCv для c, чтобы проверить, есть ли другие результаты в результате, но никаких сюрпризов , нет разницы. Я был бы признателен, если бы вы могли предложить мне, как управлять шаблоном в основном изображении. Заранее спасибо!

1 Ответ

0 голосов
/ 13 января 2020

Один из подходов, нечувствительных к цвету, заключается в сопоставлении шаблонов на бинарных извлеченных изображениях. Так что, похоже, это работает в Python / OpenCV.

  • Считайте изображение и шаблон в градациях серого
  • Do Canny edge Detection с L2gradient = True
  • Do Normalized Cross Correlation с этими краевыми изображениями
  • Получите местоположение максимального значения корреляции
  • Поместите белые края шаблона в красный цвет по краям изображения

Изображение:

enter image description here

Шаблон:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('blue_object.png')

# convert img to grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# read template as grayscale
tmplt = cv2.imread('pink_template.png', cv2.IMREAD_GRAYSCALE)
hh, ww = tmplt.shape

# do canny edge detection on image and template
img_edges = cv2.Canny(img_gray,100,200,3,L2gradient=True)
tmplt_edges = cv2.Canny(tmplt,100,200,3,L2gradient=True)

# do template matching
corrimg = cv2.matchTemplate(img_edges,tmplt_edges,cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(corrimg)
max_val_ncc = '{:.3f}'.format(max_val)
print("normalize_cross_correlation: " + max_val_ncc)
xx = max_loc[0]
yy = max_loc[1]
print('xmatchloc =',xx,'ymatch =',yy)

# offset the templt_edges image to place at match point in black image the size of the img_edges
templt_edges_match = np.full_like(img_edges, 0)
templt_edges_match[yy:yy+hh, xx:xx+ww] = tmplt_edges

# draw template edges in red onto img edges
result1 = img_edges.copy()
result1 = cv2.merge((result1, result1, result1))
result1[templt_edges_match==255] = (0,0,255)

# draw template edges in red onto img
result2 = img.copy()
result2[templt_edges_match==255] = (0,0,255)

cv2.imshow('image', img)
cv2.imshow('template', tmplt)
cv2.imshow('image edges', img_edges)
cv2.imshow('template edges', tmplt_edges)
cv2.imshow('result1', result1)
cv2.imshow('result2', result2)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('edge_template_match_on_image_edges.png', result1)
cv2.imwrite('edge_template_match_on_image.png', result2)


Результат 1:

enter image description here

Результат 2:

enter image description here

Местоположение матча:

xmatchloc = 59 ymatch = 36
...