3

I'm building an "Optical Character Recognition" system.

so far the system is capable to identify licence plates in good quality without any noise.

what I want in the next level is to be able to identify licence plates in poor quality beacuse of different reasons.

for example, let's look at the next plate:

enter image description here

as you see, the numbers are not look clearly, because of light returns or something else.

for my question: how can I improve the image quality, so when I move to binary image the numbers will not fade away?

thanks in advance.

Ofir A.
  • 3,112
  • 11
  • 57
  • 83
  • 2
    Use humans, you could put it as captcha in a website, that's almost what http://www.google.com/recaptcha does – Hernán Eche Jul 04 '11 at 19:30
  • Ummm, converting to binary most likely decreases the image quality a lot...is it a space issue?? Are you spying on lots of people?? :P – tylerthemiler Jul 04 '11 at 19:31
  • 1
    Could you explain how this question is different from your other questions such as [1](http://stackoverflow.com/questions/5312514/clean-noise-from-an-image-with-matlab), [2](http://stackoverflow.com/questions/5545020/segment-digits-in-an-image-matlab), [3](http://stackoverflow.com/questions/6238083/help-with-ocr-application-matlab) –  Jul 04 '11 at 19:34
  • Specifically, question 1 looks exactly like what you want :P – tylerthemiler Jul 04 '11 at 19:37
  • @tylerthemiler, @d00b, @Michael: I rewrote the Mathematica solution in [#1](http://stackoverflow.com/questions/5312514/clean-noise-from-an-image-with-matlab) into MATLAB code, take a look... – Amro Jul 04 '11 at 20:13

3 Answers3

3

We can try to correct for lighting effect by fitting a linear plane over the image intensities, which will approximate the average level across the image. By subtracting this shading plane from the original image, we can attempt to normalize lighting conditions across the image.

For color RGB images, simply repeat the process on each channel separately, or even apply it to a different colorspace (HSV, Lab*, etc...)

Here is a sample implementation:

function img = correctLighting(img, method)
    if nargin<2, method='rgb'; end
    switch lower(method)
        case 'rgb'
            %# process R,G,B channels separately
            for i=1:size(img,3)
                img(:,:,i) = LinearShading( img(:,:,i) );
            end
        case 'hsv'
            %# process intensity component of HSV, then convert back to RGB
            HSV = rgb2hsv(img);
            HSV(:,:,3) = LinearShading( HSV(:,:,3) );
            img = hsv2rgb(HSV);
        case 'lab'
            %# process luminosity layer of L*a*b*, then convert back to RGB
            LAB = applycform(img, makecform('srgb2lab'));
            LAB(:,:,1) = LinearShading( LAB(:,:,1) ./ 100 ) * 100;
            img = applycform(LAB, makecform('lab2srgb'));
    end
end

function I = LinearShading(I)
    %# create X-/Y-coordinate values for each pixel
    [h,w] = size(I);
    [X Y] = meshgrid(1:w,1:h);

    %# fit a linear plane over 3D points [X Y Z], Z is the pixel intensities
    coeff = [X(:) Y(:) ones(w*h,1)] \ I(:);

    %# compute shading plane
    shading = coeff(1).*X + coeff(2).*Y + coeff(3);

    %# subtract shading from image
    I = I - shading;

    %# normalize to the entire [0,1] range
    I = ( I - min(I(:)) ) ./ range(I(:));
end

Now lets test it on the given image:

img = im2double( imread('https://i.stack.imgur.com/JmHKJ.jpg') );
subplot(411), imshow(img)
subplot(412), imshow( correctLighting(img,'rgb') )
subplot(413), imshow( correctLighting(img,'hsv') )
subplot(414), imshow( correctLighting(img,'lab') )

enter image description here

The difference is subtle, but it might improve the results of further image processing and OCR task.


EDIT: Here is some results I obtained by applying other contrast-enhancement techniques IMADJUST, HISTEQ, ADAPTHISTEQ on the different colorspaces in the same manner as above:

enter image description here

Remember you have to fine-tune any parameter to fit your image...

Amro
  • 123,847
  • 25
  • 243
  • 454
  • thanks for your answer, but as you say the difference is very subtle and this is not helping me. the numbers still fade away when I move to binary image. do you have any more ideas? – Ofir A. Jul 05 '11 at 09:16
  • @Michael: there is not much you can do if the image is too faded to start with... Maybe try some of the other contrast-enhancements techniques available in MATLAB: `imadjust`, `histeq`, `adapthisteq`, applied on different color-spaces: RGB,HSV,Lab,.. – Amro Jul 05 '11 at 11:55
  • @Michael: I added some results from experimenting with the other methods I mentioned.. – Amro Jul 05 '11 at 12:06
  • I think that the problem here is that there is no unified illumination, and because of that some of the numbers look good and some not. do you know how to improve that? – Ofir A. Jul 05 '11 at 13:36
  • by the way I'm really appreciate your efforts to help me, thanks. – Ofir A. Jul 05 '11 at 13:38
  • 1
    @Michael: that's precisely what I tried to do first, correct the non-uniform lighting conditions by subtracting the linear shading model, although as we saw the result was moderate... Have you tried the other techniques I suggested? – Amro Jul 05 '11 at 13:42
  • yes, I tried the other techniques you suggested, but as you see in your experimenting results above it's not help me a lot. what I get is only the numbers in the sides, but all the numbers in middle fades away when I move it to binary. – Ofir A. Jul 05 '11 at 13:51
  • Im afraid I'm out of ideas. In any way, there is no such thing as a 100% accurate OCR, you are bound to miss a few difficult cases :) – Amro Jul 05 '11 at 13:55
1

It looks like your question has been more or less answered already (see d00b's comment); however, here are a few basic image processing tips that might help you here.

First, you could try a simple imadjust. This simply maps the pixel intensities to a "better" value, which often increases the contrast (making it easier to view/read). I have had a lot of success with it in my work. It is easy to use too! I think its worth a shot.

Also, this looks promising if you simply want a higher resolution image.

Enjoy the "pleasure" of image-processing in MATLAB!

Good luck,

tylerthemiler

P.S. If you are flattening the image to binary tho, you are most likely ruining the image to start with, so don't do that if you can avoid it!

tylerthemiler
  • 5,496
  • 6
  • 32
  • 40
1

As you only want to find digits (of which there are only 10), you can use cross-correlation. For this you would Fourier transform the picture of the plate. You also Fourier transform a pattern you want to match a good representation of a picture of the digit 1. Then you multiply in fourier space and inversely Fourier transform the result.

In the final cross-correlation, you will see pronounced peaks, where the pattern overlaps nicely with your image.

You do this 10 times and know where each digit is. Note that you must correct the tilt before you do the cross correlation.

This method has the advantage that you don't have to threshold your image.

There are certainly much more sophisticated algorithms in the literature for assigning number plates. One could for example use Bayes theory to estimate which digit would most likely occur (this helps a lot if you already have a databases of possible numbers).

whoplisp
  • 2,508
  • 16
  • 19