使用 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) 会让程序暂停,直到用户按下任意键。
相关推荐
蒙奇D索大8 小时前
【算法】递归算法实战:汉诺塔问题详解与代码实现
c语言·考研·算法·面试·改行学it
No0d1es9 小时前
2025年 CSP-J1 入门级初赛 C++真题
开发语言·c++·青少年编程·csp·信息学奥赛·初赛
橙子也要努力变强9 小时前
C++中的多态
c++
ysa0510309 小时前
虚拟位置映射(标签鸽
数据结构·c++·笔记·算法
Yue丶越9 小时前
【C语言】深入理解指针(二)
c语言·开发语言·数据结构·算法·排序算法
m0_748248029 小时前
C++中的位运算符:与、或、异或详解
java·c++·算法
草莓熊Lotso11 小时前
C++ 方向 Web 自动化测试实战:以博客系统为例,从用例到报告全流程解析
前端·网络·c++·人工智能·后端·python·功能测试
共享家952711 小时前
LRU 缓存的设计与实现
开发语言·c++
奔跑吧邓邓子11 小时前
【C语言实战(77)】STM32实战:解锁传感器数据采集的C语言奥秘
c语言·stm32·开发实战·传感器数据采集
小刘爱玩单片机11 小时前
【stm32简单外设篇】- 土壤湿度传感器
c语言·stm32·单片机·嵌入式硬件