模板匹配(目标跟踪)

一、算法简介

        OpenCV的模板匹配算法是一种在大图中寻找模板图像位置的方法。它主要通过滑动模板图像在大图中进行匹配,计算模板图像与大图中每一个小区域的匹配度,以此来确定模板在大图中的位置。这种方法简单、直观,适用于寻找不变形的目标。

工作原理:算法将模板图像在目标图像上滑动,并在每一个位置计算模板图像和覆盖它的目标图像区域之间的相似度。通过比较这些相似度,可以确定模板图像在目标图像中最匹配的位置。

应用场景:模板匹配在许多图像处理和计算机视觉任务中非常有用,特别是当目标图像中的对象大小和角度保持不变时。例如,在文档扫描、对象识别、视频监控等场景下有广泛的应用。

局限性:尽管模板匹配在某些场景下非常有效,但它也有一些局限性。主要是当目标图像中的对象出现旋转、缩放或者视角变化时,模板匹配的效果会大打折扣。此外,当背景复杂或光照条件变化大时,匹配效果也会受到影响。

二、实现步骤

  • 加载目标图像和模板图像。
  • 选择合适的模板匹配方法。
  • 使用cv2.matchTemplate()函数进行模板匹配。
  • 使用cv2.minMaxLoc()函数找到匹配结果中的最小值或最大值点,这些点表示模板图像在目标图像上的位置。
  • 根据模板大小在目标图像上绘制矩形框,标示出匹配区域。

三、代码实现(C++)

参数

  • image: 输入图像,类型为cv::Mat。这是要在其中查找模板图像的目标图像。
  • temp: 模板图像,类型为cv::Mat。这是需要在目标图像中被识别和追踪的图像。
  • roi: 感兴趣区域,类型为cv::Rect&。表示当前图像中预期找到模板图像的区域。该区域基于先前的匹配结果进行更新。
  • scaleFactor: 放大倍数,类型为float。用于在每次追踪之前放大ROI区域,以增加匹配的灵活性和范围。
  • confidence: 置信度阈值,类型为float。仅当匹配的置信度高于此阈值时,才会更新ROI区域。这个参数用于控制匹配质量的标准。

返回值

  • true: 如果找到了一个匹配度高于置信度阈值的区域,函数将更新ROI到这个新的位置,并返回true
  • false: 如果匹配度低于置信度阈值,函数不会更新ROI,并返回false

关于matchTemplate函数的method参数说明:

1. TM_SQDIFF:平方差匹配
  • 计算方式:计算模板与图像之间的平方差,最小值表示最佳匹配。
  • 适用场景:当目标与背景对比度较高,且目标颜色较为统一时。因为平方差能够强调像素值的细微差别,适用于寻找颜色差异明显的目标。
2. TM_SQDIFF_NORMED:归一化平方差匹配
  • 计算方式:与TM_SQDIFF相似,但结果会被归一化到[0,1]区间,最小值表示最佳匹配。
  • 适用场景:与TM_SQDIFF类似,但当模板或图像在不同的光照条件下或不同的尺度时,归一化能提供更稳定的匹配效果。
3. TM_CCORR:相关性匹配
  • 计算方式:计算模板与图像之间的乘积和,最大值表示最佳匹配。
  • 适用场景:适用于目标和背景的颜色分布较为接近,或者颜色变化不是很大的情况。这种方法对亮度变化较为敏感,因此在亮度较为一致的场景中效果较好。
4. TM_CCORR_NORMED:归一化相关性匹配
  • 计算方式:与TM_CCORR相似,但通过归一化处理使结果落在[0,1]区间,最大值表示最佳匹配。
  • 适用场景:当图像中的光照条件可能变化,或者目标与背景的亮度差异不大时,归一化可以提供更一致的匹配效果。
5. TM_CCOEFF:相关系数匹配
  • 计算方式:计算模板与图像之间的相关系数,考虑了图像的平均亮度,最大值表示最佳匹配。
  • 适用场景:当目标与背景的亮度有较大差异,或者背景亮度不均匀时。这种方法能够较好地排除亮度的影响,专注于结构的匹配。
6. TM_CCOEFF_NORMED:归一化相关系数匹配
  • 计算方式:与TM_CCOEFF相似,但结果经过归一化处理,最大值表示最佳匹配。
  • 适用场景:适合于图像中目标与背景亮度差异显著,同时图像可能存在不同的光照条件或尺度变化。归一化处理使得匹配结果对这些变化更加鲁棒。
总结
  • 平方差方法(TM_SQDIFF和TM_SQDIFF_NORMED):适合于颜色差异明显的目标检测。
  • 相关性方法(TM_CCORR和TM_CCORR_NORMED):适合于亮度一致的场景,尤其是当目标与背景颜色接近时。
  • 相关系数方法(TM_CCOEFF和TM_CCOEFF_NORMED):适合于背景复杂或目标与背景亮度有显著差异的场景,能较好地排除
bool trackTemplate(const cv::Mat& image, const cv::Mat& temp, cv::Rect& roi, float scaleFactor, float confidence) 
{
    // 计算新的ROI尺寸
    cv::Rect expandedROI = roi;
    expandedROI.x -= roi.width * (scaleFactor - 1) / 2; // 计算放大后ROI的新x坐标
    expandedROI.y -= roi.height * (scaleFactor - 1) / 2; // 计算放大后ROI的新y坐标
    expandedROI.width *= scaleFactor; // 更新ROI宽度
    expandedROI.height *= scaleFactor; // 更新ROI高度

    // 将ROI限制在图像范围内
    expandedROI = expandedROI & cv::Rect(0, 0, image.cols, image.rows);
    // 从图像中裁剪扩展后的ROI
    cv::Mat roiImage = image(expandedROI).clone();
    // 模板匹配
    cv::Mat result;
    matchTemplate(roiImage, temp, result, TM_CCORR_NORMED); // 使用归一化的相关性匹配方法
    // 找到最佳匹配位置
    float minVal, maxVal;
    cv::Point minLoc, maxLoc;
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); // 查找最大和最小值及其位置


    // 检查最佳匹配是否足够好
    if (maxVal > confidence) 
    {
        // 更新ROI到新的位置
        roi.x = expandedROI.x + maxLoc.x;
        roi.y = expandedROI.y + maxLoc.y;
        roi.width = temp.cols; // 设置ROI宽度为模板的宽度
        roi.height = temp.rows; // 设置ROI高度为模板的高度
        roi= roi& cv::Rect(0, 0, image.cols, image.rows);
        return true;
    } 
    else 
        return false;
}

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值