Floyd Steinberg抖动灰色(pgm ascii)到黑白色(pbm ascii)

时间:2013-11-19 10:03:54

标签: c++ image-processing pbm

我在pgm中有图片

enter image description here

使用此功能后:

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;
        }
    }

}

我有这个

enter image description here

我想仅以黑白色获得相同的图像

2 个答案:

答案 0 :(得分:2)

上次我对PGM文件进行了类似的玷污,这是因为我将数据保存在由fopen(filename,"w");打开的文件中

该文件有很多\r\n行结尾(os:windows),而它只需要\n。也许你的问题是那样的。使用

以二进制格式保存文件

fopen(filename,"wb");

编辑:除了嗅觉,你的Floyd-Steinberg抖动的实现是不正确的。

首先,您的错误传播应该是XXX * quant_error /16而不是XXX/16 * quant_error(始终等于0)。

然后,您正在混合两个颜色空间(0/1和0-> 255)。处理它的正确方法是通过将测试行更改为

来始终使用0-> 255空格

newpixel = (oldpixel > 128) ? 255 : 0; (请注意,订单255 : 0很重要,如果您允许0 : 255,则该算法将无效)

在函数结束时,你的数组将是满的或0或255.如果你愿意,你可以再迭代一次将它转换为0-1,但我认为一旦你记录它就更容易做到你的pbm文件。

答案 1 :(得分:0)

看起来在此函数之外转换为PBM做错了。看起来它正在将一个PGM像素转换为几个PBM像素,这会产生这种“嗅觉”效果。只是一个狂野的猜测。 除了一件小事之外,函数本身对我来说没问题:我认为由于你使用int来处理所有事情,所有5/16 * quant_error都将为零。而是使用浮点数或双精度数并使其成为5.0/16.0