最近学了一下使用python的opencv通过图像识别来进行自动化测试,点击按钮,给大家分享一下。
cv2:python的图像识别软件,据说功能非常强大,注意下载这个包的时候,不要搜索cv2,这个是没有的,应该搜索opencv-python,然后直接 import cv2 就可以了。
numpy :没啥说的,直接下载,强大的矩阵处理工具。
PIL:图像处理工具,我的环境是python3,这个只支持到2.7,目前没有3以上的版本,所以我们要下载这个:pillow,
然后:from PIL import Image。
然后就是selenium,webdriver之类的,不熟悉的可以看我的其他博客,上面有详细的讲解。
import cv2
import numpy
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
class GraphicalLocator(object):
def __init__(self, img_path):
self.locator = img_path
# x, y position in pixels counting from left, top corner
self.x = None
self.y = None
self.img = cv2.imread(img_path)
self.height = self.img.shape[0]
self.width = self.img.shape[1]
self.threshold = None
@property
def center_x(self):
return self.x + int(self.width / 2) if self.x and self.width else None
@property
def center_y(self):
return self.y + int(self.height / 2) if self.y and self.height else None
def find_me(self, drv):
# Clear last found coordinates
self.x = self.y = None
# Get current screenshot of a web page
scr = drv.get_screenshot_as_png()
# Convert img to BytesIO
scr = Image.open(BytesIO(scr))
# Convert to format accepted by OpenCV
scr = numpy.asarray(scr, dtype=numpy.float32).astype(numpy.uint8)
# Convert image from BGR to RGB format
scr = cv2.cvtColor(scr, cv2.COLOR_BGR2RGB)
# Image matching works only on gray images
# (color conversion from RGB/BGR to GRAY scale)
img_match = cv2.minMaxLoc(
cv2.matchTemplate(cv2.cvtColor(scr, cv2.COLOR_RGB2GRAY),
cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY),
cv2.TM_CCOEFF_NORMED))
# Calculate position of found element
self.x = img_match[3][0]
self.y = img_match[3][1]
# From full screenshot crop part that matches template image
scr_crop = scr[self.y:(self.y + self.height),
self.x:(self.x + self.width)]
# Calculate colors histogram of both template
# and matching images and compare them
scr_hist = cv2.calcHist([scr_crop], [0, 1, 2], None,
[8, 8, 8], [0, 256, 0, 256, 0, 256])
img_hist = cv2.calcHist([self.img], [0, 1, 2], None,
[8, 8, 8], [0, 256, 0, 256, 0, 256])
comp_hist = cv2.compareHist(img_hist, scr_hist,
cv2.HISTCMP_CORREL)
# Save threshold matches of: graphical image and image histogram
self.threshold = {'shape': round(img_match[1], 2),
'histogram': round(comp_hist, 2)}
# Return image with blue rectangle around match
return cv2.rectangle(scr, (self.x, self.y),
(self.x + self.width, self.y + self.height),
(0, 0, 255), 2)
if __name__ == '__main__':
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('网址:可以用百度之类的')
img_check = GraphicalLocator('需要匹配的图片(绝对路径也可以)')
img_check.find_me(driver)
cv2.imwrite('这里生成一个新图片,会将匹配的图片在原图中圈出来', img_check.find_me(driver))
is_found = True if img_check.threshold['shape'] >= 0.8 and img_check.threshold['histogram'] >= 0.4 else False
if is_found:
action = ActionChains(driver)
print(img_check.center_x, img_check.center_y)
action.move_by_offset(img_check.center_x, img_check.center_y)
action.click()
action.perform()
else:
print('无法识别')
GraphicalLocator类:
初始化函数:参数为需要匹配的图片的路径,然后里面定义了x,y坐标(左上角),要匹配的图片的高度和宽度,基于形状和颜色直方图的阈值。
center_x,center_y方法求出匹配后的图像的中心坐标。
find_me:参数为当前网页的网址,
然后就是一系列的矩阵处理,图像匹配,直方图计算等操作,最后返回一个图片带有矩形框,框住的是最佳匹配部分。
注意is_found变量表示一个阈值由直方图和形状相似度来计算,其中的参数可以自己调节。
以上全部参考了下面这篇文章,感谢大佬!!