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

В настоящее время я пытаюсь реализовать алгоритм Флойда-Стейнберга-дизеринга на 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-цветную палитру. Однако после добавления ошибки в пиксели, разве я не создаю совершенно новые цвета, которых даже не существует в палитре?

Но будет ли достаточно вернуть все изображение в цветовую палитру в конце, чтобы это сработало?

Заранее спасибо!


person Kilian    schedule 17.04.2014    source источник


Ответы (2)


Обратите внимание, что ошибка квантования добавляется только к пикселям, которые еще не сопоставлены с палитрой (квантованы)!

Это означает, что после того, как ошибка была добавлена, эти пиксели также будут сопоставлены, и их ошибка будет распространяться на другие необработанные пиксели.

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

В результате у вас не должно быть никаких пикселей за пределами палитры в конце операции квантования.

person Glenn    schedule 17.04.2014
comment
Спасибо! Это имеет большой смысл и помогло мне отлично с этим справиться. - person Kilian; 17.04.2014

Я использовал модифицированный алгоритм:

 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

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

person Mircea Melinte    schedule 16.12.2015
comment
Извините за ошибку: пурпурный: 127, 0, 127 коричневый: 0, 127, 127 - person Mircea Melinte; 16.12.2015