title: Align 2 overlapping photos of a page of text
body: <p>I've got 2 images of text where the right side of the first image overlaps with the left side of the second (2 partial photos of the same page of text taken from left to right).
  I'd like to stitch the images and I'm trying an approach with feature matching.
  I've tried the example with the ORB feature search + brute force feature matching from the OpenCV site <a href="http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html#matcher" rel="nofollow noreferrer">http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html#matcher</a> </p>
  
  <p>It's completely off (doesn't find any correct matches, all false positives) in my case at least with the default parameters of the feature search. It looks logical that it would have a hard time in case of text if it uses corners.</p>
  
  <p>How do I match this kind of images with text more reliably with feature matching? Should I specify some different non-default parameters for the ORB search algorithm? use a different algorithm with different parameters?</p>
  
  <p>If not feature matching what other approach with Open CV can I use for this alignment?</p>
  
  <pre><code>Mat p1 = new Mat("part1.jpg", LoadMode.GrayScale);
  Mat p2 = new Mat("part2.jpg", LoadMode.GrayScale);
  
  var orb = new ORB();
  
  Mat ds1;
  var kp1 = DetectAndCompute(orb, p1, out ds1);
  
  Mat ds2;
  var kp2 = DetectAndCompute(orb, p2, out ds2);
  
  var bfMatcher = new BFMatcher(NormType.Hamming, crossCheck: true);
  var matches = bfMatcher.Match(ds1, ds1);
  
  var tenBestMatches = matches.OrderBy(x =&gt; x.Distance).Take(10);
  
  var res = new Mat();
  Cv2.DrawMatches(p1, kp1, p2, kp2, tenBestMatches, res, flags: DrawMatchesFlags.DrawRichKeypoints);
  
  
  using (new Window("result", WindowMode.ExpandedGui, res))
  {
      Cv2.WaitKey();
  }
  </code></pre>
  
  <hr>
  
  <pre><code>private static KeyPoint[] DetectAndCompute(ORB orb, Mat p1, out Mat ds1)
  {
      var kp1 = orb.Detect(p1);
      ds1 = new Mat();
      orb.Compute(p1, ref kp1, ds1);
      return kp1;
  }
  </code></pre>
  
  <p><img src="https://i.imgur.com/0t9ZlSG.png" alt="image description"></p>