views:

372

answers:

4

I implemented some adaptive binarization methods, they use a small window and at each pixel the threshold value is calculated. There are problems with these methods: If we select the window size too small we will get this effect (I think the reason is because of window size is small) alt text

At the left upper corner there is an original image, right upper corner - global threshold result. Bottom left - example of dividing image to some parts (but I am talking about analyzing image's pixel small surrounding, for example window of size 10X10). So you can see the result of such algorithms at the bottom right picture, we got a black area, but it must be white. Does anybody know how to improve an algorithm to solve this problem?

+2  A: 

There shpuld be quite a lot of research going on in this area, but unfortunately I have no good links to give.

An idea, which might work but I have not tested, is to try to estimate the lighting variations and then remove that before thresholding (which is a better term than "binarization"). The problem is then moved from adaptive thresholding to finding a good lighting model.

If you know anything about the light sources then you could of course build a model from that.

Otherwise a quick hack that might work is to apply a really heavy low pass filter to your image (blur it) and then use that as your lighting model. Then create a difference image between the original and the blurred version, and threshold that.

EDIT: After quick testing, it appears that my "quick hack" is not really going to work at all. After thinking about it I am not very surprised either :)

I = someImage
Ib = blur(I, 'a lot!')
Idiff = I - Idiff
It = threshold(Idiff, 'some global threshold')

EDIT 2 Got one other idea which could work depending on how your images are generated. Try estimating the lighting model from the first few rows in the image:

  1. Take the first N rows in the image
  2. Create a mean row from the N collected rows. You know have one row as your background model.
  3. For each row in the image subtract the background model row (the mean row).
  4. Threshold the resulting image.

Unfortunately I am at home without any good tools to test this.

kigurai
Can you explain please in more details!What is meant by "remove that before thresholding"?How to Remove?Then one more thing:Blurring a lot and taking difference and then thresholding with global threshold - what effect will it produce for good images? I mean for images that do not became damaged after adaptive threshold method?
maximus
See the update: I don't think my method could ever work. I think you'd have to resort to some more advanced method.
kigurai
Anyway, Thank you for your answer!Hope here will be more answers!
maximus
I still think your best luck is trying to find research papers that deal with lighting correction/modeling.I have one more idea, which I have updated my answer with. You could try that and see if it works.
kigurai
Very interesting idea. But how the mean row is gonna be computed? I think there are different ways of doing that! widely speaking, it depends on situation. In my case it is ok, but if we are talking about 1D barcodes then you can see this question:http://stackoverflow.com/questions/2020994/approximation-methodsIs it what you were talking about?Your approach is interesting..
maximus
For example in 1D barcode case the row analysing of noisy image will give small changes in row, and mean line of each row will contain noisy information and real information and it will be almost impossible to know which one is noise or real.But 1D barcode case is an off topic, so please don't pay much attention to it.
maximus
Ah, i forgot to make clear that my example more or less assumes a lighting model that creates a gradient from left to right.The mean row would be computed in the y-direction: that is compute the mean for each column in your NxImageWidth matrix of pixel values. That gives you a 1xImageWidth row of mean values.But as I said: this assumes a 1D lighting model (horizontal gradient).
kigurai
What about two dimensional lighting model?I will try your approach, what I have in my mind right now, is that what if the all local extremums of image are calculated, and two surfaces are contructed, first is constructed using local minimums, the second using local maximums. So the idea is to contruct two surfaces using interpolation, and then we can calculate mean surface, that should be a "threshold surface"BUT, a big problem here is how two deal with noises?There can be many false noise extremums, that spoils the whole idea.Is there any thoughts to improve my idea?
maximus
A: 

It looks like you're doing adaptive thresholding wrong. Your images look as if you divided your image into small blocks, calculated a threshold for each block and applied that threshold to the whole block. That would explain the "box" artifacts. Usually, adaptive thresholding means finding a threshold for each pixel separately, with a separate window centered around the pixel.

Another suggestion would be to build a global model for your lighting: In your sample image, I'm pretty sure you could fit a plane (in X/Y/Brightness space) to the image using least-squares, then separate the pixels into pixels brighter (foreground) and darker than that plane (background). You can then fit separate planes to the background and foreground pixels, threshold using the mean between these planes again and improve the segmentation iteratively. How well that would work in practice depends on how well your lightning can be modeled with a linear model.

If the actual objects you try to segment are "thinner" (you said something about barcodes in a comment), you could try a simple opening/closing operation the get a lighting model. (i.e. close the image to remove the foreground pixels, then use [closed image+X] as threshold).

Or, you could try mean-shift filtering to get the foreground and background pixels to the same brightness. (Personally, I'd try that one first)

nikie
+1  A: 

You have very non-uniform illumination and fairly large object (thus, no universal easy way to extract the background and correct the non-uniformity). This basically means you can not use global thresholding at all, you need adaptive thresholding.

You want to try Niblack binarization. Matlab code is available here http://www.uio.no/studier/emner/matnat/ifi/INF3300/h06/undervisningsmateriale/week-36-2006-solution.pdf (page 4). There are two parameters you'll have to tune by hand: window size (N in the above code) and weight.

AVB
A: 

Try to apply a local adaptive threshold using this procedure: 1. convolve the image with a mean or median filter 2. subtract the original image from the convolved one 3. threshold the difference image

The local adaptive threshold method selects an individual threshold for each pixel.

I'm using this approach extensively and it's working fine with images having non uniform background.

frosty