2014-01-24 4 views
7

Моя цель - найти местоположение определенных изображений на других изображениях с помощью python. Возьмем такой пример:Поиск положения объекта на изображении

enter image description here enter image description here

Я хочу найти местоположение грецкого ореха в изображении. Изображение грецкого ореха известно, поэтому я думаю, что нет необходимости в каком-либо расширенном сопоставлении шаблонов или машинного обучения, чтобы сказать, что что-то такое грецкий орех или нет.

Как я могу найти грецкий орех на картинке? Будет ли работать стратегия по этим направлениям:

  • чтения изображения с PIL
  • превратить их в Numpy массивы
  • использование графических фильтров SciPy в

Спасибо (какие фильтры?)!

ответ

9

Я бы пошел с чистым PIL.

  1. Прочитать на изображении и грецкий орех.
  2. Возьмите любой пиксель грецкого ореха.
  3. Найти все изображения изображения схожи друг от друга.
  4. Проверьте, совпадают ли окружающие пиксели с окружающими пикселями грецкого ореха (и перерыв, как только вы найдете одно несоответствие, чтобы свести к минимуму время).

Теперь, если изображение использует сжатие с потерями (например, JFIF), грецкий орех изображения не будет точно таким же, как у орехового рисунка. В этом случае вы можете определить некоторый порог для сравнения.


EDIT: Я использовал следующий код (путем преобразования белого к альфа, цвет оригинального ореха изменился незначительно):

#! /usr/bin/python2.7 

from PIL import Image, ImageDraw 

im = Image.open ('zGjE6.png') 
isize = im.size 
walnut = Image.open ('walnut.png') 
wsize = walnut.size 
x0, y0 = wsize [0] // 2, wsize [1] // 2 
pixel = walnut.getpixel ((x0, y0)) [:-1] 

def diff (a, b): 
    return sum ((a - b) ** 2 for a, b in zip (a, b)) 

best = (100000, 0, 0) 
for x in range (isize [0]): 
    for y in range (isize [1]): 
     ipixel = im.getpixel ((x, y)) 
     d = diff (ipixel, pixel) 
     if d < best [0]: best = (d, x, y) 

draw = ImageDraw.Draw (im) 
x, y = best [1:] 
draw.rectangle ((x - x0, y - y0, x + x0, y + y0), outline = 'red') 
im.save ('out.png') 

В основном, один случайный пиксель грецкого ореха и ищет лучший матч. Это первый шаг с не слишком плохим выходом:

enter image description here

То, что вы все еще хотите сделать это:

  • Увеличением выборки пространства (не только с помощью одного пикселя, но может быть 10 или 20).

  • Не только проверить лучшее совпадение, но и наилучшие 10 матчи для экземпляров.


EDIT 2: Некоторые улучшения

#! /usr/bin/python2.7 
import random 
import sys 
from PIL import Image, ImageDraw 

im, pattern, samples = sys.argv [1:] 
samples = int (samples) 

im = Image.open (im) 
walnut = Image.open (pattern) 
pixels = [] 
while len (pixels) < samples: 
    x = random.randint (0, walnut.size [0] - 1) 
    y = random.randint (0, walnut.size [1] - 1) 
    pixel = walnut.getpixel ((x, y)) 
    if pixel [-1] > 200: 
     pixels.append (((x, y), pixel [:-1])) 

def diff (a, b): 
    return sum ((a - b) ** 2 for a, b in zip (a, b)) 

best = [] 

for x in range (im.size [0]): 
    for y in range (im.size [1]): 
     d = 0 
     for coor, pixel in pixels: 
      try: 
       ipixel = im.getpixel ((x + coor [0], y + coor [1])) 
       d += diff (ipixel, pixel) 
      except IndexError: 
       d += 256 ** 2 * 3 
     best.append ((d, x, y)) 
     best.sort (key = lambda x: x [0]) 
     best = best [:3] 

draw = ImageDraw.Draw (im) 
for best in best: 
    x, y = best [1:] 
    draw.rectangle ((x, y, x + walnut.size [0], y + walnut.size [1]), outline = 'red') 
im.save ('out.png') 

Запуск этого с scriptname.py image.png walnut.png 5 выходами например:

enter image description here

+0

могли бы вы предоставить орех как отдельное изображение с альфа? (Я хотел бы провести некоторое тестирование). – Hyperboreus

+0

Добавил отдельное изображение грецкого ореха на столбе, не уверен точно, как альфа работает с PNG, но это сработало для меня в маске MS, используя прозрачный инструмент выделения – user2461391

+0

@ user2461391 Я разместил несколько примеров кода. – Hyperboreus

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