在更大的图像内找到图像的位置

vks*_*vks 7 python numpy image-processing

所以我有一个图像让我们说small.png和一个更大的图像big.png.小图像在较大的图像中出现2次,我希望找到它的位置.

我尝试使用numpy和Image但是出错了

'JpegImageFile' object has no attribute '__getitem__'我之前有png格式,它给出了同样的错误.

是否有任何其他模块或方法来完成这一点.我对任何人开放.

现在抛出错误的代码是

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"
Run Code Online (Sandbox Code Playgroud)

有另一个cv2模块,但它只是没有安装在我的Mac上. pip install cv2找不到包装上的说法.

在此输入图像描述

在此输入图像描述

jed*_*rds 5

以下代码对我有用:

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)
Run Code Online (Sandbox Code Playgroud)

输出: 312 237

图形化:

在此处输入图片说明

使用测试图像

lenna.png

伦娜

eye.png

眼睛

注意:创建较小的裁剪版本时,请使用无损图像格式,这一点很重要(PNG是无损的,JPEG通常是有损的)。如果使用有损格式,则可能会冒像素值接近但不相同的风险。上面基于您的代码只能找到逐像素的精确匹配。在这方面,OpenCV模板匹配功能更加灵活。这并不是说您不能修改代码以使其正常工作。但就目前而言,此答案中的代码具有该限制。

更一般的版本

在这里,作为函数,它将收集所有匹配的坐标,并将它们作为(x,y)元组的列表返回:

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))
Run Code Online (Sandbox Code Playgroud)

更新:

给定您提供的图像,您会注意到匹配的设置方式,它将仅匹配此处的两个之一。左上角的一个是您为针形图像裁剪的一个,因此它完全匹配。右下角的图像需要精确地逐像素匹配。通过这种实现方式,即使在一个颜色通道中只有一点点的差异也会导致它被忽略。

事实证明,这两者之间的差异要大得多: 在此处输入图片说明

测试版本:

  • 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