Как может работать Флойд-Штайнберг-Дизеринг?
В настоящее время я пытаюсь реализовать алгоритм Флойда-Штейнберга-Дизеринга в Java. После нескольких неудачных попыток я наткнулся на вопрос после прочтения псевдокода, указанного в Википедии.
for each y from top to bottom
for each x from left to right
oldpixel := pixel[x][y]
newpixel := find_closest_palette_color(oldpixel)
pixel[x][y] := newpixel
quant_error := oldpixel - newpixel
pixel[x+1][y ] := pixel[x+1][y ] + 7/16 * quant_error
pixel[x-1][y+1] := pixel[x-1][y+1] + 3/16 * quant_error
pixel[x ][y+1] := pixel[x ][y+1] + 5/16 * quant_error
pixel[x+1][y+1] := pixel[x+1][y+1] + 1/16 * quant_error
То, что я пытаюсь достичь, это сжатие изображения в 16 цветовой палитре. Однако после добавления ошибки в пиксели я не создаю совершенно новые цвета, которых даже нет в палитре?
Но достаточно ли заставить эту работу вернуть все изображение обратно в цветовую палитру в конце?
Заранее спасибо!
2 ответа
Обратите внимание, что квантовая ошибка добавляется только к пикселям, которые еще не были сопоставлены с палитрой (квантована)!
Это означает, что после добавления ошибки эти пиксели также будут отображаться, и их ошибка распространяется дальше на другие необработанные пиксели.
В конце алгоритма каждый пиксель будет сопоставлен, а последняя оставшаяся ошибка будет отброшена.
В результате у вас не должно быть пикселей вне палитры в конце операции квантования.
Я использовал модифицированный алгоритм:
for each y from 0 to ImageHeight-1
for each x from 1 to ImageWidth-1
oldpixel := pixel[x][y]
newpixel := find_closest_palette_color(oldpixel)
pixel[x][y] := newpixel
quant_error := oldpixel - newpixel
pixel[x+1][y ] := pixel[x+1][y ] + 7/16 * quant_error
pixel[x-1][y+1] := pixel[x-1][y+1] + 3/16 * quant_error
pixel[x ][y+1] := pixel[x ][y+1] + 5/16 * quant_error
pixel[x+1][y+1] := pixel[x+1][y+1] + 1/16 * quant_error
and i have used this 16 colors palette:
**B G R**
black: 0, 0, 0
blue: 127, 0, 0
green: 0, 127, 0
cyan: 127, 127, 0
red: 0, 0, 127
magenta: 127, 0, 0
brown: 127, 0, 127
gray: 191, 191, 191
dark gray: 63, 63, 63
light blue: 255, 0, 0
light green: 0, 255, 0
light cyan: 255, 255, 0
light red: 0, 0, 255
pink: 255, 0, 255
yellow: 0, 255, 255
white: 255, 255, 255
Результат был лучше с этой палитрой, без серпантинного сканирования, как рекомендовано в Википедии.