Это не лучшее решение, но это решение. Я хотел бы узнать о лучших методах:
Если они не будут вращаться или масштабироваться, вы можете использовать простую взаимную корреляцию изображений. Там будет яркий пик, где маленькое изображение встречается на большом изображении.
Вы можете ускорить взаимную корреляцию, используя метод БПФ, но если вы просто сопоставляете небольшое исходное изображение с большим целевым изображением, метод умножения-и-сложения методом грубой силы иногда (не обычно) быстрее.
Источник:
Цель:
Кросс-корреляция:
Два ярких пятна - это места, которые совпадают.
Но вы делаете , имеют параметр вращения в вашем примере изображения, так что не будет работать сам по себе. Если разрешено только вращение, но не масштабирование, тогда все еще возможно использовать взаимную корреляцию, но вам необходимо взаимно коррелировать, вращать источник, взаимно коррелировать его со всем целевым изображением, вращать его снова и т. Д. Для все вращения.
Обратите внимание, что это не обязательно когда-либо найти изображение. Если исходное изображение является случайным шумом, а цель - случайным шумом, вы не найдете его, если не будете искать точно под прямым углом. В нормальных ситуациях он, вероятно, найдет его, но это зависит от свойств изображения и углов, в которых вы ведете поиск.
Эта страница показывает пример того, как это будет сделано, но не дает алгоритм.
Любое смещение, где сумма выше некоторого порога, является совпадением. Вы можете рассчитать качество совпадения, сопоставив исходное изображение с самим собой и разделив все свои суммы на это число. Идеальное совпадение будет 1,0.
Это будет очень сложным в вычислительном отношении, хотя, и, вероятно, есть лучшие методы для сопоставления шаблонов точек (о которых я хотел бы знать).
Пример быстрого Python с использованием градаций серого и метода FFT:
from __future__ import division
from pylab import *
import Image
import ImageOps
source_file = 'dots source.png'
target_file = 'dots target.png'
# Load file as grayscale with white dots
target = asarray(ImageOps.invert(Image.open(target_file).convert('L')))
close('all')
figure()
imshow(target)
gray()
show()
source_Image = ImageOps.invert(Image.open(source_file).convert('L'))
for angle in (0, 180):
source = asarray(source_Image.rotate(angle, expand = True))
best_match = max(fftconvolve(source[::-1,::-1], source).flat)
# Cross-correlation using FFT
d = fftconvolve(source[::-1,::-1], target, mode='same')
figure()
imshow(source)
# This only finds a single peak. Use something that finds multiple peaks instead:
peak_x, peak_y = unravel_index(argmax(d),shape(d))
figure()
plot(peak_y, peak_x,'ro')
imshow(d)
# Keep track of all these matches:
print angle, peak_x, peak_y, d[peak_x,peak_y] / best_match
1-цветные растровые изображения
Для одноцветных растровых изображений это будет намного быстрее. Кросс-корреляция становится:
- Поместите исходное изображение поверх целевого изображения
- Переместить исходное изображение на 1 пиксель
- побитовое И все перекрывающиеся пиксели
- суммировать все 1
- ...
Пороговое преобразование изображения в градациях серого в двоичный файл и последующее выполнение этого может быть достаточно хорошим.
Облако точек
Если источник и цель являются точечными паттернами, более быстрый способ - найти центры каждой точки (выполнить взаимную корреляцию один раз с известной точкой, а затем найти пики) и сохранить их как набор точек, а затем сопоставить источник нацеливаться, поворачивая, переводя и находя ошибку наименьших квадратов между ближайшими точками в двух наборах.