使用 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) 会让程序暂停,直到用户按下任意键。
相关推荐
端平入洛16 小时前
delete又未完全delete
c++
祈安_21 小时前
C语言内存函数
c语言·后端
端平入洛2 天前
auto有时不auto
c++
norlan_jame3 天前
C-PHY与D-PHY差异
c语言·开发语言
哇哈哈20213 天前
信号量和信号
linux·c++
多恩Stone3 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
czy87874753 天前
除了结构体之外,C语言中还有哪些其他方式可以模拟C++的面向对象编程特性
c语言
蜡笔小马3 天前
21.Boost.Geometry disjoint、distance、envelope、equals、expand和for_each算法接口详解
c++·算法·boost
m0_531237173 天前
C语言-数组练习进阶
c语言·开发语言·算法
超级大福宝3 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode