1 | initial version |
In the first you have to use threshold() then use minMaxLoc.In each step you have to clear the current local maximum then find next local maximum.
Example:
object :
scene:
Result:
You have to change OpenCV example.
vector<Point> tempMatch(Mat object,Mat scene,int match_method,float peek_percent)
{
Mat img_display;
scene.copyTo( img_display );
/// Create the result matrix
int result_cols = scene.cols - object.cols + 1;
int result_rows = scene.rows - object.rows + 1;
Mat result( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( scene, object, 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;
/// 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;
threshold(result,result,0.1,1,CV_THRESH_BINARY_INV);
}
else
{
matchLoc = maxLoc;
threshold(result,result,0.9,1,CV_THRESH_TOZERO);
}
vector<Point> res;
maxVal = 1.f;
while (maxVal > peek_percent)
{
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
if (maxVal > peek_percent)
{
rectangle(result,Point(maxLoc.x - object.cols/2,maxLoc.y - object.rows/2),Point(maxLoc.x + object.cols/2,maxLoc.y + object.rows/2),Scalar::all(0),-1);
res.push_back(maxLoc);
}
}
return res;
}
void drawMatch(Mat object,Mat scene,vector<Point> match_centers)
{
for(size_t i=0; i < match_centers.size();i++)
rectangle(scene,Point(match_centers[i].x ,match_centers[i].y ),Point(match_centers[i].x + object.cols,match_centers[i].y + object.rows),Scalar(0,255,0),2);
}
int main()
{
Mat scene = imread("c:\\scene.png");
Mat object = imread("c:\\object.png");
vector<Point> match_centers = tempMatch(object,scene,CV_TM_SQDIFF_NORMED,0.9);
drawMatch(object,scene,match_centers);
imshow("result",scene);
waitKey(0);
return 0;
}
2 | No.2 Revision |
In the first you have to use threshold() then use minMaxLoc.In each step you have to clear the current local maximum then find next local maximum.
Example:
object :
scene:
Result:
You have to change OpenCV example.
vector<Point> tempMatch(Mat object,Mat scene,int match_method,float peek_percent)
{
Mat img_display;
scene.copyTo( img_display );
/// Create the result matrix
int result_cols = scene.cols - object.cols + 1;
int result_rows = scene.rows - object.rows + 1;
Mat result( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( scene, object, 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;
/// 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;
threshold(result,result,0.1,1,CV_THRESH_BINARY_INV);
}
else
{
matchLoc = maxLoc;
threshold(result,result,0.9,1,CV_THRESH_TOZERO);
}
vector<Point> res;
maxVal = 1.f;
while (maxVal > peek_percent)
{
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
if (maxVal > peek_percent)
{
rectangle(result,Point(maxLoc.x - object.cols/2,maxLoc.y - object.rows/2),Point(maxLoc.x + object.cols/2,maxLoc.y + object.rows/2),Scalar::all(0),-1);
res.push_back(maxLoc);
}
}
return res;
}
void drawMatch(Mat object,Mat scene,vector<Point> match_centers)
{
for(size_t i=0; i < match_centers.size();i++)
rectangle(scene,Point(match_centers[i].x ,match_centers[i].y ),Point(match_centers[i].x + object.cols,match_centers[i].y + object.rows),Scalar(0,255,0),2);
}
int main()
{
Mat scene = imread("c:\\scene.png");
Mat object = imread("c:\\object.png");
vector<Point> match_centers = tempMatch(object,scene,CV_TM_SQDIFF_NORMED,0.9);
drawMatch(object,scene,match_centers);
imshow("result",scene);
waitKey(0);
return 0;
}
There is another example here.