How to use OpenCV+Tesseract for accurate Text recognition in Android? - android

I am trying to use OpenCV (Android) for processing image taken using camera and then pass it to Tesseract for text (digits) recognition but am not getting good results till the images are very (almost no noise) fine.
Currently I am performing below processing on taken images as:
1. Applying Gaussian blur.
2. Adaptive threshold: to binarize the image.
3. Inverting colours to make background black.
Then passing the processed image to Tesseract.
But I am not getting good results.
Please suggest what steps/measures I may take further to process image before passing to Tesseract or at stage while processing at Tesseract.
Also, are there any other better libraries in Android for this?

You can isolate/detect characters in images. This can be done with powerful algorithms such as the Stroke Width Transform.
The following steps worked well with me:
Obtain grayscale of image.
Perform canny edge detection on grayscale image.
Apply gaussian blur on grayscale image(store in seperate matrix)
Input matrices from steps 2 & 3 into SWT
algorithm
Binarize(threshhold) resulting image.
Feed image to tesseract.
Please note, for step 4 you will need to build the c++ library in the link and then import into your android project with JNI wrappers. Also, you will need to do micro tweaking for all steps to get the best results. But, this should at least get you started.

Related

Junk results when using Tesseract OCR and tess-two

I have developed OCR Application using Tesseract OCR Library and referred from the following Links.
android-ocr
tesseract
But I am getting junk data as results sometimes. Can anyone help me what to do further to get accurate results.
You should provide your test images if you want to get specific help for your case as well as any code you are using but a general rule of thumb for getting accurate results are :
Use a high resolution image (if needed) 300 DPI is minimum
Make sure there is no shadows or bends in the image
If there is any skew, you will need to fix the image in code prior to ocr
Use a dictionary to help get good results
Adjust the text size (12 pt font is ideal)
Binarize the image and use image processing algorithms to remove noise
On top of all this, there are a lot of image processing functions out there that can help increase accuracy depending on your image such as deskew, perspective correction, line removal, border removal, dot removal, despeckle, and many more depending on your image.

Image processing using opencv before doing OCR on an image using tesseract

I've been trying to train tesseract engine to ocr images that have numbers written using the seven digital font.
And, after searching, it turned out that tesseract won't ocr a segmented font unless the segments are somehow connected.
So, I used erosion, which is an opencv function, on the images to connect the segments.
http://www.tutorialspoint.com/java_dip/eroding_dilating.htm
And, after that, I used thresholding to convert the image to binary before handing the image to tesseract (This step is redundant because tesseract internally does image binarization).
http://docs.opencv.org/2.4/doc/tutorials/imgproc/threshold/threshold.html
My main problem is that the numbers are written in black on a dark green background.
Here are the results
Original image:
Method 1:
After Erosion and binarization (I tried various threshold max values)
Method 2:
I tried to use k-means or c-means algorithms but the results were no much better.
Method 3:
I also tried adaptive Gaussian thresholding
Method 4:
Adaptive Mean
Method 5:
Handing the original image to tesseract without any image processing and outputting the result image (Tesseract uses leptonica to do image processing internally).
I also tried various samples instead of this one and tried Gimp to enhance the images using the steps in Gimp image processing, but nothing is working for me.
Any suggestions?
Thanks!

Real-time image processing with Camera2

I tried searching in a ton of places about doing this, with no results. I did read that the only (as far as I know) way to obtain image frames was to use a ImageReader, which gives me a Image to work with. However, a lot of work must be done before I have a nice enough image (converting Image to byte array, then converting between formats - YUV_420_888 to ARGB_8888 - using RenderScript, then turning it into a Bitmap and rotating it manually - or running the application on landscape mode). By this point a lot of processing is made, and I haven't even started the actual processing yet (I plan on running some native code on it). Additionally, I tried to lower the resolution, with no success, and there is a significant delay when drawing on the surface.
Is there a better approach to this? Any help would be greatly appreciated.
Im not sure what exactly you are doing with the images, but a lot of times only a grayscale image is actually needed (again depending on your exact goal) If your camera outputs YUV, the grayscale information is in the Y channel. The nice thing,is you don't need to convert to numerous colorspaces and working with only one layer (as opposed to three) decreases the size of your data set greatly.
If you need color images then this wouldn't help

Android auto crop camera captured images

I am looking for some kind of auto trim/crop functionality in android.
Which detects a object in captured image and creates a square box around object for
cropping. I have found face detection apis in android, but my problem is captured images are documents/pages not human faces so how can I detected documents or any other object from captured picture.
I am thinking of any algorithms for object detection or some color detection. Is there any apis or libraries available for it.
I have tried following link but not found any desired output.
Find and Crop relevant image area automatically (Java / Android)
https://github.com/biokys/cropimage
Any small hint would also help me alot. Please help. Thanks in advance
That depends on what you intend to capture and crop, but there are many ways to achieve this. Like littleimp suggested, you should use OpenCv for the effect.
I suggest you use edge-detection algorithms, such as Sobel, and perform image transformation on it with, for example, a Threshold function that will turn the image into a binary one (only black and white). Afterwards, you can search the image for the geometric shape you want, using what's suggested here. Filter the object you want by calculating the detected geometric figure's area and ratio.
It would help a lot to know what you're trying to detect in an image. Those methods I described were the ones I used for my specific case, which was developing an algorithm to detect and crop the license plate from a given vehicle image. It works close to perfect and it was all done by using OpenCV.
If you have anything else you'd like to know, don't hesitate to ask. I'm watching this post :)
Use OpenCV for android.
You can use the Watershed (Imgproc.watershed) function to segment the image into foreground and background. Then you can crop around the foreground (which will be the document).
The watershed algorithm needs some markers pre-defining the regions. You can for example assume the document to be in the middle of the image, so create a marked region in the middle of the image to get the watershed algorithm started.

Real Time Image Processing in Android using the NDK

Using an Android (2.3.3) phone, I can use the camera to retrieve a preview with the onPreviewFrame(byte[] data, Camera camera) method to get the YUV image.
For some image processing, I need to convert this data to an RGB image and show it on the device. Using the basic java / android method, this runs at a horrible rate of less then 5 fps...
Now, using the NDK, I want to speed things up. The problem is: How do I convert the YUV array to an RGB array in C? And is there a way to display it (using OpenGL perhaps?) in the native code? Real-time should be possible (the Qualcomm AR demos showed us that).
I cannot use the setTargetDisplay and put an overlay on it!
I know Java, recently started with the Android SDK and have zero experience in C
Have you considered using OpenCV's Android port? It can do a lot more than just color conversion, and it's quite fast.
A Google search returned this page for a C implementation of YUV->RGB565. The author even included the JNI wrapper for it.
You can also succeed by staying with Java. I did this for the imagedetectíon of the androangelo-app.
I used the sample code which you find here by searching "decodeYUV".
For processing the frames, the essential part to consider is the image-size.
Depending on the device you may get quite large images. i.e. for the Galaxy S2
the smallest supported previewsize is 640*480. This is a big amount of pixels.
What I did, is to use only every second row and every second column, after yuvtorgb decoding. So processing a 320*240 image works quite well and allowed me to get frame-rates of 20fps. (including some noise-reduction, a color-conversion from rgb to hsv and a circledetection)
In addition You should carefully check the size of the image-buffer provided to the setPreview function. If it is too small, the garbage-collection will spoil everything.
For the result you can check the calibration-screen of the androangelo-app. There I had an overlay of the detected image over the camera-preview.

Categories

Resources