Grayscale to binary image conversion

This topic is 3783 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello, I searched quite a lot but I haven't found any dtailed information about how to transform a grayscale image into binary image that looks as much the same as possible. I found some implementations but none of them seemed to work fine. For example, when the input is a 64x64 bitmap with all pixels at 0.5 I want to output a checker, which is the nearest to the original (what I got from the methods I found was all black or all white). I developed a texture-compression-like approach where I pass the image with a sub-frame of, for example, 4 by 4 pixels (Initially all pixels in the uotput are black). In such a frame, I add values of all pixels and round it to integer (let's call it N). N is the number of pixels in the frame that has to be white in the output. So i make the corresponding pixel which has the maxmum value white and decrease N, and repeat this until N is 0. Seems logical to me, but when the input is all pixels 0.5, the output is horizontal black and white lines instead of a checker. What would be a better and all-purpose algorithm to convert grayscale into binary image?

Share on other sites
Check out error diffusion.

Share on other sites
There is also Dithering

Share on other sites
Thanks, that helped a lot!

But I'm not sure about following thing:

in error diffusion, I compare each pixel in the input to a 0.5 value and set it 1.0 or 0.0 and then diffuse the error (let's say the Floyd-Steinberg way), but this won't give me the binary values, so do I make the comparison to 0.5 (or some other threshold) again?

Share on other sites
I am no expert but are you sure you have to compare it to 0.5? Have you looked at the pseudo code example here: Floyd-Steinberg Dithering

Share on other sites
I guess that is what I should do, as it is in that pseudocode:

newpixel := find_closest_palette_color(oldpixel)

because my palette is only black (0.0) and white (1.0), I find nearest color by comparing the value to 0.5

wonder why the Floys-Steinberg method has different distribution matrices in different articles...

Oh, And I've answered my previous question myself, so it's out-of-date.

Share on other sites
Quote:
 I compare each pixel in the input to a 0.5 value and set it 1.0 or 0.0 and then diffuse the error (let's say the Floyd-Steinberg way), but this won't give me the binary values, so do I make the comparison to 0.5 (or some other threshold) again?

After reading a bit more I now understand what you are saying. What you are doing is thresholding the current pixel to 0 or 1 and dispersing the error to the neighbouring pixels. When you go the x+1 pixel that value is no longer 0.5, its 0.5 + error, so you threshold that pixel and add the error to the surrounding pixels again and so on.
I found these notes better at explaining things than just the pseudo code:
Floyd-Steinberg Dithering
I managed to get my own implementation going that converted this 32 bit gray scale image:

To a 1 bit binary image

Basically using this code
for (int y = 1; y < height-1; y++) {		offset =y*width;		for (int x=1; x < width-1; x++) {			pos = offset + x;			//oldpixel := pixel[x][y]			oldPixel = pixels[pos];			//newpixel := find_closest_palette_color(oldpixel)			newPixel = (oldPixel >= 0.5)?1.0f : 0.0f;			//pixel[x][y] := newpixel			pixels[pos] = newPixel ;			//quant_error := oldpixel - newpixel			quant_error = oldPixel - newPixel;			//pixel[x+1][y] := pixel[x+1][y] + 7/16 * quant_error			pixels[pos + 1] += 7.0f/16.0f * quant_error;						//pixel[x-1][y+1] := pixel[x-1][y+1] + 3/16 * quant_error			pixels[pos - 1 + width] += 3.0f/16.0f * quant_error;			//pixel[x][y+1] := pixel[x][y+1] + 5/16 * quant_error			pixels[pos + width] += 5.0f/16.0f * quant_error;			//pixel[x+1][y+1] := pixel[x+1][y+1] + 1/16 * quant_error			pixels[pos + 1 + width] += 1.0f/16.0f * quant_error;		}	}

Although apparently you are suppose to go in a zig zag motion rather than a left to right motion that I did. Not really sure why but hope that helps.

Share on other sites
4fingers, have you changed anything since you wrote your post?

The image looks much better than the original I saw, that one had some bad artifacts... I'm not sure if it's a different image or is it that I'm viewing it on some other machine.

Share on other sites
Nope haven't changed anything, maybe you were on a different resolution?

Share on other sites
Yes, and it was LCD and now I'm viewing it on my CRT and it's what it was, a huge difference though. I'll be coding this today or tomorrow so I'll post what I've managed to do.

1. 1
2. 2
3. 3
Rutin
18
4. 4
5. 5
JoeJ
13

• 9
• 14
• 10
• 25
• 9
• Forum Statistics

• Total Topics
632644
• Total Posts
3007625
• Who's Online (See full list)

There are no registered users currently online

×