win11 python opencv作图像匹配小结
最近做了一个用到python opencv的项目,安装编码都是非常可快速的,使用中遇到一些奇怪问题。
1、安装
w11下,cmd直接
pip install opencv-python
检验是否安装成功:
import cv2
print(cv2.__version__)
2、截屏功能
两种写法都可以:
from PIL import ImageGrab
bbox = [10,120,350,450]
im = ImageGrab.grab(bbox = bbox)
import pyautogui
screenshot = pyautogui.screenshot(region=(x1, y1, x2 - x1, y2 - y1))
截屏完,要转换为np.array,如:
import numpy as np
np.array(screenshot)
3、图像识别接口
cv2.matchTemplate
函数的语法如下:
result = cv2.matchTemplate(image, templ, method[, mask])
- image:待匹配的大图像。
- templ:用于匹配的模板图像。不得超过image,否则会报错。
- method:匹配方法,常见的有:cv2.TM_CCOEFF、cv2.TM_CCOEFF_NORMED、cv2.TM_CCORR、cv2.TM_CCORR_NORMED、cv2.TM_SQDIFF、cv2.TM_SQDIFF_NORMED。
- mask(可选):用于指定在源图像和模板图像上进行匹配的区域。
常见的匹配方法包括:
- cv2.TM_CCOEFF:计算相关系数。
- cv2.TM_CCOEFF_NORMED:归一化相关系数。
- cv2.TM_CCORR:计算相关和。
- cv2.TM_CCORR_NORMED:归一化相关和。
- cv2.TM_SQDIFF:计算平方差。
- cv2.TM_SQDIFF_NORMED:归一化平方差。
4、封装函数
我自己封装了一个函数:
def grab_and_match(template_image_file, bbox):
im = ImageGrab.grab(bbox = bbox)
im.save(r"temp.jpeg")
image = cv2.imread('temp.jpeg', cv2.IMREAD_GRAYSCALE)
item_get_template = cv2.imread(template_image_file, cv2.IMREAD_GRAYSCALE)
res = cv2.matchTemplate(image, item_get_template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# print(f'min_val {min_val}, max_val {max_val}, min_loc {min_loc}, max_loc {max_loc}')
return max_val >= 0.9
写的有点挫,截屏后,先save了下,然后用cv2读出,保证与template一样得读取操作。如果直接使用截屏得image,调用matchTemplate会出错。
后来看到别人封装的接口,感觉更通用些:
def find_image_in_area(image_path, x1, y1, x2, y2, threshold=0.8):
try:
screenshot = pyautogui.screenshot(region=(x1, y1, x2 - x1, y2 - y1))
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
screenshot_inverted = cv2.bitwise_not(screenshot)
inverted_template = invert_image_colors(image_path)
res = cv2.matchTemplate(screenshot_inverted, inverted_template, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(res)
if max_val >= threshold:
h, w, _ = inverted_template.shape
center_x = max_loc[0] + w // 2 + x1
center_y = max_loc[1] + h // 2 + y1
return center_x, center_y
else:
print(f'max_val {max_val}, max_loc {max_loc}')
return None
except Exception as e:
print(f"Error: {e}")
return None
除了进行图像匹配,还返回了匹配到的图像的中心,便于后面业务使用。