使用 C/C++ 和 OpenCV 进行模板匹配

代码示例

在你运行此代码前,请确保你已经安装并配置好了 OpenCV 库。

cpp 复制代码
#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
    // 1. 加载源图像和模板图像
    // 将 "source_image.jpg" 替换为你的源图像路径
    // 将 "template_image.jpg" 替换为你的模板图像路径
    cv::Mat srcImage = cv::imread("source_image.jpg", cv::IMREAD_COLOR);
    cv::Mat templateImage = cv::imread("template_image.jpg", cv::IMREAD_COLOR);

    // 检查图像是否成功加载
    if (srcImage.empty() || templateImage.empty()) {
        std::cerr << "错误: 无法加载图像!" << std::endl;
        return -1;
    }

    // 2. 创建用于存放结果的矩阵
    // 结果矩阵的尺寸: (W - w + 1, H - h + 1)
    // W, H 是源图像的宽高; w, h 是模板图像的宽高
    int result_cols = srcImage.cols - templateImage.cols + 1;
    int result_rows = srcImage.rows - templateImage.rows + 1;
    cv::Mat resultImage;
    resultImage.create(result_rows, result_cols, CV_32FC1);

    // 3. 执行模板匹配
    // TM_CCOEFF_NORMED 是一种常用的匹配算法,它返回归一化的相关系数
    // 结果越接近 1,表示匹配度越高
    cv::matchTemplate(srcImage, templateImage, resultImage, cv::TM_CCOEFF_NORMED);

    // 4. 找到最佳匹配位置
    double minVal, maxVal;
    cv::Point minLoc, maxLoc;
    cv::Point matchLoc;

    cv::minMaxLoc(resultImage, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());

    // 对于 TM_CCOEFF_NORMED 方法,最佳匹配点是最大值所在的位置
    matchLoc = maxLoc;

    // 5. 在源图像上绘制矩形框来标记匹配区域
    cv::rectangle(srcImage, matchLoc,
                  cv::Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows),
                  cv::Scalar(0, 255, 0), 2, 8, 0);

    // 6. 显示结果
    cv::imshow("匹配结果", srcImage);
    cv::imshow("模板图像", templateImage);

    // 等待用户按键后退出
    cv::waitKey(0);

    return 0;
}

如何编译和运行

你需要准备两张图片:

  • source_image.jpg: 你要在其中进行搜索的大图。
  • template_image.jpg: 你要搜索的小图(模板)。

将这两张图片与你的 C++ 文件放在同一个目录下。

编译命令 (以 g++ 为例):

假设你的 C++ 文件名为 match.cpp。你需要链接 OpenCV 库来编译它。请根据你自己的 OpenCV 安装路径来修改命令。

bash 复制代码
g++ match.cpp -o match `pkg-config --cflags --libs opencv4`

如果你没有使用 pkg-config,你需要手动指定头文件和库文件的路径:

bash 复制代码
g++ match.cpp -o match -I/path/to/opencv/include -L/path/to/opencv/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs

运行:

bash 复制代码
./match

程序会弹出两个窗口,一个显示模板图像,另一个显示源图像,并在源图像上用一个绿色矩形标出了最佳匹配位置。


代码讲解 📝

  1. 加载图像 (cv::imread): 读取源图像和模板图像。确保路径正确。
  2. 创建结果矩阵 (cv::Mat) : matchTemplate 函数的输出是一个浮点型的矩阵,其中每个像素值代表了在该点模板与源图像的匹配程度。
  3. 模板匹配 (cv::matchTemplate) : 这是核心函数。它将模板图像在源图像上滑动,并在每个位置计算一个相似度得分。
    • cv::TM_CCOEFF_NORMED 是众多匹配算法中的一种。它计算的是归一化相关系数,结果范围在 -1.0 到 1.0 之间,1.0 代表完美匹配。其他常用的方法还有 TM_SQDIFF_NORMED (值越小越好) 等。
  4. 定位最佳匹配 (cv::minMaxLoc) : 在结果矩阵中找到最大值 (最匹配) 和最小值 (最不匹配) 的位置。对于 TM_CCOEFF_NORMED 方法,我们关心的是最大值的位置 maxLoc
  5. 绘制矩形 (cv::rectangle) : 使用 maxLoc 作为左上角顶点,结合模板的尺寸,在源图像上画出矩形框,以可视化匹配结果。
  6. 显示图像 (cv::imshow) : 展示最终的结果。cv::waitKey(0) 会让程序暂停,直到用户按下任意键。
相关推荐
快乐的划水a13 分钟前
组合模式及优化
c++·设计模式·组合模式
星星火柴9361 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑2 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
Cx330❀4 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
阿巴~阿巴~4 小时前
深入解析C++ STL链表(List)模拟实现
开发语言·c++·链表·stl·list
..过云雨5 小时前
01.【数据结构-C语言】数据结构概念&算法效率(时间复杂度和空间复杂度)
c语言·数据结构·笔记·学习
旺小仔.5 小时前
双指针和codetop复习
数据结构·c++·算法
jingfeng5146 小时前
C++ STL-string类底层实现
前端·c++·算法
郝学胜-神的一滴6 小时前
基于C++的词法分析器:使用正则表达式的实现
开发语言·c++·程序人生·正则表达式·stl
谱写秋天6 小时前
在STM32F103上进行FreeRTOS移植和配置(STM32CubeIDE)
c语言·stm32·单片机·freertos