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


    模板匹配matchTemplate()

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

    函数原型如下:

    void cv::matchTemplate(
        InputArray image,
        InputArray templ,
        OutputArray result,
        int method
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中:

    • 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    在这里插入图片描述

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

    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
  • 相关阅读:
    vue课程79 介绍并安装vue-cli
    Kubernetes - Ingress暴露应用(四)
    【疯狂Java】数组
    Hive 分区表
    2022年最新前端面试题
    es笔记一之es安装与介绍
    京东产品上架如何批量上传商品素材?
    Redis哨兵
    HK32F030MF4P6 3路ADC采集
    Windows Server服务器下的Linux子系统
  • 原文地址:https://blog.csdn.net/qq_46107892/article/details/133793305