Đây không phải là giải pháp tốt nhất, nhưng nó là một giải pháp. Tôi muốn tìm hiểu các kỹ thuật tốt hơn:
Nếu chúng không được xoay hoặc thu nhỏ, bạn có thể sử dụng một mối tương quan chéo đơn giản của hình ảnh. Sẽ có một đỉnh sáng bất cứ nơi nào hình ảnh nhỏ xuất hiện trong hình ảnh lớn.
Bạn có thể tăng tốc độ tương quan chéo bằng cách sử dụng phương pháp FFT, nhưng nếu bạn chỉ khớp một hình ảnh nguồn nhỏ với một hình ảnh mục tiêu lớn, thì phương pháp nhân và thêm của brute-force đôi khi (thường không) nhanh hơn.
Nguồn:
Mục tiêu:
Tương quan chéo:
Hai điểm sáng là vị trí phù hợp.
Nhưng bạn làm có một tham số xoay theo hình ảnh ví dụ của bạn, do đó sẽ không làm việc của chính nó. Nếu chỉ cho phép xoay và không chia tỷ lệ, thì vẫn có thể sử dụng tương quan chéo, nhưng bạn cần tương quan chéo, xoay nguồn, tương quan chéo với toàn bộ ảnh đích, xoay lại, v.v. tất cả các vòng quay.
Lưu ý rằng điều này sẽ không nhất thiết phải tìm thấy hình ảnh. Nếu hình ảnh nguồn là nhiễu ngẫu nhiên và mục tiêu là nhiễu ngẫu nhiên, bạn sẽ không tìm thấy nó trừ khi bạn tìm kiếm ở góc chính xác. Đối với các tình huống thông thường, nó có thể sẽ tìm thấy nó, nhưng nó phụ thuộc vào thuộc tính hình ảnh và các góc bạn tìm kiếm.
Trang này hiển thị một ví dụ về cách nó sẽ được thực hiện, nhưng không đưa ra thuật toán.
Bất kỳ giá trị bù nào có tổng nằm trên ngưỡng nào đó đều khớp. Bạn có thể tính toán mức độ tốt của trận đấu bằng cách tương quan hình ảnh nguồn với chính nó và chia tất cả số tiền của bạn cho số này. Một trận đấu hoàn hảo sẽ là 1.0.
Tuy nhiên, điều này sẽ rất nặng về tính toán, và có lẽ có các phương pháp tốt hơn để kết hợp các mẫu chấm (mà tôi muốn biết).
Ví dụ Python nhanh sử dụng phương pháp thang độ xám và 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
Ảnh bitmap 1 màu
Đối với bitmap 1 màu, tuy nhiên, điều này sẽ nhanh hơn nhiều. Tương quan chéo trở thành:
- Đặt hình ảnh nguồn trên hình ảnh mục tiêu
- Di chuyển hình ảnh nguồn 1 pixel
- bitwise-VÀ tất cả các pixel chồng lấp
- tổng tất cả 1
- ...
Đập một hình ảnh thang độ xám thành nhị phân và sau đó làm điều này có thể là đủ tốt.
Đám mây điểm
Nếu nguồn và đích là cả hai mẫu chấm, phương pháp nhanh hơn sẽ là tìm tâm của mỗi dấu chấm (tương quan chéo một lần với dấu chấm đã biết và sau đó tìm các đỉnh) và lưu trữ chúng dưới dạng tập hợp điểm, sau đó khớp nguồn để nhắm mục tiêu bằng cách xoay, dịch và tìm lỗi bình phương nhỏ nhất giữa các điểm gần nhất trong hai bộ.