Флойд Штайнберг: от дизеринга от серого (pgm ascii) до черно-белого (pbm ascii)

У меня есть изображение в пгм

введите описание изображения здесь

после использования этой функции:

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

}

у меня есть это

введите описание изображения здесь

Я хочу получить одно и то же изображение только в черно-белых тонах

1

Решение

В прошлый раз у меня было похожее смешение с PGM-файлом, потому что я сохранил данные в файле, открытом fopen(filename,"w");

В файле было много \r\n окончания строки (os: windows), тогда как нужно было только \n, Может быть, ваша проблема что-то вроде этого. Сохраните файл в двоичном формате, с

fopen(filename,"wb");

Изменить: Помимо смешения, ваша реализация дизеринга Флойда-Стейнберга неверна.

Во-первых, ваше распространение ошибки должно быть 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. ,

2

Другие решения

Похоже, что преобразование в PBM вне этой функции делает что-то не так. Похоже, что он преобразует один пиксель PGM в несколько пикселей PBM, что приводит к эффекту «смешения». Просто дикая догадка.
Сама функция выглядит хорошо для меня, за исключением одной маленькой вещи: я думаю, из-за того, что вы используете int за все, все ваши 5/16 * quant_error будет ноль. Скорее используйте поплавки или двойники и сделайте это 5.0/16.0,

0

По вопросам рекламы [email protected]