Find location of image inside bigger image

↘锁芯ラ 提交于 2020-11-30 12:07:45

问题


So i have an image lets say small.png and a bigger image big.png .The small image occurs 2 times in the bigger image and i wish to find its location.

I tried using numpy and Image but got error

'JpegImageFile' object has no attribute '__getitem__'.I had png format earlier and it gave the same error.

Is there any other module or way to get this done.I am open to any .

The code as of now which throws error is

import numpy
from PIL import Image
here = Image.open(r"/Users/vks/Desktop/heren.jpg")
big = Image.open(r"/Users/vks/Desktop/Settingsn.jpg")
print here,big
herear = numpy.asarray(here)
bigar = numpy.asarray(big)
herearx = herear.shape[0]
hereary = herear.shape[1]

bigarx = bigar.shape[0]
bigary = bigar.shape[1]

print herearx , hereary , bigarx, bigary

stopx = bigarx - herearx + 1
stopy = bigary - hereary + 1

for x in range(0, stopx):
    for y in range(0, stopy):
        x2 = x+ herearx
        y2 = y + hereary
        pic = big[y:y2, x:x2] ===> error thrown here
        test = pic = here
        if test.all():
            print x,y
else:
    print "None"

There was another cv2 module but it just doesnt get installed on my mac. pip install cv2 fails saying on package found.


回答1:


The following code works for me:

import numpy
from PIL import Image

here = Image.open(r"eye.png")
big  = Image.open(r"lenna.png")

herear = numpy.asarray(here)
bigar  = numpy.asarray(big)

hereary, herearx = herear.shape[:2]
bigary,  bigarx  = bigar.shape[:2]

stopx = bigarx - herearx + 1
stopy = bigary - hereary + 1

for x in range(0, stopx):
    for y in range(0, stopy):
        x2 = x + herearx
        y2 = y + hereary
        pic = bigar[y:y2, x:x2]
        test = (pic == herear)
        if test.all():
            print(x,y)

Output: 312 237

Graphically:

Test Images Used

lenna.png

eye.png

Note: It's important that you use a lossless image format when you create the smaller, cropped version (PNG is lossless, JPEG is most usually lossy). If you use a lossy format, you risk the pixel values being close, but not identical. The above code based off yours will only find exact pixel-by-pixel matches. The OpenCV template matching functions are a bit more flexible in this regard. That is not to say you couldn't modify your code to work just as well, you could. But as it stands, the code in this answer has that limitation.

More general version

Here, as a function, this gathers all matching coordinates and returns them as a list of (x,y) tuples:

import numpy as np
from PIL import Image

im_haystack = Image.open(r"lenna.png")
im_needle   = Image.open(r"eye.png")

def find_matches(haystack, needle):
    arr_h = np.asarray(haystack)
    arr_n = np.asarray(needle)

    y_h, x_h = arr_h.shape[:2]
    y_n, x_n = arr_n.shape[:2]

    xstop = x_h - x_n + 1
    ystop = y_h - y_n + 1

    matches = []
    for xmin in range(0, xstop):
        for ymin in range(0, ystop):
            xmax = xmin + x_n
            ymax = ymin + y_n

            arr_s = arr_h[ymin:ymax, xmin:xmax]     # Extract subimage
            arr_t = (arr_s == arr_n)                # Create test matrix
            if arr_t.all():                         # Only consider exact matches
                matches.append((xmin,ymin))

    return matches

print(find_matches(im_haystack, im_needle))

Update:

Given the images you provided, you'll notice that the way the matching is set up, it will only match one of the two here's. The top-left one is one the one you cropped for the needle image, so it matches exactly. The bottom-right image would need to match exactly pixel-for-pixel. With this implementation, even a single bit difference in one of the color channels would cause it to be ignored.

As it turns out, the two here's vary quite a bit more:

Tested Versions:

  • Python 2.7.10, Numpy 1.11.1, PIL (Pillow) 1.1.7
  • Python 3.5.0, Numpy 1.10.4, PIL (Pillow) 1.1.7


来源:https://stackoverflow.com/questions/38473952/find-location-of-image-inside-bigger-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!