2013-06-29 3 views
0

Я пытаюсь сделать так, как описано здесь: Finding a subimage inside a Numpy image, чтобы иметь возможность искать изображение внутри снимка экрана.Поиск небольшого изображения внутри большого (PIL + OpenCV)

код выглядит следующим образом:

import cv2 
import numpy as np 
import gtk.gdk 
from PIL import Image 

def make_screenshot(): 
    w = gtk.gdk.get_default_root_window() 
    sz = w.get_size() 
    pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, sz[0], sz[1]) 
    pb = pb.get_from_drawable(w, w.get_colormap(), 0, 0, 0, 0, sz[0], sz[1]) 
    width, height = pb.get_width(), pb.get_height() 
    return Image.fromstring("RGB", (width, height), pb.get_pixels()) 

if __name__ == "__main__": 
    img = make_screenshot() 
    cv_im = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) 
    template = cv_im[30:40, 30:40, :] 
    result = cv2.matchTemplate(cv_im, template, cv2.TM_CCORR_NORMED) 
    print np.unravel_index(result.argmax(), result.shape) 

В зависимости от выбранного метода (вместо cv2.TM_CCORR_NORMED) Я получаю совершенно разные координаты, но ни один из них не является (30, 30), как в примере.

Пожалуйста, научите меня, что случилось с таким подходом?

+0

matchtemplate дает вам верхний левый угол прямоугольника, окружающего объект. ты это проверил? –

+0

Да, я знаю это, и это дает мне (0, 0) или (256, 400) или что-то в этом роде. Ничто не близко к реальности. – Enchantner

ответ

0

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

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result) 

Переменная MAXLOC проведет кортеж, содержащий х, у индексов верхнего левого угла из лучший матч.

Длинный ответ:

cv2.matchTemplate() возвращает один канал изображения, где количество по каждому индексу соответствует тому, насколько хорошо входному изображению соответствует шаблону по этому индексу. Попробуйте визуализировать результат, вставив следующие строки кода после вашего вызова matchTemplate, и вы увидите, почему у numpy было бы трудное время, чтобы понять это.

cv2.imshow("Debugging Window", result) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

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

Этот код работал для меня на образце, которое я читал из файла. Если ваш код продолжает плохо себя вести, вы, вероятно, не читаете свои изображения так, как хотите. Вышеприведенный фрагмент кода полезен для отладки с помощью OpenCV. Замените результат аргумента imshow на имя любого объекта изображения (массив numpy), чтобы визуально подтвердить, что вы получаете нужное изображение.