2010-06-15 2 views
19

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

Любые предложения до того, как я полностью опустил неправильный путь?

/edit: Хорошо, некоторые идеи: я использую PIL, и я преобразую каждое изображение в режим «P», чтобы сравнить каждый пиксель как целое число. Я пытаюсь реализовать что-то вроде строкового поиска Boyer-Moore или алгоритма Кнута-Морриса-Пратта, но в двух измерениях.

Может быть, это поможет: вместо того, чтобы искать ABC in XXXABCXXX (ответ = 4) мы ищем

ABC  
DEF  
GHI  

в

XXXXX   
XABCX   
XDEFX  
XGHIX  
XXXXX 

(ответ = (2,2))

+1

Вы ищете точное изображение или изображение может быть повернуто/перекошено/масштабировано/и т. Д.? –

+0

1 мелкий изображение точно. – Zach

+1

Зак, ты когда-нибудь это решил? Я сейчас в одной лодке – mikew

ответ

8

EDIT: Хорошо, вот наивный способ сделать это:

import Image, numpy 

def subimg(img1,img2): 
    img1=numpy.asarray(img1) 
    img2=numpy.asarray(img2) 

    #img1=numpy.array([[1,2,3],[4,5,6],[7,8,9]]) 
    #img2=numpy.array([[0,0,0,0,0],[0,1,2,3,0],[0,4,5,6,0],[0,7,8,9,0],[0,0,0,0,0]]) 

    img1y=img1.shape[0] 
    img1x=img1.shape[1] 

    img2y=img2.shape[0] 
    img2x=img2.shape[1] 

    stopy=img2y-img1y+1 
    stopx=img2x-img1x+1 

    for x1 in range(0,stopx): 
     for y1 in range(0,stopy): 
      x2=x1+img1x 
      y2=y1+img1y 

      pic=img2[y1:y2,x1:x2] 
      test=pic==img1 

      if test.all(): 
       return x1, y1 

    return False 

small=Image.open('small.tif') 
big=Image.open('big.tif') 

print subimg(small, big) 

Он работает просто отлично, но я хочу СКОРОСТИ. Я думаю, что ключ находится в массиве 'test', который мы могли бы использовать, чтобы пропустить некоторые позиции на изображении.

Редактирование 2: Убедитесь, что вы используете изображения в формате без потерь, чтобы проверить это.

На Mac установите подушку и from PIL import Image

+0

Как мы преобразуем в режим 'P' .... что, если мое изображение' png' или 'jpg' – vks

6

Sikuli использует OpenCV, см. here, как работает match_by_template, а затем использует привязки OpenCV Python для выполнения этого же действия. Делать это без OpenCV должно быть трудно, посмотрите на OpenCV документации, поиск соответствия шаблона и т.д ...

3

Я знаю, что это немного поздно, но вы можете использовать Boyer-Moore для поиска первой линии небольшого изображения в каждой из линий большого изображения. В тот момент, когда вы находите совпадение, у вас есть позиция X и Y, и вам просто нужно проверить, совпадает ли оставшаяся часть линий меньшего изображения с остальными строками большего изображения, начиная с позиций X и Y + 1,2, 3, ... При первом несоответствии продолжаются поиск первой строки. Я не думаю, что вы можете добиться этого быстрее.

+0

Не могли бы вы разместить код примера? – Zach

+0

Мне тоже очень понравился бы пример использования Boyer-Moore (-Horspool) в 2d-пространстве – mikew

+2

Фактически этот ответ только оптимизирует в одном измерении на плоскости X.вы ускоряете поиск горизонтального поиска с помощью B-M, перемещаясь поперек. но тогда вы делаете наивный поиск в veritcal плоскости, так как вы никогда не смещаетесь вниз. тем не менее, его очень интуитивное и, безусловно, улучшение – mikew

0

Посмотрите на мой ответ на аналогичный вопрос для code example using OpenCV. Преобразование из PIL в numpy является прямым, например. просто используйте np.array(pilimage).

Смежные вопросы