title: Object detection with OpenCV Feature Matching with a threshold/similarity score - Java/C++
body: <p>I am in the process of creating a small program which detects objects(small image) in the large image and I am using OpenCV java. 
  As I have to consider rotation and scaling I have used FeatureDetector.BRISK and DescriptorExtractor.BRISK. </p>
  
  <p>Following approach is used to filter the match results to get the best matches only.</p>
  
  <p>I have two questions</p>
  
  <ol>
  <li>Is there a way to find the below min_dist and max_dist with the loop I have used?</li>
  <li>Most important question - Now the problem is I need to use these matches to determine whether the object(template) found or not. Would be great if some one help me here.</li>
  </ol>
  
  <p>Thanks in advance.</p>
  
  <pre><code>    FeatureDetector  fd = FeatureDetector.create(FeatureDetector.BRISK); 
      final MatOfKeyPoint keyPointsLarge = new MatOfKeyPoint();
      final MatOfKeyPoint keyPointsSmall = new MatOfKeyPoint();
  
      fd.detect(largeImage, keyPointsLarge);
      fd.detect(smallImage, keyPointsSmall);
  
      System.out.println("keyPoints.size() : "+keyPointsLarge.size());
      System.out.println("keyPoints2.size() : "+keyPointsSmall.size());
  
      Mat descriptorsLarge = new Mat();
      Mat descriptorsSmall = new Mat();
  
      DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.BRISK);
      extractor.compute(largeImage, keyPointsLarge, descriptorsLarge);
      extractor.compute(smallImage, keyPointsSmall, descriptorsSmall);
  
      System.out.println("descriptorsA.size() : "+descriptorsLarge.size());
      System.out.println("descriptorsB.size() : "+descriptorsSmall.size());
  
      MatOfDMatch matches = new MatOfDMatch();
  
      DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
      matcher.match(descriptorsLarge, descriptorsSmall, matches);
  
      System.out.println("matches.size() : "+matches.size());
  
      MatOfDMatch matchesFiltered = new MatOfDMatch();
  
      List&lt;DMatch&gt; matchesList = matches.toList();
      List&lt;DMatch&gt; bestMatches= new ArrayList&lt;DMatch&gt;();
  
      Double max_dist = 0.0;
      Double min_dist = 100.0;
  
      for (int i = 0; i &lt; matchesList.size(); i++)
      {
          Double dist = (double) matchesList.get(i).distance;
  
          if (dist &lt; min_dist &amp;&amp; dist != 0)
          {
              min_dist = dist;
          }
  
          if (dist &gt; max_dist)
          {
              max_dist = dist;
          }
  
      }
  
      System.out.println("max_dist : "+max_dist);
      System.out.println("min_dist : "+min_dist);
  
      double threshold = 3 * min_dist;
      double threshold2 = 2 * min_dist;
  
      if (threshold2 &gt;= max_dist)
      {
          threshold = min_dist * 1.1;
      }
      else if (threshold &gt;= max_dist)
      {
          threshold = threshold2 * 1.4;
      }
  
      System.out.println("Threshold : "+threshold);
  
      for (int i = 0; i &lt; matchesList.size(); i++)
      {
          Double dist = (double) matchesList.get(i).distance;
          System.out.println(String.format(i + " match distance best : %s", dist));
          if (dist &lt; threshold)
          {
              bestMatches.add(matches.toList().get(i));
              System.out.println(String.format(i + " best match added : %s", dist));
          }
      }
  
  
      matchesFiltered.fromList(bestMatches);
  
      System.out.println("matchesFiltered.size() : " + matchesFiltered.size());
  </code></pre>
  
  <hr>
  
  <h2>Edit</h2>
  
  <p>Edited my code as follows.I know still it's not the best way to come to a conclusion whether the object found or not based on no of best matches.
  So please share your views.</p>
  
  <pre><code>    System.out.println("max_dist : "+max_dist);
      System.out.println("min_dist : "+min_dist);
  
      if(min_dist &gt; 50 )
      {
          System.out.println("No match found");
          System.out.println("Just return ");
          return false;
      }
  
      double threshold = 3 * min_dist;
      double threshold2 = 2 * min_dist;
  
      if (threshold &gt; 75)
      {
          threshold  = 75;
      }
      else if (threshold2 &gt;= max_dist)
      {
          threshold = min_dist * 1.1;
      }
      else if (threshold &gt;= max_dist)
      {
          threshold = threshold2 * 1.4;
      }
  
      System.out.println("Threshold : "+threshold);
  
      for (int i = 0; i &lt; matchesList.size(); i++)
      {
          Double dist = (double) matchesList.get(i).distance;
  
          if (dist &lt; threshold)
          {
              bestMatches.add(matches.toList().get(i));
              //System.out.println(String.format(i + " best match added : %s", dist));
          }
      }
  
      matchesFiltered.fromList(bestMatches);
  
      System.out.println("matchesFiltered.size() : " + matchesFiltered.size());
  
  
      if(matchesFiltered.rows() &gt;= 1)
      {
          System.out.println("match found");
          return true;
      }
      else
      {
          return false;
      }
  </code></pre>