valentin
valentin

Reputation: 511

Merge edges and fill areas

This is question is a follow-up of Prepare complex image for OCR.

I have an output of a canny edge detector of an image with digits:

Canny edge image

As you can see, I have various edges for a digit, which result from the embossment on a credit card. The goal would be to have solid digits, which are suitable for character recognition.

This is an attempt to "fill" the digits using a morphological close operation with a 5x5 structuring element in shape of a diamond:

Morphological close operation

I tried various structuring elements, but without much success. You can see how holes are being created (digit 9 and 0) and shapes are being distorted (digit 3).

Can you recommend a better approach to fill the structures, but without glueing different digits together and keeping the original shape?

However, even with the poorly looking digits and splitting the digits vertically after applying the close operation, there are already good recognition results achievable.

Thanks, Valentin

Upvotes: 2

Views: 1368

Answers (2)

Buddhisthead
Buddhisthead

Reputation: 338

you haven't shown any code, so we can't help too much. Here is a snippet of how to use some morphological operations to fill in some gaps without changing the size before you try the canny operation.

// OTSU, then binary threshold
Imgproc.threshold(colorImg, grayImg, 0, 255.0, Imgproc.THRESH_OTSU | Imgproc.THRESH_BINARY);

// Morphological reduction of noise, strengthen lines
Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(7, 7));
Imgproc.dilate(grayImg, grayImg2, element);
Imgproc.erode(grayImg2, grayImg, element);

// Edge detection
Imgproc.Canny(grayImg, output, 50, 50);

However, you should look at card.io, which reads credit cards. Reading the embossed symbols is very difficult with pre image processing because the lighting varies so much. You are better off using machine learning.

Upvotes: 1

Konstantin Pribluda
Konstantin Pribluda

Reputation: 12367

enter image description hereI think that you can reach better results with advanced grayscale binarisation techniques, like sauvola binarisation with big kernel (I use 50x50). This threshold filter takes into account local variance of grayscale values and is not sensitive to changes in liminance. It also has some highpass/lowpass properties depending on settings. See implementation in JavaOCR Project:

http://sourceforge.net/projects/javaocr/

(PS: 50x50 kernels are not a problem - this implementation speed is kernel size independent )

Update, just tried my OCR dialer on credit card, binarisation result below:

Reflecting surfaces produce a lot of noise, but I think this could be manageable with some more preprocessing.

Upvotes: 2

Related Questions