opencv学习之路(21)、模板匹配及应用
一、模板匹配概念
二、单模板匹配
1 #include "opencv2/opencv.hpp" 2 #include <iostream> 3 using namespace std; 4 using namespace cv; 5 6 void main() 7 { 8 Mat temp=imread("E://mu.jpg"); 9 Mat src=imread("E://lena.jpg"); 10 Mat dst=src.clone(); 11 imshow("temp",temp); 12 13 int width=src.cols-temp.cols+1;//result宽度 14 int height=src.rows-temp.rows+1;//result高度 15 16 Mat result(height,width,CV_32FC1);//创建结果映射图像 17 //matchTemplate(srcImg, templateImg, resultImg, CV_TM_SQDIFF); //平方差匹配法(最好匹配0) 18 //matchTemplate(srcImg, templateImg, resultImg, CV_TM_SQDIFF_NORMED); //归一化平方差匹配法(最好匹配0) 19 //matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCORR); //相关匹配法(最坏匹配0) 20 //matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCORR_NORMED); //归一化相关匹配法(最坏匹配0) 21 //matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCOEFF); //系数匹配法(最好匹配1) 22 matchTemplate(src,temp,result,CV_TM_CCOEFF_NORMED);//化相关系数匹配,最佳值1 23 imshow("result",result); 24 normalize(result,result,0,1,NORM_MINMAX,-1);//归一化到0-1范围 25 26 double minValue,maxValue; 27 Point minLoc,maxLoc; 28 minMaxLoc(result,&minValue,&maxValue,&minLoc,&maxLoc); 29 cout<<"minValue="<<minValue<<endl; 30 cout<<"maxValue="<<maxValue<<endl; 31 32 rectangle(dst,maxLoc,Point(maxLoc.x+temp.cols,maxLoc.y+temp.rows),Scalar(0,255,0),2,8); 33 imshow("dst",dst); 34 35 waitKey(0); 36 }
注意:result的长宽正好是原图-模板图的长宽,result图中白亮程度表示匹配程度
三、视频模板匹配
1 #include "opencv2/opencv.hpp" 2 #include <iostream> 3 using namespace std; 4 using namespace cv; 5 6 void main() 7 { 8 Mat frame,resultImg; 9 Mat templateImg = imread("E://green.jpg"); 10 VideoCapture cap("E://1.mp4"); 11 if(!cap.isOpened()) 12 return; 13 int resultImg_cols,resultImg_rows; 14 15 while(1) 16 { 17 cap>>frame; 18 if(frame.empty()) break; 19 Mat showImg = frame.clone(); 20 resultImg_cols = frame.cols - templateImg.cols + 1; 21 resultImg_rows = frame.rows - templateImg.rows + 1; 22 resultImg.create(resultImg_cols, resultImg_rows, CV_32FC1); 23 matchTemplate(frame, templateImg, resultImg, CV_TM_CCOEFF_NORMED); //化相关系数匹配法(最好匹配1) 24 normalize(resultImg, resultImg, 0, 1, NORM_MINMAX); 25 26 double minValue, maxValue; 27 Point minLoc, maxLoc; 28 Point matchLoc; 29 30 minMaxLoc(resultImg, &minValue, &maxValue, &minLoc, &maxLoc); 31 cout<<"max_value= "<<maxValue<<endl; 32 //cout<<"min_value= "<<minValue<<endl; 33 if(maxValue>=0.7) 34 rectangle(showImg, maxLoc, Point(maxLoc.x + templateImg.cols, maxLoc.y + templateImg.rows), Scalar(0, 255, 0), 2); 35 imshow("frame", frame); 36 imshow("result", showImg); 37 if(27 == waitKey(10)) 38 break; 39 } 40 destroyAllWindows(); 41 42 waitKey(0); 43 }
四、多模板匹配(没懂/(ㄒoㄒ)/~~)
1 #include "opencv2/opencv.hpp" 2 #include <iostream> 3 using namespace std; 4 using namespace cv; 5 6 void main() 7 { 8 Mat srcImg = imread("E://src.png"); 9 Mat templateImg = imread("E://temp.png"); 10 Mat resultImg; 11 Mat showImg = srcImg.clone(); 12 13 int resultImg_cols = srcImg.cols - templateImg.cols + 1; 14 int resultImg_rows = srcImg.rows - templateImg.rows + 1; 15 16 resultImg.create(resultImg_cols, resultImg_rows, CV_32FC1); 17 matchTemplate(srcImg, templateImg, resultImg, CV_TM_CCOEFF_NORMED); //化相关系数匹配法(最好匹配1) 18 normalize(resultImg, resultImg, 0, 1, NORM_MINMAX); 19 Mat midImg = resultImg.clone(); 20 21 //多目标模板匹配---方法一 22 /*double matchValue; 23 int count0=0; 24 int tempW=0, tempH=0; 25 char matchRate[10]; 26 27 for(int i=0; i<resultImg_rows; i++) 28 { 29 for(int j=0; j<resultImg_cols; j++) 30 { 31 matchValue = resultImg.at<float>(i, j); 32 sprintf(matchRate, "%0.2f", matchValue); 33 if(matchValue>=0.85 && (abs(j - tempW)>5) && (abs(i - tempH)>5) ) 34 { 35 count0++; 36 putText(showImg, matchRate, Point(j-5, i-5), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1); 37 rectangle(showImg, Point(j, i), Point(j + templateImg.cols, i + templateImg.rows), Scalar(0, 255, 0), 2); 38 tempW = j; 39 tempH = i; 40 } 41 } 42 } 43 cout<<"count="<<count0<<endl; 44 imshow("resultImg", resultImg); 45 imshow("dst", showImg);*/ 46 47 //多目标模板匹配---方法二 48 double minValue, maxValue; 49 Point minLoc, maxLoc; 50 Point matchLoc; 51 char matchRate[10]; 52 53 for(int i=0; i<100; i++) 54 { 55 int startX = maxLoc.x - 4; 56 int startY = maxLoc.y - 4; 57 int endX = maxLoc.x + 4; 58 int endY = maxLoc.y + 4; 59 if(startX<0 || startY<0) 60 { 61 startX = 0; 62 startY = 0; 63 } 64 if(endX > resultImg.cols - 1 || endY > resultImg.rows - 1) 65 { 66 endX = resultImg.cols - 1; 67 endY = resultImg.rows- 1; 68 } 69 Mat temp = Mat::zeros(endX - startX, endY - startY, CV_32FC1); 70 //Mat ROI = resultImg(Rect(Point(startX, startY), temp.cols, temp.rows)); 71 temp.copyTo(resultImg(Rect(startX, startY, temp.cols, temp.rows))); 72 minMaxLoc(resultImg, &minValue, &maxValue, &minLoc, &maxLoc); 73 if(maxValue<0.8) break; 74 75 cout<<"max_value= "<<maxValue<<endl; 76 sprintf(matchRate, "%0.2f", maxValue); 77 putText(showImg, matchRate, Point(maxLoc.x - 5, maxLoc.y - 5), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1); 78 rectangle(showImg, maxLoc, Point(maxLoc.x + templateImg.cols, maxLoc.y + templateImg.rows), Scalar(0, 255, 0), 2); 79 80 } 81 imshow("midImg", midImg); 82 imshow("resultImg", resultImg); 83 imshow("dst", showImg); 84 85 waitKey(0); 86 }