VS2010+Opencv2.3.1,例程實現 筆記之模板匹配
VS2010+Opencv2.3.1,例程實現
020 Template Matching
成功程式: /** * @file MatchTemplate_Demo.cpp * @brief Sample code to use the function MatchTemplate * @author OpenCV team */ #include #include"opencv2/imgproc/imgproc.hpp" #include<iostream> #include<stdio.h>
usingnamespace std; usingnamespace cv;
/// Global Variables Mat img; Mat templ; Mat result; char* image_window = "Source Image" char* result_window = "Result window";
int match_method; int max_Trackbar = 5;
/// Function Headers void MatchingMethod( int, void* );
/** * @function main */ int main( int argc, char** argv ) { /// Load image and template img = imread( "H:\\Image\\image0.jpg" , 1 ); // templ = imread( "H:\\Image\\image0010.jpg" , 1 );
/// Create windows namedWindow( image_window, CV_WINDOW_AUTOSIZE ); namedWindow( result_window, CV_WINDOW_AUTOSIZE );
/// Create Trackbar char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
MatchingMethod( 0, 0 );
waitKey(0); return 0; }
/** * @function MatchingMethod * @brief Trackbar callback */ void MatchingMethod( int, void* ) { /// Source image to display Mat img_display; img.copyTo( img_display );
/// Create the result matrix int result_cols = img.cols - templ.cols + 1; int result_rows = img.rows - templ.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize matchTemplate( img, templ, result, match_method ); normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
/// Localizing the best match with minMaxLoc double minVal; double maxVal; Point minLoc; Point maxLoc; Point matchLoc;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED ) { matchLoc = minLoc; } else { matchLoc = maxLoc; }
/// Show me what you got rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
imshow( image_window, img_display ); imshow( result_window, result );
return; }
原圖
執行結果:
看打框框的就表示程式找到了模板圖的目標了,//左上角的圖表示的是相似度圖,最亮的就表示相似度最高!
程式詳解: Explanation
1. Declare some global variables, such as the image, template and result matrices, as well as the match method and the window names: Mat img; Mat templ; Mat result; char* image_window = "Source Image"; char* result window = "Result window"; int match_method; int max_Trackbar = 5 ;
2. Load the source image and template: img = imread( argv[1], 1 ); templ = imread( argv[2], 1 ); 3. Create the windows to show the results: namedWindow( image_window, CV_WINDOW_AUTOSIZE ); namedWindow( result_window, CV_WINDOW_AUTOSIZE ); 4. Create the Trackbar to enter the kind of matching method to be used. When a change is detected the callback function MatchingMethod is called. char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod ); 5. Wait until user exits the program. waitKey(0); return 0 ; 6. Let’s check out the callback function. First, it makes a copy of the source image: Mat img_display; img.copyTo( img_display ); 7. Next, it creates the result matrix that will store the matching results for each template location. Observe in detail the size of the result matrix (which matches all possible locations for it) int result cols = img.cols - templ.cols + 1; int result rows = img.rows - templ.rows + 1; result.create( result cols, result rows, CV 32FC1 ); 8. Perform the template matching operation: matchTemplate( img, templ, result, match_method ); the arguments are naturally the input image I, the template T, the result R and the match_method (given by the Trackbar) 9. We normalize the results: normalize( result, result, 0 , 1, NORM MINMAX, -1, Mat() ); 10. We localize the minimum and maximum values in the result matrix R by using minMaxLoc. //怪不得,最亮的就表示相似度最高! double minVal; double maxVal; Point minLoc; Point maxLoc; Point matchLoc; minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() ); the function calls as arguments: • result: The source array
• &minVal and &maxVal: Variables to save the minimum and maximum values in result
• &minLoc and &maxLoc: The Point locations of the minimum and maximum values in the array.
• Mat(): Optional mask 11. For the first two methods ( CV_SQDIFF and CV_SQDIFF_NORMED ) the best match are the lowest values. For all the others, higher values represent better matches. So, we save the corresponding value in the matchLoc variable: if ( match method == CV TM SQDIFF || match method == CV TM SQDIFF NORMED ) { matchLoc = minLoc; } else { matchLoc = maxLoc; } 12. Display the source image and the result matrix. Draw a rectangle around the highest possible matching area: rectangle( img display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar ::all(0), 2, rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar ::all(0), 2, 8 , 0 imshow( image_window, img_display ); imshow( result_window, result ); |