所以我有一个图像可以说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"
还有另一个cv2
模块,但它并没有安装在我的mac上。
pip install cv2
在找到包裹时失败了。
答案 0 :(得分:4)
以下代码适用于我:
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)
输出: 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))
<强>更新强>
根据您提供的图片,您会注意到匹配的设置方式,它只会匹配这两个中的一个。左上角是针对针图像裁剪的一个,因此它完全匹配。右下角的图像需要精确匹配像素。通过这种实现,即使其中一个颜色通道中的单个位差异也会导致它被忽略。
经过测试的版本