views:

144

answers:

4

How to get rid of uneven illumination from images, that contain text data, usually printed but may be handwritten? It can have some spots of lights because the light reflected while making picture. I've seen the Halcon program's segment_characters function that is doing this work perfectly, but it is not open source. I wish to convert an image to the image that has a constant illumination at background and more dark colored regions of text. So that binarization will be easy and without noise. The text is assumed to be dark colored than it's background. Any ideas?

+1  A: 

Strictly speaking, assuming you have access to the image's pixels (you can search online for how to accomplish this in your programming language as the topic is abundantly available), the exercise involves going over the pixels once to determine a "darkness threshold". In order to do this you convert each pixel from RGB to HSL in order to get the lightness level component for each pixel. During this process you calculate an average lightness for the whole image which you can use as your "darkness threshold"

Once you have the image average lightness level, you can go over the image pixels once more and if a pixel is less than the darkness threshold, set it's color to full white RGB(255,255,255), otherwise, set it's color to full black RGB (0,0,0). This will give you a binary image with in which the text should be black - the rest should be white.

Of course, the key is in finding the appropriate darkness threshold - so if the average method doesn't give you good results you may have to come up with a different method to augment that step. Such a method could involve separating the image in the primary channels Red, Green, Blue and computing the darkness threshold for each channel separately and then using the aggressive threshold of the three..

And lastly, a better approach may be to compute the light levels distribution - as opposed to simply the average - and then from that, the range around the maximum is what you want to keep. Again, go over each pixel and if it's lightness fits the band make it black, otherwise, make it white.

EDIT

For further reading about HSL I recommend starting with the Wiky entry on HSL and HSV Color spaces.

Miky Dinescu
It is interesting idea, I will try it, But sounds like finding global threshold value and thresholding using that value, Here is something different and I will try it but first impression is like it is a global threshold algorithm. So if I understood correctly do you mean that calculating the Luminance image from HSL image and finding global threshold will give me what I want?May be I am misunderstood something, sorry if so, I need a litle bit more explanation.
erjik
-1: If the lighting is uneven a global threshold will not work. Consider a gradient background from almost white at the left and almost totally black at the right: The global average will of course end up in between (some sort of gray). That means half the image will eb black and the other half white.Also, IMHO no need to go to HSL/HSV if all you are using is the luminance/chroma channel. Just convert to gray scale and use that as "light"-level.
kigurai
kigurai, I think you're a little down-vote trigger happy, don't you think? Your example is a fringe case and for such cases I suggested a more comprehensive method which would involve calculating the luminance distribution which in your case should be almost a straight line - for the gradient - with a narrow band for the color of the text.
Miky Dinescu
Extreme case or not (I don't think it is), a global threshold will have difficulties with uneven illumination without the illumination being extreme in any way. Your advice on "calculating the distribution" might sound better, but since you are still calculating a *global* distribution it is not much different from just taking the average.Sorry, I still think my -1 is accurate. :)
kigurai
A: 

If the background features are generally larger than the letters, you can try to estimate and subsequently remove the background.

There are many ways to do that, a very simple one would be to run a median filter on your image. You want the filter window to be large enough that text inside the window rarely makes up more than a third of the pixels, but small enough that there are several windows that fit into the bright spots. This filter should result in an image without text, but with background only. Subtract that from the original, and you should have an image that can be segmented with a global threshold.

Note that if the bright spots are much smaller than the text, you do the inverse: choose the filter window such that it removes the light only.

Jonas
A: 

The first thing you need to try and do it change the lighting, use a dome light or some other light that will give you a more diffuse and even light.

If that's not possible, you can try some of the ideas in this question or this one. You want to implement some type of "adaptive threshold", this will apply a local threshold to individual parts of the image so that the change in contrast won't be as noticable.

There is also a simple but effective method explained here. The simple outline of the alrithm is the following:

  1. Split the image up into NxN regions or neighbourhoods
  2. Calculate the mean or median pixel value for the neighbourhood
  3. Threshold the region based on the value calculated in 2) or the value from 2) minus C (where C is a chosen constant)
Matt Warren
+1  A: 

Have you tried using morphological techniques? Closure-by-reconstruction (as presented in Gonzalez, Woods and Eddins) can be used to create a grayscale representation of background illumination levels. You can more-or-less standardize the effective illumination by:

1) Calculating the mean intensity of all the pixels in the image

2) Using closure-by-reconstruction to estimate background illumination levels

3) Subtract the output of (2) from the original image

4) Adding the mean intensity from (1) to every pixel in the output of (3).

Basically what closure-by-reconstruction does is remove all image features that are smaller than a certain size, erasing the "foreground" (the text you want to capture) and leaving only the "background" (illumination levels) behind. Subtracting the result from the original image leaves behind only small-scale deviations (the text). Adding the original average intensity to those deviations is simply to make the text readable, so that the resulting picture looks like a light-normalized version of the original image.

estanford