title: Improving threshold result for Tesseract
body: <p>I am kind of stuck with this problem, and I know there are so many questions about it on stack overflow but in my case. Nothing gives the expected result.</p>
  
  <p><strong>The Context:</strong></p>
  
  <p>Am using Android OpenCV along with Tesseract so I can read the MRZ area in the passport. When the camera is started I pass the input frame to an AsyncTask, the frame is processed, the MRZ area is extracted succesfully, I pass the extracted MRZ area to a function prepareForOCR(inputImage) that takes the MRZ area as gray Mat and Will output a bitmap with the thresholded image that I will pass to Tesseract.</p>
  
  <p><strong>The problem:</strong></p>
  
  <p>The problem is while thresholding the Image, I use adaptive thresholding with blockSize = 13 and C = 15, but the result given is not always the same depending on the lighting of the image and the conditions in general from which the frame is taken. </p>
  
  <p><strong>What I have tried:</strong></p>
  
  <p>First I am resizing the image to a specific size (871,108) so the input image is always the same and not dependant on which phone is used. 
  After resizing, I try with different BlockSize and C values</p>
  
  <pre><code>//toOcr contains the extracted MRZ area
  Bitmap toOCRBitmap = Bitmap.createBitmap(bitmap);
  Mat inputFrame = new Mat();
  Mat toOcr = new Mat();
  Utils.bitmapToMat(toOCRBitmap, inputFrame);
  Imgproc.cvtColor(inputFrame, inputFrame, Imgproc.COLOR_BGR2GRAY);
  TesseractResult lastResult = null;
  for (int B = 11; B &lt; 70; B++) {
      for (int C = 11; C &lt; 70; C++){
          if (IsPrime(B) &amp;&amp; IsPrime(C)){
              Imgproc.adaptiveThreshold(inputFrame, toOcr, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, B ,C);
              Bitmap toOcrBitmap = OpenCVHelper.getBitmap(toOcr);
              TesseractResult result = TesseractInstance.extractFrame(toOcrBitmap, "ocrba");
              if (result.getMeanConfidence()&gt; 70) {
                  if (MrzParser.tryParse(result.getText())){
                      Log.d("Main2Activity", "Best result with " + B + " : " + C);
                      return result;
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>Using the code below, the thresholded result image is a black on white image which gives a confidence greater than 70, I can't really post the whole image for privacy reasons, but here's a clipped one and a dummy password one. </p>
  
  <p><a href="https://i.stack.imgur.com/Sly3e.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Sly3e.png" alt="Clipped image"></a></p>
  
  <p><a href="https://i.stack.imgur.com/e6hva.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/e6hva.png" alt="From the web"></a></p>
  
  <p>Using the MrzParser.tryParse function which adds checks for the character position and its validity within the MRZ, am able to correct some occurences like a name containing a 8 instead of B, and get a good result but it takes so much time, which is normal because am thresholding almost 255 images in the loop, adding to that the Tesseract call. </p>
  
  <p>I already tried getting a list of C and B values which occurs the most but the results are different. </p>
  
  <p>The question:</p>
  
  <p>Is there a way to define a C and blocksize value so that it s always giving the same result, maybe adding more OpenCV calls so The input image like increasing contrast and so on, I searched the web for 2 weeks now I can't find a viable solution, this is the only one that is giving accurate results</p>