c++视觉处理----图像模板匹配

模板匹配matchTemplate()

matchTemplate() 是OpenCV中用于模板匹配的函数之一。它的主要作用是在一幅图像中搜索模板图像的位置,即找到模板在图像中的匹配位置。

函数原型如下:

void cv::matchTemplate(
    InputArray image,
    InputArray templ,
    OutputArray result,
    int method
);

其中:

  • image 是源图像,你要在这幅图像中搜索模板。
  • templ 是模板图像,你要搜索的目标。
  • result 是输出参数,用于存储匹配结果。
  • method 是匹配方法,指定匹配时要使用的算法,可以是以下之一:
    • TM_SQDIFF: 平方差匹配,最匹配的位置是结果最小的位置。
    • TM_SQDIFF_NORMED: 标准化平方差匹配,最匹配的位置是结果最小的位置。
    • TM_CCORR: 相关性匹配,最匹配的位置是结果最大的位置。
    • TM_CCORR_NORMED: 标准化相关性匹配,最匹配的位置是结果最大的位置。
    • TM_CCOEFF: 系数匹配,最匹配的位置是结果最大的位置。
    • TM_CCOEFF_NORMED: 标准化系数匹配,最匹配的位置是结果最大的位置。

使用 matchTemplate() 后,result 图像中会包含匹配结果。你可以通过在 result 图像中找到最小(TM_SQDIFFTM_SQDIFF_NORMED)或最大(其他方法)的值的位置来定位匹配的区域。

这个函数对于目标检测、物体跟踪和模式识别等应用非常有用。

图像模板匹配

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

// 定义窗口标题
#define WINDOW_NAME1 "Original Image"
#define WINDOW_NAME2 "Matching Result"

// 全局变量
Mat g_srcImage;
Mat g_templateImage;
Mat g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;

// 回调函数声明
void onMatching(int, void*);

int main()
{
	// 载入原始图像和模板图像
	g_srcImage = imread("1.jpg");
	g_templateImage = imread("1112.jpg");

	// 创建窗口
	namedWindow(WINDOW_NAME1, CV_WINDOW_AUTOSIZE);
	namedWindow(WINDOW_NAME2, CV_WINDOW_AUTOSIZE);

	// 创建滑动条并进行一次初始化
	createTrackbar("Method", WINDOW_NAME1, &g_nMatchMethod, g_nMaxTrackbarNum, onMatching);
	onMatching(0, 0);

	waitKey(0);

	return 0;
}

void onMatching(int, void*)
{
	// 给局部变量初始化
	Mat srcImage;
	g_srcImage.copyTo(srcImage);

	// 初始化结果输出矩阵
	int resultImageCols = g_srcImage.cols - g_templateImage.cols + 1;
	int resultImageRows = g_srcImage.rows - g_templateImage.rows + 1;
	g_resultImage.create(resultImageRows, resultImageCols, CV_32FC1);

	// 执行模板匹配
	matchTemplate(g_srcImage, g_templateImage, g_resultImage, g_nMatchMethod);
	normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());

	// 定位最佳匹配位置
	double minValue, maxValue;
	Point minLocation, maxLocation, matchLocation;

	minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());

	// 根据不同的匹配方法,计算匹配位置
	if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == TM_SQDIFF_NORMED)
	{
		matchLocation = minLocation;
	}
	else
	{
		matchLocation = maxLocation;
	}

	// 在原始图像上绘制匹配位置的矩形
	rectangle(srcImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);

	// 在结果图像上绘制匹配位置的矩形
	rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);

	// 显示图像
	imshow(WINDOW_NAME1, srcImage);
	imshow(WINDOW_NAME2, g_resultImage);
}

c++视觉处理----图像模板匹配_第1张图片

调用本地相机进行模版匹配

#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main()
{
	VideoCapture cap(0); // 打开默认相机,0代表第一个摄像头
	if (!cap.isOpened())
	{
		std::cout << "Could not open the camera!" << std::endl;
		return -1;
	}

	Mat templateImage = imread("122.jpg", IMREAD_COLOR); // 读取要匹配的模板图像
	if (templateImage.empty())
	{
		std::cout << "Could not open or find the template image!" << std::endl;
		return -1;
	}

	int templateWidth = templateImage.cols;
	int templateHeight = templateImage.rows;

	while (true)
	{
		Mat frame;
		cap >> frame; // 从摄像头捕获一帧

		Mat result;
		matchTemplate(frame, templateImage, result, TM_CCOEFF_NORMED);

		double minVal, maxVal;
		Point minLoc, maxLoc;
		minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

		Point matchLoc = maxLoc;

		rectangle(frame, matchLoc, Point(matchLoc.x + templateWidth, matchLoc.y + templateHeight), Scalar(0, 0, 255), 2);

		imshow("Camera", frame);

		char key = waitKey(30);
		if (key == 27) // 按ESC键退出
			break;
	}

	cap.release();
	destroyAllWindows();

	return 0;
}

你可能感兴趣的:(#,C++视觉处理,c++,目标跟踪,开发语言)