2010-06-15 43 views
19

Tôi đang cố gắng sử dụng python để xác định xem một (nhỏ) hình ảnh có nằm trong một hình ảnh (lớn) khác không.Cách tìm hình ảnh trong hình ảnh khác bằng cách sử dụng python

Bất kỳ đề xuất nào trước khi tôi tự hoàn toàn đi sai đường dẫn?

/chỉnh sửa: Ok, một số ý tưởng: Tôi đang sử dụng PIL và tôi chuyển đổi từng hình ảnh sang chế độ 'P' để tôi có thể so sánh từng pixel dưới dạng số nguyên. Tôi đang cố gắng để thực hiện một cái gì đó giống như một tìm kiếm chuỗi Boyer-Moore hoặc thuật toán Knuth-Morris – Pratt, nhưng trong 2 chiều.

Có lẽ điều này sẽ giúp: thay vì tìm kiếm ABC in XXXABCXXX (câu trả lời = 4), chúng tôi đang tìm kiếm

ABC  
DEF  
GHI  

trong

XXXXX   
XABCX   
XDEFX  
XGHIX  
XXXXX 

(câu trả lời = (2,2))

+1

Bạn đang tìm kiếm hình ảnh nhỏ chính xác hoặc hình ảnh có thể được xoay/nghiêng/thu nhỏ/etc? –

+0

1 hình ảnh nhỏ chính xác. – Zach

+1

Zach, bạn đã từng giải quyết vấn đề này chưa? Tôi đang ở trong cùng một chiếc thuyền ngay bây giờ – mikew

Trả lời

8

EDIT: Ok, đây là cách ngây thơ để làm điều này:

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) 

Nó hoạt động tốt, nhưng tôi muốn TỐC ĐỘ NÓI. Tôi nghĩ rằng chìa khóa nằm trong mảng 'test' mà chúng ta có thể sử dụng để bỏ qua một số vị trí trong hình ảnh.

Chỉnh sửa 2: Đảm bảo bạn sử dụng hình ảnh ở định dạng ít hao tổn để kiểm tra điều này.

On Mac, cài đặt gối và from PIL import Image

+0

Làm cách nào để chuyển đổi sang chế độ 'P' .... nếu hình ảnh của tôi là 'png' hoặc' jpg' – vks

6

Sikuli hiện nó bằng cách sử dụng OpenCV, xem here cách match_by_template hoạt động và sau đó sử dụng các ràng buộc Python OpenCV để làm như vậy. Làm việc đó mà không OpenCV nên cứng, hãy xem tài liệu OpenCV, tìm kiếm mẫu phù hợp, vv ...

3

Tôi biết đó là một chút trễ, nhưng bạn có thể sử dụng Boyer-Moore để tìm kiếm những dòng đầu tiên của hình ảnh nhỏ trong mỗi dòng của hình ảnh lớn. Thời điểm bạn tìm thấy kết quả phù hợp với vị trí X và Y và bạn chỉ cần kiểm tra xem phần còn lại của các dòng của hình ảnh nhỏ hơn có khớp với phần còn lại của các dòng của hình ảnh lớn hơn bắt đầu từ vị trí X và Y + 1,2 hay không, 3, ... Tại sự không phù hợp đầu tiên tiếp tục với việc tìm kiếm các dòng đầu tiên. Tôi không nghĩ rằng bạn có thể nhận được nhanh hơn này.

+0

Bạn có thể đăng một số mã mẫu không? – Zach

+0

tôi cũng thực sự đánh giá cao một ví dụ về cách sử dụng Boyer-Moore (-Horspool) trong không gian 2d – mikew

+2

thực sự câu trả lời này chỉ tối ưu hóa trong một chiều, trên mặt phẳng X.bạn đang đẩy nhanh quá trình tìm kiếm ngang bằng cách sử dụng B-M bằng cách dịch chuyển qua. nhưng thế thì bạn đang tìm kiếm ngây thơ trong mặt phẳng veritcal, vì bạn không bao giờ chuyển xuống. vẫn còn rất trực quan và chắc chắn là một sự cải tiến – mikew

0

Hãy xem câu trả lời của tôi cho một câu hỏi tương tự cho một số code example using OpenCV. Việc chuyển đổi từ PIL thành tiền gửi là thẳng về phía trước, ví dụ: chỉ cần sử dụng np.array(pilimage).

Các vấn đề liên quan