Я бы пошел с чистым PIL.
- Прочитать на изображении и грецкий орех.
- Возьмите любой пиксель грецкого ореха.
- Найти все изображения изображения схожи друг от друга.
- Проверьте, совпадают ли окружающие пиксели с окружающими пикселями грецкого ореха (и перерыв, как только вы найдете одно несоответствие, чтобы свести к минимуму время).
Теперь, если изображение использует сжатие с потерями (например, 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')
В основном, один случайный пиксель грецкого ореха и ищет лучший матч. Это первый шаг с не слишком плохим выходом:
То, что вы все еще хотите сделать это:
Увеличением выборки пространства (не только с помощью одного пикселя, но может быть 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
выходами например:
могли бы вы предоставить орех как отдельное изображение с альфа? (Я хотел бы провести некоторое тестирование). – Hyperboreus
Добавил отдельное изображение грецкого ореха на столбе, не уверен точно, как альфа работает с PNG, но это сработало для меня в маске MS, используя прозрачный инструмент выделения – user2461391
@ user2461391 Я разместил несколько примеров кода. – Hyperboreus