1.问题或需求描述
opencv 基于形状的模板匹配测试
2.解决方法或原理:
主要步骤:
- 使用opencv查找轮廓(findContours)
- 匹配轮廓(形状)(matchShapes)的相似度
python代码:
import cv2
# 读取目标图像
target_image = cv2.imread('target.png', cv2.IMREAD_COLOR)
# 读取模板图像
template_image = cv2.imread('template.png', cv2.IMREAD_COLOR)
# 转换为灰度图像
gray_target_image = cv2.cvtColor(target_image, cv2.COLOR_BGR2GRAY)
gray_template_image = cv2.cvtColor(template_image, cv2.COLOR_BGR2GRAY)
# 扩展通道数以绘制色彩
view = cv2.merge((gray_target_image, ) * 3)
# 二值化
_, gray_target_image = cv2.threshold(gray_target_image, 50, 255, cv2.THRESH_BINARY)
_, gray_template_image = cv2.threshold(gray_template_image, 50, 255, cv2.THRESH_BINARY)
# 显示图像
cv2.imshow('template', gray_template_image)
cv2.imshow('match', view)
# 提取图像轮廓
target_contours, target_hierarchy = cv2.findContours(gray_target_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
template_contours, template_hierarchy = cv2.findContours(gray_template_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# 调试输出
print('target_contours num:',len(target_contours))
print('template_contours num:',len(template_contours))
# 存储各个形状匹配值
values = []
for v in range(len(target_contours)):
# 计算形状匹配值
match_value = cv2.matchShapes(target_contours[v], template_contours[0], cv2.CONTOURS_MATCH_I1, 0.0)
print(f"形状匹配值: {match_value}")
values.append(match_value)
# 绘制当前匹配轮廓
view_copy = view.copy()
cv2.drawContours(view_copy, [target_contours[v]], -1, (0, 255, 0), thickness=cv2.FILLED)
cv2.putText(view_copy, f"match value: {match_value}", (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
cv2.imshow('match', view_copy)
cv2.waitKey(500)
# 显示匹配结果
idx = values.index(min(values))
cv2.drawContours(view, [target_contours[idx]], -1, (0, 255, 0), thickness=cv2.FILLED)
cv2.putText(view, f"match value: {values[idx]}", (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
cv2.imshow('match', view)
cv2.waitKey(0)
cv2.destroyAllWindows()