正常模板匹配函数
cpp
matchTemplate(img, templatee, resultMat, 0);//模板匹配
这里0代表的是方法,一般默认为0就ok
img是输入图像 templatee是模板 resultmat是输出
cpp
1、cv::TM_SQDIFF:该方法使用平方差进行匹配,因此最佳的匹配结果在结果为0处,值越大匹配结果越差。
2、cv::TM_SQDIFF_NORMED:该方法使用归一化的平方差进行匹配,最佳匹配也在结果为0处。
3、cv::TM_CCORR:相关性匹配方法,该方法使用源图像与模板图像的卷积结果进行匹配,因此,最佳匹配位置在值最大处,值越小匹配结果越差。
4、cv::TM_CCORR_NORMED:归一化的相关性匹配方法,与相关性匹配方法类似,最佳匹配位置也是在值最大处。
5、cv::TM_CCOEFF:相关性系数匹配方法,该方法使用源图像与其均值的差、模板与其均值的差二者之间的相关性进行匹配,最佳匹配结果在值等于1处,最差匹配结果在值等于-1处,值等于0直接表示二者不相关。
6、cv::TM_CCOEFF_NORMED:归一化的相关性系数匹配方法,正值表示匹配的结果较好,负值则表示匹配的效果较差,也是值越大,匹配效果也好。
对于输出的说明:
就是说result图像中的每一个点的值代表了一次相似度比较结果。
如图可知,模板在待测图像上每次在横向或是纵向上移动一个像素,并作一次比较计算,由此,横向比较W-w+1次,纵向比较H-h+1次,从而得到一个(W-w+1)×(H-h+1)维的结果矩阵,result即是用图像来表示这样的矩阵,因而图像result的大小为(W-w+1)×(H-h+1)。匹配结果图像与原图像之间的大小关系,他们之间差了一个模板大小。
对输出值的归一化
cpp
normalize(resultMat, resultMat, 0, 1, NORM_MINMAX, -1, Mat());//归一化
找出最佳匹配的位置:
cpp
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc(resultMat, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
matchLoc = minLoc;
我们这里选择了最小值的位置,因为我们选的第一种方法也就是值越小越好,其他方法有可能是选最大的位置!!
在图像画出匹配最佳:
cpp
Mat dispmat;
img.copyTo(dispmat);
rectangle(dispmat, matchLoc, Point(matchLoc.x + templatee.cols, matchLoc.y + templatee.rows),CV_RGB(0,255,0), 2, 8, 0);
imshow("dispmat", dispmat);
waitKey(0);
destroyAllWindows();
结果显示
利用opencv自带选取roi+模板匹配,进行简单的人脸追踪识别
选取roi
cpp
if (cnt == 0) {
Rect2d r;
r = selectROI(frame, true);
tempMat = frame(r);
tempMat.copyTo(refMat);
destroyAllWindows();
}
完整代码:
cpp
VideoCapture cap(0);
Mat frame;
Mat tempMat;
Mat refMat;
Mat dispMat;
Mat resultMat;
int cnt = 0;
while (1) {
cap >> frame;
if (cnt == 0) {
Rect2d r;
r = selectROI(frame, true);
tempMat = frame(r);
tempMat.copyTo(refMat);
destroyAllWindows();
}
imshow("template", refMat);
int match_method = 0;
matchTemplate(frame, refMat, resultMat, match_method);
normalize(resultMat, resultMat, 0, 1, NORM_MINMAX, -1, Mat());
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc(resultMat, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED)
{
matchLoc = minLoc;
}
else
{
matchLoc = maxLoc;
}
frame.copyTo(dispMat);
rectangle(dispMat, matchLoc, Point(matchLoc.x + refMat.cols, matchLoc.y + refMat.rows), Scalar::all(0), 2, 8, 0);
cnt++;
//imshow("template", refMat);
imshow("dispMat", dispMat);
waitKey(30);
至此opencv基础学习到此结束 后期学习一些进阶自学内容。
************************************************----***********************************************************