このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
誤差拡散法の中でも、非常によく使われている配列に、
Floyd-Stein 法というものがある。
誤差拡散のアルゴリズムや誤差配列には様々な方法があるが、
この方法は計算速度が速い割りに精度が高い。
これは、以下のような比率で差分値を分散する。
×××
×■7
351
つまり、差分値の 7/16 を右へ、3/16 を左下へ、
5/16 を下へ、1/16 を右下へ割り振る計算である。
実装は昨日とほとんど変わらないため割愛する。
これだけでは短いので、番外編的な 2 値化を紹介しよう。
それは「ランダム 2 値化」だ。
方法は単純で、ピクセルごとに閾値をランダムで決める。
乱数処理が入るので、処理ごとに結果が異なる事となる。
ランダムなので、品質は高いとはいえないが、
ランダム処理がノイズのような役割を果たすため、
大き目の画像に対して処理をすると面白い。
# BMP 読み込み。
my $data = read_bmp;
foreach my $line (@$data) {
foreach my $pixel (@$line) {
my ($red, $green, $blue) = unpack_rgb($pixel);
no integer;
# 明度を求める。(0~255)
$pixel = $red * 0.299 + $green * 0.587 + $blue * 0.114;
# ランダムな閾値で白か黒に。
$pixel = $pixel > rand() * 255 ? 1 : 0;
}
}
# カラーテーブルを定義。0 = 黒、1 = 白。
my @colors = (0x00000000, 0x00ffffff);
# 白黒の BMP を書き出す。
write_bmp($data, 1, \@colors);
さて、白黒 2 値化だけで何日かやってきたが、
これらの考え方は減色処理の基本となる。
また、例示したコードは最適化の余地が十分残されている。
例えば、昨日の誤差分散のコードでは、
差分値を切り捨てているので、
積み重なる端数が無視される結果となっている。
それを修正すれば、若干品質が上がる可能性はある。
今回は Perl を使っているため、
処理速度的には他の言語に劣るが、
基本的な考え方が分かれば、他の言語で表現するのは
それほど難しくはないはずだ。
また、2 値化には他にも色々な方法があるので、
ぜひともそれらを試してみてほしい。
例えば、Jarvis-Judice-Ninke 法というのも、
なかなか有名な配列である。