opencv之模板匹配(初)

这篇博客介绍了OpenCV中的模板匹配技术,主要讲解了如何进行图像匹配,并探讨了在图片上的应用效果。虽然在图片匹配上表现良好,但在应用于视频时并未达到预期效果。文中引用了两篇相关资源供进一步学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

匹配函数

matchTemplate(InputArray image, InputArray temp, OutputArray result, int method)
第一个参数为输入源图像,第二个参数为输入模板图像,第三个参数为匹配结果,记录在源图像上滑动窗口和
模板的相似程度,第四个参数为匹配方法。
匹配方法:
CV_TM_SQDIEF平方差匹配法,最好匹配为0,值越大匹配越差
CV_TM_SQDIEF_NORMED归一化平方差匹配法
CV_TM_CCORR相关匹配法,采用乘法操作,数值越大表明匹配越好
CV_TM_CCORR_NORMED归一化相关匹配法
CV_TM_CCOEFF相关系数匹配法,最好匹配为1,最差为-1
CV_TM_CCOEFF_NORMED归一化相关系数匹配法


2.对图片的识别

// hough_fitline.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>    
#include<iostream>
#include<time.h>
using namespace cv;  
using namespace std;  

void Match_1(Mat&src_Img,Mat&templ,Mat&result)
{
	matchTemplate(src_Img,templ,result,CV_TM_SQDIFF);
	double minVal, maxVal;
	Point minLoc, maxLoc;
	minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
	rectangle(src_Img, Rect(minLoc, Size(templ.cols, templ.rows) ), Scalar(0, 0, 255), 2, 8, 0 );
	imshow("result",src_Img);
}
void Match_2(Mat&src_Img,Mat&templ,Mat&result)
{
	matchTemplate(src_Img,templ,result,CV_TM_SQDIFF);
	double minVal, maxVal;
	Point minLoc, maxLoc;
	minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
	rectangle(src_Img, Rect(minLoc, Size(templ.cols, templ.rows) ), Scalar(0, 255,0), 2, 8, 0 );
	imshow("result",src_Img);
}
int main()
{
	Mat result_1,result_2;
	Mat img=imread("D://vvoo//huoyinga.jpg");
	Mat templ=imread("D://vvoo//mingren.jpg");
	Mat temp2=imread("D://vvoo//sidai.jpg");
	int result_cols = img.cols - templ.cols + 1;
	int result_rows = img.rows - templ.rows + 1;
	result_1.create(result_cols, result_rows, CV_32FC1);

	int result2_cols = img.cols - temp2.cols + 1;
	int result2_rows = img.rows - temp2.rows + 1;
	result_2.create(result2_cols, result2_rows, CV_32FC1);
	
	int key;
	cout<<"inout key:";
	cin>>key;
	switch(key)
	{
	case 1:
		Match_1(img,templ,result_1);break;
	case 2:
		Match_2(img,temp2,result_2);break;
	case 3:
		Match_1(img,templ,result_1);
		Match_2(img,temp2,result_2);break;
	default:cout<<"error"<<endl;
	}
	imwrite("D://vvoo3//123.jpg",img);	
	waitKey(0);
	return 0;

}


                                              


3.视频效果

#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

Rect select;
bool select_flag = false;
Mat img, showImg,roiImg,dst_image,result;

void A_on_Mouse(int event, int x, int y, int flags, void*param)//实现画矩形框
{
	Point p1, p2;
	if (event == EVENT_LBUTTONDOWN)
	{
		select.x = x;
		select.y = y;
		select_flag = true;
	}
	else if (select_flag &&event == EVENT_MOUSEMOVE)
	{
		img.copyTo(showImg);
		p1 = Point(select.x, select.y);
		p2 = Point(x, y);
		rectangle(showImg, p1, p2, Scalar(0, 255, 0), 2);
		imshow("img", showImg);
	}
	else if (select_flag && event == EVENT_LBUTTONUP)
	{
		select_flag = false;
	}
}
void B_on_Mouse(int event, int x, int y, int flags, void*param)//实现画矩形框并截图
{

	Point p1, p2;
	switch (event)
	{

	case  EVENT_LBUTTONDOWN:
	{
								  select.x = x;
								  select.y = y;
								  select_flag = true;
	}
		break;
	case EVENT_MOUSEMOVE:
	{
							   if (select_flag)
							   {
					
							   img.copyTo(showImg);
							   p1 = Point(select.x, select.y);
							   p2 = Point(x, y);
							   rectangle(showImg, p1, p2, Scalar(0, 255, 0), 2);
							   imshow("img", showImg);
							   }					  
	} 
		break;
	case EVENT_LBUTTONUP:
	{
							   //显示框出的ROI
                                                           //改成Rect roi = Rect(p1, p2);为什么不对?
							   Rect roi = Rect(Point(select.x, select.y), Point(x, y));
							   if (roi.width && roi.height)//点一下时会没有反应
							   {
								   roiImg = img(roi);
								   imshow("roi", roiImg);
								   
							   }
							   select_flag = false;
							   
	}
		break;
	}
}

int main()
{   //Mat dst_image;
	bool stop = false; 
	 VideoCapture capture("D:\\vvoo1\\road.avi");  
  
    if (!capture.isOpened())  
    {  
        cout << "读取视频失败!" << endl;  
        return -1;  
    }  
	capture>>img;
	showImg = img.clone();
	select.x = select.y = 0;
	imshow("img", showImg);

	
	while (1)
	{
		int key = waitKey(10);
switch (key)
	{
	case 'a':
				setMouseCallback("img", A_on_Mouse, 0);
		break;
	case 'b':
				setMouseCallback("img", B_on_Mouse, 0);
		break;
	}
    
if (key == 27||key=='q')
break;
	}
	cvtColor(roiImg,roiImg,CV_RGB2GRAY);
			imshow("roiImg",roiImg);
			
	 while (!stop)  
    {  
        capture >> dst_image;  
    cvtColor(dst_image,dst_image,CV_RGB2GRAY);
	int result_cols = dst_image.cols - roiImg.cols + 1;
	int result_rows = dst_image.rows - roiImg.rows + 1;
	result.create(result_cols, result_rows, CV_32FC1);
	
	matchTemplate(dst_image, roiImg, result, CV_TM_SQDIFF);//CV_TM_SQDIFF_NORMED CV_TM_SQDIFF
	//normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	double minVal;
	double maxVal;
	Point minLoc;
	Point maxLoc;
	Point matchLoc;

	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
	matchLoc = minLoc;
	rectangle(dst_image, matchLoc, Point(matchLoc.x + roiImg.cols, matchLoc.y +roiImg.rows),
 Scalar(0,255,0), 2, 8, 0);


        imshow("当前视频", dst_image);  
		
            if (waitKey(30) >= 0)  
                stop = true;  
    }  
			
	//waitKey(0);
	return 0;
}

对图片匹配还可以,但视频结果并卵。

1.http://lib.youkuaiyun.com/article/opencv/26772

2.http://blog.youkuaiyun.com/liyuanbhu/article/details/49837661

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值