在另一张图像中查找透明的(png)图像

4
我有一张截图,需要在其中找到一些图片(始终具有相同的大小、旋转角度等)。我已经找到了一些使用PIL和numpy的解决方案,但它们仅适用于非透明图像。我必须找到像圆形这样的东西,因此我必须在其后面使用透明背景。
示例图像如下所示:
https://istack.dev59.com/CUvHH.webp 我正在寻找一个类似于以下目标:
https://istack.dev59.com/iqalO.webp 有什么想法可以实现这个吗?

请您添加一个示例图片,您的代码和期望的结果。 - alko
我尝试使用来自https://dev59.com/1HA75IYBdhLWcg3w49UR的代码,但是我遇到了一个错误:if test.all():AttributeError: 'bool' object has no attribute 'all'实际上,我意识到我可以使用普通的矩形图像而不是圆形和透明背景。这是一个示例截图和我想要找到的图像:http://mopsiok.comuv.com/uploader/screen_.png和http://mopsiok.comuv.com/uploader/cookie.png。 - mopsiok
我在问题中没有看到透明度的任何参考。是标题误导了还是我错过了什么? - kraftydevil
2个回答

3

由于你正在完全匹配图像,因此很容易创建一个滑动块来查找目标。这不是最快的解决方案,但很容易使其正常工作。

import numpy as np
from scipy.misc import imread

screen = imread("screen.png")
target = imread("cookie.png")

def find_match(screen, target):
    dx,dy,_ = target.shape

    for x in xrange(screen.shape[0]-dx):
        for y in xrange(screen.shape[1]-dy):
            diff = (screen[x:x+dx,y:y+dy,:]-target)
            dz = np.abs(diff).sum()
            if dz == 0: return x,y, dx, dy
    return None, None, None, None

x,y,dx,dy = find_match(screen, target)

# Show the result

import pylab as plt
plt.subplot(121)
plt.imshow(screen)

screen_sample = np.copy(screen)
screen_sample[x:x+dx,y:y+dy,:] = 0
plt.subplot(122)
plt.imshow(screen_sample)

plt.tight_layout()
plt.show()

enter image description here


2

谢谢回复!我再次分析了我上面发布的主题,有了一些想法。你的代码很简单,但执行时间需要约40秒。我已经做了以下改进:

def search(screen, img):
sx, sy = screen.size
ix, iy = img.size
for xstart in range(sx - ix): 
    for ystart in range(sy - iy):
        #search for the pixel on the screen that equals the pixel at img[0:0]
        if img.getpixel((0,0)) == screen.getpixel((xstart, ystart)):
            match = 1 #temporary
            for x in range(ix): #check if first row of img is on this coords
                if img.getpixel((x,0)) <> screen.getpixel((xstart+x, ystart)):
                    match = 0 #if there's any difference, exit the loop
                    break 
            if match == 1: #otherwise, if this coords matches the first row of img
                for x in range(ix): 
                    for y in range(iy):
                        #check every pixel of the img
                        if img.getpixel((x,y)) <> screen.getpixel((xstart+x, ystart+y)):
                            match = 0 #any difference - break
                            break
                if match == 1: return (xstart, ystart) #return top-left corner coordinates
return (-1,-1) #or this, if not found

它使用的是getpixel方法,这种方法速度相对较慢,但执行时间约为4秒,我对此非常满意。感谢你的关注!

祝好, mopsiok


如果其他解决方案对您有帮助,请投票支持它们是标准做法。如果您的答案是有效的,请务必接受它! - Hooked

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接