title: OpenCV - Use FLANN with ORB descriptors to match features
body: <p>I am using OpenCV 3.2</p>
  
  <p>I am trying to use FLANN to match features descriptors in a faster way than brute force.</p>
  
  <pre><code>// Ratio to the second neighbor to consider a good match.
  #define RATIO    0.75
  
  void matchFeatures(const cv::Mat &amp;query, const cv::Mat &amp;target,
                     std::vector&lt;cv::DMatch&gt; &amp;goodMatches) {
      std::vector&lt;std::vector&lt;cv::DMatch&gt;&gt; matches;
      cv::Ptr&lt;cv::FlannBasedMatcher&gt; matcher = cv::FlannBasedMatcher::create();
      // Find 2 best matches for each descriptor to make later the second neighbor test.
      matcher-&gt;knnMatch(query, target, matches, 2);
      // Second neighbor ratio test.
      for (unsigned int i = 0; i &lt; matches.size(); ++i) {
          if (matches[i][0].distance &lt; matches[i][1].distance * RATIO)
              goodMatches.push_back(matches[i][0]);
      }
  }
  </code></pre>
  
  <p>This code is working me with SURF and SIFT descriptors, but not with ORB.</p>
  
  <pre><code>OpenCV Error: Unsupported format or combination of formats (type=0) in buildIndex
  </code></pre>
  
  <p>As it's said <a href="https://stackoverflow.com/questions/11565255/opencv-flann-with-orb-descriptors">here</a>, FLANN needs the descriptors to be of type CV_32F so we need to convert them.</p>
  
  <pre><code>if (query.type() != CV_32F) query.convertTo(query, CV_32F);
  if (target.type() != CV_32F) target.convertTo(target, CV_32F);
  </code></pre>
  
  <p>However, this supposed fix is returning me another error in <code>convertTo</code> function.</p>
  
  <pre><code>OpenCV Error: Assertion failed (!fixedType() || ((Mat*)obj)-&gt;type() == mtype) in create
  </code></pre>
  
  <p>This assertion is in <code>opencv/modules/core/src/matrix.cpp</code> file, line 2277.</p>
  
  <p>What's happening?</p>
  
  <hr>
  
  <p><em>Code to replicate issue.</em></p>
  
  <pre><code>#include &lt;opencv2/opencv.hpp&gt;
  
  int main(int argc, char **argv) {
      // Read both images.
      cv::Mat image1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
      if (image1.empty()) {
          std::cerr &lt;&lt; "Couldn't read image in " &lt;&lt; argv[1] &lt;&lt; std::endl;
          return 1;
      }
      cv::Mat image2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
      if (image2.empty()) {
          std::cerr &lt;&lt; "Couldn't read image in " &lt;&lt; argv[2] &lt;&lt; std::endl;
          return 1;
      }
      // Detect the keyPoints and compute its descriptors using ORB Detector.
      std::vector&lt;cv::KeyPoint&gt; keyPoints1, keyPoints2;
      cv::Mat descriptors1, descriptors2;
      cv::Ptr&lt;cv::ORB&gt; detector = cv::ORB::create();
      detector-&gt;detectAndCompute(image1, cv::Mat(), keyPoints1, descriptors1);
      detector-&gt;detectAndCompute(image2, cv::Mat(), keyPoints2, descriptors2);
      // Match features.
      std::vector&lt;cv::DMatch&gt; matches;
      matchFeatures(descriptors1, descriptors2, matches);
      // Draw matches.
      cv::Mat image_matches;
      cv::drawMatches(image1, keyPoints1, image2, keyPoints2, matches, image_matches);
      cv::imshow("Matches", image_matches);
  }
  </code></pre>