Ask Your Question

Revision history [back]

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 :

image description

scene:

image description

Result:

image description

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;
}

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 :

image description

scene:

image description

Result:

image description

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.