// グレイスケール画像を誤差拡散法によって2値化した画像を作成するプログラム // 誤差分散の配分 ただし,画像外に誤差分散しない。 // +----------+----------+ // | 注目画素 | 3 / 8 | // +----------+----------+ // | 3 / 8 | 2 / 8 | // +----------+----------+ // // プログラム名:dither_err1.cpp #include "eps-header.hh" // 元画像(src)を誤差拡散法によって2値化した処理済画像(dst)を作成する関数 void dither_err1( class image& src, // 元画像クラス(入力) class image& dst) // 処理済画像クラス(出力) { if (src.p == NULL) { printf("元画像がありません。"); return; } printf("\n誤差拡散法によって2値化します。\n"); printf(" 誤差分散の配分 ただし,画像外に誤差分散しない。\n"); printf(" +----------+----------+\n"); printf(" | 注目画素 | 3 / 8 |\n"); printf(" +----------+----------+\n"); printf(" | 3 / 8 | 2 / 8 |\n"); printf(" +----------+----------+\n"); int nr_lines = src.get_nr_lines(); // 元画像のライン数 (縦の画素数) int nr_pixels = src.get_nr_pixels(); // 元画像のピクセル数 (横の画素数) dst.gmake(nr_lines, nr_pixels); // 処理済画像の配列を確保 // 画素値はゼロにクリアされる。 double * err_buf[2]; // 誤差拡散用の2ライン分の配列を確保 err_buf[0] = new double [nr_pixels]; err_buf[1] = new double [nr_pixels]; for (int ix = 0; ix < nr_pixels; ix ++) { err_buf[0][ix] = 0.0; err_buf[1][ix] = 0.0; } for (int iy = 0; iy < nr_lines; iy ++) { for (int ix = 0; ix < nr_pixels; ix ++) { int a = src.p[iy][ix]; // 近傍が画像の外に出るときは,単純に2値化する。 if (iy == nr_lines - 1 || ix == nr_pixels - 1) { if (a > MAX_GRAY_LEVEL / 2) { dst.p[iy][ix] = MAX_GRAY_LEVEL; } } else { double gray = a + err_buf[0][ix]; double err1 = gray - MIN_GRAY_LEVEL; double err2 = gray - MAX_GRAY_LEVEL; double err3; if (fabs(err1) < fabs(err2)) { // dst.p[iy][ix] = 0; // 処理済画像は,すでにゼロにクリアされている。 err3 = err1; } else { dst.p[iy][ix] = MAX_GRAY_LEVEL; err3 = err2; } // 近傍に応じて誤差拡散値をバッファに記録する。 err_buf[0][ix + 1] += (3.0 / 8.0) * err3; err_buf[1][ix ] += (3.0 / 8.0) * err3; err_buf[1][ix + 1] += (2.0 / 8.0) * err3; } } for (int ix = 0; ix < nr_pixels; ix ++) { err_buf[0][ix] = err_buf[1][ix]; err_buf[1][ix] = 0.0; } } delete [] err_buf[0]; delete [] err_buf[1]; } // プログラムの開始位置 int main() { class image src; // 元画像クラスを宣言 class image dst; // 処理済画像クラスを宣言 src.gload(); // 元画像をBMPファイルから読み込む // BMPファイルを指定したい場合は, // src.gload("パス付きBMPファイル名"); // とする。 // 元画像(src)を誤差拡散法によって2値化した処理済画像(dst)を作成する。 dither_err1( src, // 元画像クラス(入力) dst); // 処理済画像クラス(出力) dst.gsave(); // 処理済画像をBMPファイルに保存する // BMPファイルを指定したい場合は, // dst.gsave("パス付きBMPファイル名"); // とする。 }