代码示例
在你运行此代码前,请确保你已经安装并配置好了 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
程序会弹出两个窗口,一个显示模板图像,另一个显示源图像,并在源图像上用一个绿色矩形标出了最佳匹配位置。
代码讲解 📝
- 加载图像 (
cv::imread
): 读取源图像和模板图像。确保路径正确。 - 创建结果矩阵 (
cv::Mat
) :matchTemplate
函数的输出是一个浮点型的矩阵,其中每个像素值代表了在该点模板与源图像的匹配程度。 - 模板匹配 (
cv::matchTemplate
) : 这是核心函数。它将模板图像在源图像上滑动,并在每个位置计算一个相似度得分。cv::TM_CCOEFF_NORMED
是众多匹配算法中的一种。它计算的是归一化相关系数,结果范围在 -1.0 到 1.0 之间,1.0 代表完美匹配。其他常用的方法还有TM_SQDIFF_NORMED
(值越小越好) 等。
- 定位最佳匹配 (
cv::minMaxLoc
) : 在结果矩阵中找到最大值 (最匹配) 和最小值 (最不匹配) 的位置。对于TM_CCOEFF_NORMED
方法,我们关心的是最大值的位置maxLoc
。 - 绘制矩形 (
cv::rectangle
) : 使用maxLoc
作为左上角顶点,结合模板的尺寸,在源图像上画出矩形框,以可视化匹配结果。 - 显示图像 (
cv::imshow
) : 展示最终的结果。cv::waitKey(0)
会让程序暂停,直到用户按下任意键。