Как может работать Флойд-Штайнберг-Дизеринг?

В настоящее время я пытаюсь реализовать алгоритм Флойда-Штейнберга-Дизеринга в 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

Результат был лучше с этой палитрой, без серпантинного сканирования, как рекомендовано в Википедии.

Другие вопросы по тегам