【计算机视觉算法与应用】模板匹配、图像配准

目录

1. 基于灰度值的模板匹配

2. 基于相关性的模板匹配

3. 基于形状的模板匹配

4. 基于组件的模板识别

5. 基于形变的模板匹配

6. 基于描述符的模板匹配

7. 基于点的模板匹配

性能比较


模板匹配的算法实现需要结合具体需求和应用场景来选择方法。以下是基于 OpenCV 的实现示例,用于实现以下模板匹配方法:

1. 基于灰度值的模板匹配

使用 OpenCV 的 cv2.matchTemplate 方法进行模板匹配。

import cv2
import numpy as np

# 加载图像和模板
image = cv2.imread('image.jpg', 0)
template = cv2.imread('template.jpg', 0)
w, h = template.shape[::-1]

# 匹配方法
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

# 结果
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(image, top_left, bottom_right, 255, 2)
cv2.imshow('Matched Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 基于相关性的模板匹配

相关性匹配也可以基于 cv2.matchTemplate,但使用不同的匹配模式。

result = cv2.matchTemplate(image, template, cv2.TM_CCORR_NORMED)
# 剩余代码与上面类似

3. 基于形状的模板匹配

使用 Canny 边缘检测和轮廓匹配。

# 提取轮廓
edges_image = cv2.Canny(image, 100, 200)
edges_template = cv2.Canny(template, 100, 200)

# 轮廓匹配
contours_image, _ = cv2.findContours(edges_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_template, _ = cv2.findContours(edges_template, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

similarity = cv2.matchShapes(contours_template[0], contours_image[0], cv2.CONTOURS_MATCH_I1, 0.0)
print(f"Shape Similarity: {similarity}")

4. 基于组件的模板识别

使用连通组件(Connected Components)。

# 连通组件
_, labels, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=8)

# 遍历组件
for i in range(1, len(stats)):
    x, y, w, h, area = stats[i]
    if area > 50:  # 根据模板特性过滤
        cv2.rectangle(image, (x, y), (x + w, y + h), 255, 2)

cv2.imshow('Components', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. 基于形变的模板匹配

形变模板匹配需要形变模型,比如 Thin Plate Splines 或其他变换。

from skimage.transform import warp
from skimage import data

# 定义形变模型
def deform(image):
    # 示例:平移或旋转
    return warp(image, lambda xy: (xy[0] + 10, xy[1] + 10))

transformed_template = deform(template)
result = cv2.matchTemplate(image, transformed_template, cv2.TM_CCOEFF_NORMED)

6. 基于描述符的模板匹配

使用 ORB 特征点和描述符。

# ORB 初始化
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(image, None)
kp2, des2 = orb.detectAndCompute(template, None)

# 特征匹配
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)

# 画出匹配结果
result = cv2.drawMatches(image, kp1, template, kp2, matches[:10], None, flags=2)
cv2.imshow('Descriptor Matching', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

7. 基于点的模板匹配

使用特征点检测方法,比如 FAST。

fast = cv2.FastFeatureDetector_create()
kp1 = fast.detect(image, None)
kp2 = fast.detect(template, None)

# 可视化特征点
image_with_kp = cv2.drawKeypoints(image, kp1, None, color=(255, 0, 0))
template_with_kp = cv2.drawKeypoints(template, kp2, None, color=(255, 0, 0))

cv2.imshow('Image Keypoints', image_with_kp)
cv2.imshow('Template Keypoints', template_with_kp)
cv2.waitKey(0)
cv2.destroyAllWindows()

性能比较

可以通过以下指标进行比较:

  1. 匹配时间:统计每种方法的运行时间。
  2. 准确性:计算匹配的正确率(例如 IoU 或精确定位的得分)。
  3. 鲁棒性:在旋转、缩放和噪声下的表现。

如需详细的性能比较,可以写一段代码封装测试和比较逻辑。需要时我可以帮助扩展测试脚本!

个人经验:

1. 工业场景几何关系明确,可以用 基于图像(相关性的就够了),测试显示,对

2. 形变,投影变换,可以考虑用特征点提取(ORB, SIFT)提取描述子, 配合匹配关系描述子配对关系计算获得。 c++ 中设计找最近点等优化算法,ranscac 去除异常点等手段。

3. 工业场景中,多用基于shape model 的查找。更稳定,速度更快(tamplate 小, 几十毫秒)

欢迎订阅本专辑,关注博主,持续更新 ~!code实战内容和经验!代码和理论即学即用!

#模板匹配 import cv2 as cv import numpy as np def template_demo(): dog = cv.imread("E:/opencv/picture/dog.jpg") dog_nose = cv.imread("E:/opencv/picture/nose.jpg") cv.imshow("dog",dog) result = cv.matchTemplate(dog,dog_nose,cv.TM_CCORR_NORMED) h,w =dog_nose.shape[:2] min_val,max_val,min_loc,max_loc=cv.minMaxLoc(result) pt1 = max_loc pt2 = (pt1[0]+w,pt1[1]+h) cv.rectangle(dog,pt1,pt2,(0,255,0),2) cv.imshow("match",dog) print(result) #src = cv.imread("E:/opencv/picture/dog.jpg") #cv.imshow("inital_window",src) template_demo() cv.waitKey(0) cv.destroyAllWindows() 分析: 模板匹配通常用于目标检测。本文我们检测狗图片的鼻子。 • 我们需要两个主要组件: 1. 源图像(I):我们期望找到模板图像图像 2. 模板图像(T):将模板图像进行比较的补丁图像 1. result = cv.matchTemplate(dog,dog_nose,cv.TM_CCORR_NORMED) void cv::matchTemplate( cv::InputArray image, // 待匹图像W*H cv::InputArray templ, // 模板图像,和image类型相同, 大小 w*h cv::OutputArray result, // 匹结果图像, 类型 32F, 大小 (W-w+1)*(H-h+1) int method // 用于比较的方法 ); 其中method有: TM_SQDIFF_NORMED匹数值越低表示匹效果越好 TM_CCORR_NORMED,TM_CCOEFF_NORMED匹数值越大表示匹效果越好 result参数:(保存各个点匹结果的参数) 模板匹配函数cvMatchTemplate依次计算模板待测图片的重叠区域的相似度,并将结果存入映射图像result当中,也就是说result图像中的每一个点的值代表了一次相似度比较结果 模板在待测图像上每次在横向或是纵向上移动一个像素,并作一次比较计算 我们可以通过cv.minMaxLoc函数来确定结果矩阵的最大值和最小值的位置。 2. cv.minMaxLoc(result) 返回result数值中最小值以及最小值所在的位置和最大值以及最大值所在的位置。 3. 当知道哪个点匹度最高时这个时候我们需要用矩阵把模板给标出来 C++: void rectangle(Mat& img, Point pt1,Point pt2,const Scalar& color, int thickness=1, int lineType=8, int shift=0) 第一个参数:要在哪个图像上画? 第二个参数:矩阵的左上角点坐标 第三个参数:矩阵的右下角点坐标 第四个参数:颜色
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值