Search code examples
c++image-processingpbm

Floyd Steinberg Dithering gray(pgm ascii) to black-white (pbm ascii)


I have image in pgm

enter image description here

after using this function:

void convertWithDithering(array_type& pixelgray)
{

    int oldpixel;
    int newpixel;
    int quant_error;

    for (int y = 0; y< HEIGHT-1; y++){
        for (int x = 1; x<WIDTH-1; x++){
                oldpixel = pixelgray[x][y];
                 newpixel  = (oldpixel > 128) ? 0 : 1;
                 pixelgray[x][y] = newpixel;
                  quant_error  = oldpixel - newpixel;
                 pixelgray[x+1][y]  =  pixelgray[x+1][y] + 7/16 * quant_error;
                pixelgray[x-1][y+1]  = pixelgray[x-1][y+1] + 3/16 * quant_error;
                pixelgray[x  ][y+1]=pixelgray[x  ][y+1]+  5/16 * quant_error;
                 pixelgray[x+1][y+1] = pixelgray[x+1][y+1]+ 1/16 * quant_error;
        }
    }

}

i have this

enter image description here

I want to get the same image only in black white colors


Solution

  • Last time I had a simililar smeering with a PGM file, it was because I saved data in a file opened by fopen(filename,"w");

    The file had a lot of \r\n line endings (os: windows), whereas it needed only \n. Maybe your issue is something like that. Save the file in binary format, with

    fopen(filename,"wb");

    Edit: Asides from the smeering, your implementation of Floyd–Steinberg dithering is incorrect.

    First, your error propagation should be XXX * quant_error /16 instead of XXX/16 * quant_error (which will always be equal to 0).

    Then, you are mixing up the two color spaces (0/1 and 0->255). A correct way to handle it is to always use the 0->255 space by changing to test line to

    newpixel = (oldpixel > 128) ? 255 : 0; (note that the order 255 : 0 is important, if you let 0 : 255, the algorithm won't work)

    At the end of the function, your array will be full or 0 or 255. If you want, you can iterate one more time to convert it to 0-1, but I think it is easier to do it once you record your pbm file.