Rotation Detection based on Template Matching
I have a source image and several template images. These template images are rotated by different degrees. If the template image is not rotated (or rotated by 0 degree), I can use the attached code to find the matched pattern in the source image. However, if the template image is rotated, the template matching method in OpenCV might not work. How can I revise the code to enable it to detect the matched rotated pattern, as well as the angle that it is rotated by?
Thanks in advance.
Source image: C:\fakepath\O.jpg Template image: C:\fakepath\T.jpg Template image rotated by 30 degrees: C:\fakepath\Tr30.jpg
cpp file: #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> #include <math.h>
using namespace std;
using namespace cv;
/// Global Variables
Mat img; Mat templ; Mat result;
char* result_window = "Result window";
int main( int argc, char** argv )
{
/// Load image and template
img = imread( argv[1], 1 );
templ = imread( argv[2], 1 );
/// Create windows
namedWindow( result_window, CV_WINDOW_AUTOSIZE );
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, CV_TM_SQDIFF_NORMED );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
double minVal; double maxVal; Point minLoc; Point maxLoc;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
/// Show me what you got
rectangle( result, minLoc, Point( minLoc.x + templ.cols , minLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
imshow( result_window, result );
waitKey(0);
return 0;
}
How are the images rotated? I mean, if you rotate a rectangle by 45deg, the new image is a bigger rectangle so the rotated one fit entirely into it. Padding will be added in order to fill all the pixels that are not part of the original rectangle. A padded pixel is usually given a value of 255 or 0 (black or white, depending of the rotation algorithm).
Now, template_matching does match all of the template, so it will try to match even the region that contains only padded pixels and no useful information, which it most likely won't find in the query image. I think I have seen people trying to use the alpha (transparency) layer to get around this, but I don't remember in which question on opencvQA and I am not able to do it myself. You might use a mask but it's only ...(more)