0

I have this image enter image description here. I am trying to OCR the letters in this image. I am not getting desired result for letters '9' and 'R'. First I cropped these letters, enter image description here & enter image description here and executing following command.

tesseract 9.png stdout -psm 8
.

It is just returning "."

OCR for all other letters are working fine but not for these two letters(though, I think their image quality is not that bad). Any suggestion/help is appreciated.

Community
  • 1
  • 1
Bhushan
  • 1,489
  • 3
  • 27
  • 45

2 Answers2

2

I've no experience with tesseract myself, but replicating the character and adding some background works on https://www.newocr.com/ which uses tesseract internally, according to google result.

So I used this as input:

enter image description here

which gives the correct result on that web-app: 99999999, while the single character doesn't work. Maybe you can verify this with your tesseract implementation and maybe it helps you to adjust your isolated extracted characters to work with tesseract. e.g. try to stitch multiple duplicates of your extracted contour next to each other to improve tesseract output - since you know how often you stitched the contour next to each other you'll know that the output might be correct if it recognizes the same character that often times..

same works for

enter image description here

The border looks important, without enough border it will recognize P. In general afaik you should try to replace background and foreground by pure black and pure white! Not sure what kind of preprocessing the web-app uses...

this code can be used to repeat an image with C++ and OpenCV, but it won't add a border around. To do that you would work very similar but with some additional steps and you would have to assign some color to the border.

EDIT: I've updated the code to use a border of 4 pixel in each direction (you can adjust the variable) and with black background color.

This code is very easy and should be very similar for opencv in java, python, etc.

int main(int argc, char * argv[])
{
    //cv::Mat input = cv::imread("../inputData/ocrR.png");

    if(argc != 3)
    {
        std::cout << "usage: .exe filename #Repetitions" << std::endl;
        return 0;
    }

    std::string filename = argv[1];
    int nRepetitions = atoi(argv[2]);

    cv::Mat inputImage = cv::imread(filename);
    if(inputImage.empty())
    {
        std::cout << "image file " << filename << " could not be loaded" << std::endl;
        return 0;
    }

    // you instead should try to extract the background color from the image (e.g. from the image border)
    cv::Scalar backgroundColor(0,0,0);

    // size of the border in each direction
    int border = 4;

    cv::Mat repeatedImage = cv::Mat(inputImage.rows + 2*border, nRepetitions*inputImage.cols + 2*border, inputImage.type() , backgroundColor);

    cv::Rect roi = cv::Rect(border,border,inputImage.cols, inputImage.rows);

    for(int i=0; i<nRepetitions; ++i)
    {
        // copy original image to subimage of repeated image
        inputImage.copyTo(repeatedImage(roi));

        // update roi position
        roi.x += roi.width;
    }

    // now here you could send your repeated image to tesseract library and test whether nRepetitions times a letter was found.

    cv::imwrite("repeatedImage.png", repeatedImage);
    cv::imshow("repeated image" , repeatedImage);
    cv::waitKey(0);
    return 0;
}

giving this result:

enter image description here

Micka
  • 19,585
  • 4
  • 56
  • 74
  • Thanks for inputs, I will try that. But can you verify this behavior with letter 'R' ? – Bhushan Dec 09 '15 at 14:00
  • 1
    yes, updated the answer. interestingly with 7 or less the 'R' will be recognized as a n times 'p' but with 8 letters it will be recognized as 'R's ... even if thresholded to pure black and pure white. in the end I don't know what kind of preprocessing is performed by that web-app, so all those are just guesses... – Micka Dec 09 '15 at 14:14
  • Strangely your images works for me too. :p Can you tell me how replicate this image one after another ? – Bhushan Dec 09 '15 at 14:38
  • 1
    updated the code with replication, some border and background color too. – Micka Dec 09 '15 at 15:00
2

I had a tiny bit more success than you... I did a "Connected Components Analysis" to extract the individual letters, then put a border around each extracted letter and appended them all together into a single horizontal line which gave me this:

enter image description here

And if I then run tesseract I get:

VQQTRF
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Hi @Mark, only problem with this approach is that tesseract gets confuse when word is alpha-numberic. But when I do OCR individual letter then I get much better result(almost correct). – Bhushan Dec 09 '15 at 17:51
  • How come letter '9' and 'R' are more clearer & brighter in your image? Did you done something extra between finding contour and appending them all together ? – Bhushan Dec 09 '15 at 17:58
  • 1
    I thresholded at 50% I think as part of the connected components analysis. I also converred to HSL colourspace at one point and discarded the Hue and Saturation and just worked with Lightness channel. I also upped the size a little to make each letter 30-50 pixels high. I then got a bit discouraged as I couldn't really get anywhere with that awkward digit `9` which is why I didn't write it up in too much detail.... – Mark Setchell Dec 09 '15 at 19:27