Ask Your Question
3

Template matching with mutiple templates

asked 2014-06-22 05:25:04 -0600

beny2111 gravatar image

updated 2014-06-22 05:28:08 -0600

hi all, I'm working on the android application template matching. I get a problem to compare one image with multiple templates. is there here that can help me in resolving the issue. I would appreciate if anyone can help me. thank you

I write the following code that I use

public void matching() {

    Mat img = Highgui.imread("/mnt/sdcard/img_eq/img_eq.jpg", CvType.CV_8SC3);

    Mat templ = Highgui.imread("/mnt/sdcard/img_template/img_template.jpg", CvType.CV_8SC3);

    //Create the result matrix
    int match_method = Imgproc.TM_SQDIFF_NORMED;
    int result_cols = img.cols() - templ.cols() + 1;
    int result_rows = img.rows() - templ.rows() + 1;
    Mat result = new Mat(result_rows, result_cols, CvType.CV_8SC3);

     //Do the Matching and Normalize
    Imgproc.matchTemplate(img, templ, result, match_method);
    int type = Imgproc.THRESH_TOZERO;
    Imgproc.threshold(result, result, 0.8, 1., type);
    Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

    // / Localizing the best match with minMaxLoc
    MinMaxLocResult mmr = Core.minMaxLoc(result);

    Point matchLoc;
    if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
        matchLoc = mmr.minLoc;
    } else {
        matchLoc = mmr.maxLoc;
    }

    // / Show me what you got
    Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),matchLoc.y + templ.rows()), new Scalar(255, 0, 0));

    // Save the visualized detection.
    Highgui.imwrite("/mnt/sdcard/img_result/img_result.jpg", img);

    Mat image = Highgui.imread("/mnt/sdcard/img_result/img_result.jpg");
    Mat android_image = Mat.zeros(image.cols(), image.rows(), CvType.CV_8SC3);

    Imgproc.cvtColor(image, android_image, Imgproc.COLOR_BGR2RGB);

    Bitmap bm = Bitmap.createBitmap(android_image.cols(),android_image.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(android_image, bm);

    ImageView iv = (ImageView) findViewById(R.id.image);
    iv.setImageBitmap(bm);

}
edit retag flag offensive close merge delete

Comments

1

problem unclear. could you be a bit more explicit ?

berak gravatar imageberak ( 2014-06-22 06:05:00 -0600 )edit

I use the above code is a template that is img_template what I want is what if using a lot of templates, so I have a template that is img_template1, img_template2, etc. so what kind of code should I use thank you, sorry if my english bad

beny2111 gravatar imagebeny2111 ( 2014-06-22 08:01:51 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
6

answered 2014-06-25 06:25:13 -0600

updated 2014-06-25 06:26:28 -0600

Hi @beny2111! If you want to compare multiple Template Images in a Scene Image you have to follow the following steps.

  1. Create a Vector of Mat Containing All Template Images
  2. Pass the Template Images one by one to the Template matching function to find the Template Object in the Scene.
  3. Get the Co-Ordinates of each Template object & Draw it in the Scene Image. Here is the Code for doing so.

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

bool FindTemplate(Mat Img_Scene_Bgr,Mat Img_Template_Bgr,Point &Point_TemplateLocation) 
{
    // `Img_Scene_Bgr` and `Img_Template_Bgr` are the reference and template image
    cv::Mat Img_Result_Float(Img_Scene_Bgr.rows-Img_Template_Bgr.rows+1, Img_Scene_Bgr.cols-Img_Template_Bgr.cols+1, CV_32FC1);
    cv::matchTemplate(Img_Template_Bgr, Img_Scene_Bgr, Img_Result_Float, CV_TM_CCOEFF_NORMED);
    normalize( Img_Result_Float, Img_Result_Float, 0, 1, NORM_MINMAX, -1, Mat() );

    double minval, maxval, threshold = 0.7;
    cv::Point minloc, maxloc;
    cv::minMaxLoc(Img_Result_Float, &minval, &maxval, &minloc, &maxloc);

    if (maxval >= threshold) 
    {
        Point_TemplateLocation= maxloc;
        return true;
    }
    else
    {
        return false;
    }
}

int main( int argc, char** argv )
{
  Mat Img_Scene; 
  Mat Img_Template_1; 
  Mat Img_Template_2; 
  Mat Img_Result;
  char* image_window = "Source Image";
  char* result_window = "Result window";
  /// Load image and template
  Img_Scene = imread("SceneImage.png", 1 );
  Img_Template_1 = imread( "Templ1.png", 1 );
  Img_Template_2 = imread( "Templ2.png", 1 );

  if(Img_Scene.data== NULL||Img_Template_1.data==NULL||Img_Template_2.data==NULL)
  {
      cout<<"Image Not Found";
      return 0;
  }

  Img_Result= Img_Scene.clone();
  Vector<Mat> List_Template_Img;
  List_Template_Img.push_back(Img_Template_1);//Otherwise Get some folder & add the Files in it
  List_Template_Img.push_back(Img_Template_2);

  Point  Point_TemplateLocation;
  for (int i = 0; i < List_Template_Img.size(); i++)
  {
      if(!FindTemplate(Img_Scene,List_Template_Img[i],Point_TemplateLocation))
      {
          cout<<"No Match Found";
      }
      /// Show me what you got
      rectangle( Img_Result, Point_TemplateLocation, Point( Point_TemplateLocation.x + Img_Template_1.cols , Point_TemplateLocation.y + Img_Template_1.rows ), Scalar(0,0,255), 2, 8, 0 );
      putText( Img_Result, format("Object %d ",i),Point( Point_TemplateLocation.x + Img_Template_1.cols/4 , Point_TemplateLocation.y + Img_Template_1.rows/2 ),1,1,Scalar(255,0,0),1,-1);
  }
  /// Create windows
  namedWindow( image_window, CV_WINDOW_AUTOSIZE );
  namedWindow( result_window, CV_WINDOW_AUTOSIZE );

  imshow( image_window, Img_Template_1);
  imshow( image_window, Img_Template_2);
  imshow( result_window, Img_Result );

  waitKey(0);
  return 0;
}

image description

edit flag offensive delete link more

Comments

sorry, can you explain the purpose of the following code: List_Template_Img.push_back (Img_Template_1); because I build it in eclipse android java language, thank you so much for your attention

beny2111 gravatar imagebeny2111 ( 2014-06-25 07:03:37 -0600 )edit

Here i took only two images for explaining process. If you are having more images you can add that to the Template Collection i.e List_Template_Img like this List_Template_Img.pushback(imread( "File1.png", 1 )); I'm not sure what API in Android. But you can find similar one.

Balaji R gravatar imageBalaji R ( 2014-06-25 07:10:03 -0600 )edit

okeee, thank you very much. Now I have to figure out how to walk in android.

beny2111 gravatar imagebeny2111 ( 2014-06-25 07:46:36 -0600 )edit

i'm sorry, from where you can get Img_Scene_Bgr and Img_Template_Bgr are the reference and template image

beny2111 gravatar imagebeny2111 ( 2014-06-25 17:12:18 -0600 )edit
Balaji R gravatar imageBalaji R ( 2014-06-26 00:42:44 -0600 )edit

i'm very confuse in convert c++ to java language, i'm so newbie -_-

beny2111 gravatar imagebeny2111 ( 2014-06-26 07:27:44 -0600 )edit

@beny2111 Please accept the answer if it solves your Problem.

Balaji R gravatar imageBalaji R ( 2014-07-11 02:46:05 -0600 )edit

Hi Balaji, I am working on Template Matching using Opencv. I have written the template matching program for one template image and its working fine.. Now i'm trying template matching with multiple template images. I tried your code for multiple template but its not working for me..I dont know the reason. When I studied your code I had few doubts, can you please clarify my doubts 1.Img_Scene_Bgr and Img_Template_Bgr are the gray values of the source and template images? 2. In this line, cv::matchTemplate(Img_Template_Bgr, Img_Scene_Bgr, Img_Result_Float, CV_TM_CCOEFF_NORMED); when I checked in the opencv tutorial for the matchtemplate format, inside the bracket first we have declare the source image and then oly template image..you did in the other way.

Manimaran gravatar imageManimaran ( 2015-06-26 06:29:57 -0600 )edit

@ManimaranHere is a sample usage of multiple template matching. Please go through it & feel free to ask for any doubt!

Balaji R gravatar imageBalaji R ( 2015-06-26 06:33:11 -0600 )edit

since I'm not able to paste the complete code in a single comment.I will paste it in two halves..sory for the inconvience. code continues, while (true) { double minval, maxval, threshold = 0.9; Point minloc, maxloc; minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

    if (maxval >= threshold)
    {
      rectangle(srcimg, maxloc, Point(maxloc.x + tmplimg.cols, maxloc.y + tmplimg.rows), CV_RGB(0,255,0), 2);
      floodFill(res, maxloc, Scalar(0), 0, Scalar(.1), Scalar(1.));

      printf("My current maxval: %f \n", maxval);
    }
    else    
        break;
}

imshow("Source Image", srcimg);
waitKey();
return 0;

}

Manimaran gravatar imageManimaran ( 2015-06-26 06:34:07 -0600 )edit

Question Tools

Stats

Asked: 2014-06-22 05:25:04 -0600

Seen: 10,603 times

Last updated: Jun 25 '14