匹配函数
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