Skip to main content

图片识别

透明背景图片识别思路

image-20220315170634753

我们可以直观的看到,如果两张截图的背景有很大的不同,这说明在目标识别中,我们需要排除背景的干扰,否则简单的使用逐像素匹配,是肯定行不通的。因此,我在笔记本上对活动按钮进行了五次截图,保留截图中的共同部分,得到了透明背景的活动按钮“活动”二字

提取相同部分出来

  • 对统一范围进行多次截图
  • 对比所有图片,将同一位置都相同的像素点提取出来

此方法适用于目标位置是相对背景不会发生改变的,如果前置还有改变的情况,此种方式需要更细粒度的提取

将相同的部分提取出来

import cv2
import numpy as np

# 读取图片,丢弃Alpha通道,转为灰度图
a = cv2.imread('pc_activity_btn.png', cv2.IMREAD_GRAYSCALE)
# 读取图片,并保留Alpha通道
b = cv2.imread('transparent_activity_btn.png', cv2.IMREAD_UNCHANGED)

# 取出Alpha通道
alpha = b[:,:,3]

# 将透明点置0
a = cv2.bitwise_and(a, alpha)
b = cv2.bitwise_and(cv2.cvtColor(b, cv2.COLOR_BGRA2GRAY), alpha)

# 比较两张图,打印不相等的像素个数
print(np.count_nonzero(cv2.compare(a, b, cv2.CMP_NE)))

使用模板识别

将误差纳入考量范围,同时兼顾大图中找小图的需要,使用cv2.matchTemplate 来实现,通过使用Alpha通道作为Mask可以排除透明部分,代码示例如下:

import cv2
import numpy as np

# 读取图片,丢弃Alpha通道,转为灰度图
a = cv2.imread('pc_activity_btn.png', cv2.IMREAD_GRAYSCALE)

# 读取图片,并保留Alpha通道
b = cv2.imread('transparent_activity_btn.png', cv2.IMREAD_UNCHANGED)

# 取出Alpha通道
alpha = b[:,:,3]

# 模板匹配,将alpha作为mask,TM_CCORR_NORMED方法的计算结果范围为[0, 1],越接近1越匹配
result = cv2.matchTemplate(a, b, cv2.TM_CCORR_NORMED, mask=alpha)

# 获取结果中最大值和最小值以及他们的坐标
print(cv2.minMaxLoc(result))

# 运行结果:
# (0.9999997615814209, 0.9999997615814209, (0, 0), (0, 0))

上面的代码中,我们是判断两张活动按钮截图的相似程度,下面尝试是否能在窗口截图中定位活动按钮的位置:

CV2 模版匹配

对比两张图片的相似度

def match_img(img1, img2):