【图像识别UI自动测试技术第二章】模版匹配算法学习分享
一、简介
💢 SIFT特征匹配效果较差,谨慎使用。
-
主要用于在目标图像中找到模板图像的位置,支持单尺度模板匹配(TemplateMatcher)、多尺度模板匹配(MultiScale)和SIFT特征匹配(SIFTFeatureMatcher)三种方法。
-
正常使用时: 可以通过调用
im_match
函数选择最佳匹配结果; -
调试代码: 确认图像识别准确率时,可以
draw_rectangle
函数绘制匹配区域和中心点以便查看识别效果-
加载图像: 需要使用OpenCV加载目标图像和模板图像,格式为numpy数组。
-
匹配图像: 调用im_match函数,输入图像、模板和置信度阈值(默认0.6),返回匹配的坐标。
-
绘制结果: 用draw_rectangle函数在图像上绘制矩形,输入图像路径和坐标,返回绘制后的图像和中心点。
-
二、类和函数详细说明
TemplateMatcher类
1. 功能:
执行标准模板匹配,使用OpenCV
的matchTemplate
函数,方法默认使用cv2.TM_CCOEFF_NORMED
,适合模板和图像尺寸一致的场景。
2. 属性:
-
method:
模板匹配方法(默认cv2.TM_CCOEFF_NORMED
)。 -
threshold:
最小置信度阈值(默认0.7)。
3. 方法:
-
__init__(self, method=cv2.TM_CCOEFF_NORMED, threshold=0.7):
初始化匹配器,设置方法和阈值。 -
match(self, image, template):
执行模板匹配。-
参数:
-
image (numpy.ndarray):
目标图像。 -
template (numpy.ndarray):
模板图像。
-
-
返回:
-
元组
(top_left, bottom_right, confidence)
,其中:-
top_left:
匹配的左上角坐标(x, y)。 -
bottom_right:
匹配的右下角坐标(x, y)。 -
confidence:
置信度值(0到1之间)。
-
-
若未找到匹配(置信度低于阈值),返回((0, 0), (0, 0), 0)。
-
-
相关代码片段:
class TemplateMatcher:
def __init__(self, method=cv2.TM_CCOEFF_NORMED, threshold=0.7):
self.method = method
self.threshold = max(0.7, threshold)
def match(self, image, template):
h, w = template.shape[:2]
res = cv2.matchTemplate(image, template, self.method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if max_val >= self.threshold:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
return top_left, bottom_right, round(max_val, 3)
else:
return (0, 0), (0, 0), 0
MultiScale类
1. 功能:
执行多尺度模板匹配,通过缩放模板(默认比例1.0到0.5,步长0.1)进行多次匹配,适合处理不同尺寸的模板。
2. 属性:
-
scales:
缩放比例列表(默认[1.0, 0.9, 0.8, 0.7, 0.6, 0.5])。 -
threshold:
最小置信度阈值(默认0.7)。
3. 方法:
-
__init__(self, scales=None, threshold=0.7):
初始化多尺度匹配器,设置缩放比例和阈值。 -
match(self, image, template, method=cv2.TM_CCOEFF_NORMED):
执行多尺度模板匹配。-
参数:
-
image (numpy.ndarray):
目标图像。 -
template (numpy.ndarray):
模板图像。 -
method (int):
模板匹配方法(默认cv2.TM_CCOEFF_NORMED)。
-
-
返回:
-
元组(top_left, bottom_right, confidence),其中:
-
top_left:
匹配的左上角坐标(x, y)。 -
bottom_right:
匹配的右下角坐标(x, y)。 -
confidence:
置信度值(0到1之间)。
-
-
若未找到匹配(置信度低于阈值),返回((0, 0), (0, 0), 0)。
-
-
相关代码片段:
class MultiScale:
def __init__(self, scales=None, threshold=0.7):
if scales is None:
self.scales = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5]
else:
self.scales = scales
self.threshold = max(0.7, threshold)
def match(self, image, template, method=cv2.TM_CCOEFF_NORMED):
template_h, template_w = template.shape[:2]
best_loc = None
best_scale = 1
best_value = -1
for scale in self.scales:
resized = cv2.resize(template, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)
res = cv2.matchTemplate(image, resized, method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if max_val > best_value and max_val > self.threshold:
best_value = max_val
best_loc = max_loc
best_scale = scale
if best_loc is not None:
best_h, best_w = int(template_h * best_scale), int(template_w * best_scale)
top_left = best_loc
bottom_right = (top_left[0] + best_w, top_left[1] + best_h)
return top_left, bottom_right, round(best_value, 3)
else:
return (0, 0), (0, 0), 0
SIFTFeatureMatcher类
1. 功能:
使用SIFT算法进行特征匹配,适合处理旋转和缩放的场景,通过检测关键点和描述符进行匹配。
2. 属性:
sift (cv2.SIFT):
SIFT特征检测器和描述符。
3. 方法:
-
__init__(self):
初始化SIFT检测器。 -
match(self, image, template):
执行特征匹配。-
参数:
-
image (numpy.ndarray):
目标图像。 -
template (numpy.ndarray):
模板图像。
-
-
返回:
-
元组
(start_point, end_point)
,其中:-
start_point:
匹配的左上角坐标(x1, y1)。 -
end_point:
匹配的右下角坐标(x2, y2)。
-
-
若未找到匹配,返回((0, 0), (0, 0))。
-
-
相关代码片段:
class SIFTFeatureMatcher:
def __init__(self):
self.sift = cv2.SIFT_create()
def match(self, image, template):
img1_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
img2_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
kp1, des1 = self.sift.detectAndCompute(img1_gray, None)
kp2, des2 = self.sift.detectAndCompute(img2_gray, None)
matcher = cv2.BFMatcher()
matches = matcher.knnMatch(des1, des2, k=2)
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append(m)
if len(good) > 10:
src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)
h, w = template.shape[:2]
pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
points = list(np.int32(dst).flatten())
y1, x1 = points[0:2]
y2, x2 = points[4:6]
return (x1, y1), (x2, y2)
else:
return (0, 0), (0, 0)
im_match函数
1. 功能:
结合TemplateMatcher和MultiScale的结果,找到最佳匹配。
2. 参数:
-
image (numpy.ndarray):
目标图像。 -
template (numpy.ndarray):
模板图像。 -
threshold (float):
最小置信度阈值(默认0.6)。
返回:
-
元组
(start_point, end_point)
,其中:-
start_point:
匹配的左上角坐标。 -
end_point:
匹配的右下角坐标。
-
-
若未找到匹配,返回((0, 0), (0, 0))。
相关代码片段:
def im_match(image, template, threshold=0.6):
template_matcher = TemplateMatcher().match(image, template)
multi_scale = MultiScale().match(image, template)
print(f"match results >>> template_matcher: {template_matcher}; multi_scale: {multi_scale}")
if template_matcher[2] >= threshold or multi_scale[2] >= threshold:
if template_matcher[2] >= multi_scale[2]:
points = template_matcher[:2]
else:
points = multi_scale[:2]
return points
else:
return (0, 0), (0, 0)
draw_rectangle函数
1. 功能:
在图像上绘制矩形,标记匹配区域,并计算中心点。
2. 参数:
-
image_path (str):
图像文件路径。 -
start_point (tuple):
矩形的左上角坐标(x1, y1)。 -
end_point (tuple):
矩形的右下角坐标(x2, y2)。 -
color (tuple):
矩形颜色(BGR格式,默认绿色(0, 255, 0))。 -
thickness (int):
矩形边框粗细(默认2)。
返回:
-
元组
(image, center_point)
,其中:-
image:
绘制矩形后的图像。 -
center_point:
矩形中心点坐标(center_x, center_y)
。
-
相关代码片段:
def draw_rectangle(image_path, start_point, end_point, color=(0, 255, 0), thickness=2):
image = cv2.imread(image_path)
if image is None:
raise ValueError(f"Unable to load image: {image_path}")
cv2.rectangle(image, start_point, end_point, color, thickness)
center_x = (start_point[0] + end_point[0]) // 2
center_y = (start_point[1] + end_point[1]) // 2
center_point = (center_x, center_y)
return image, center_point
三、思路总结
提示: SIFTFeatureMatcher虽然定义了,但未集成到im_match函数中,SIFT特征匹配方法当前实现尚不成熟,需进一步优化。
通过TemplateMatcher、MultiScale和SIFTFeatureMatcher覆盖不同场景需求。im_match函数结合单尺度和多尺度匹配,确保鲁棒性,draw_rectangle提供可视化反馈。