使用 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) 会让程序暂停,直到用户按下任意键。
相关推荐
mount_myj4 小时前
长长久久【C语言】
c语言
c++之路6 小时前
C++信号处理
开发语言·c++·信号处理
Legendary_0087 小时前
LDR6500:USB‑C DRP PD协议芯片技术详解与应用实践
c语言·开发语言
故事还在继续吗8 小时前
C++20关键特性
开发语言·c++·c++20
青少儿编程课堂9 小时前
2026青少儿信息素养大赛备赛指南!Python/Scratch/C++备考要点
开发语言·c++·python
旖-旎9 小时前
深搜练习(电话号码字母组合)(3)
c++·算法·力扣·深度优先遍历
AIFarmer9 小时前
【无标题】
开发语言·c++·算法
John_ToDebug9 小时前
WebHostView 与 TabStrip 交互机制深度解析
c++·chrome·windows
_李小白10 小时前
【android opencv学习笔记】Day 8: remap(像素位置重映射)
android·opencv·学习
南境十里·墨染春水10 小时前
C++笔记 STL——set
开发语言·c++·笔记