// グレイスケール画像のヒストグラムをグラフ化した画像を作成するプログラム // プログラム名:histogram.cpp #include "eps-header.hh" // 元画像(src)の輝度値のヒストグラムをグラフを処理済画像(dst)に入れる関数 void histogram_img( class image& src, // 元画像クラス(入力) class image& dst, // 処理済画像クラス(出力) int nr_lines_of_histogram) // ヒストグラムのグラフの縦方向の大きさ(入力) { if (src.p == NULL) { printf("元画像がありません。"); return; } printf("\n画像のヒストグラムを作成します。\n"); int nr_lines = src.get_nr_lines(); // 元画像のライン数 (縦の画素数) int nr_pixels = src.get_nr_pixels(); // 元画像のピクセル数 (横の画素数) dst.gmake(nr_lines_of_histogram, NR_GRAY_LEVEL); // 処理済画像の配列を確保 long int hist[NR_GRAY_LEVEL]; // ヒストグラムの頻度 // 元画像のヒストグラムの頻度を計数する。 for (int ia = 0; ia < NR_GRAY_LEVEL; ia ++) { hist[ia] = 0; } for (int iy = 0; iy < nr_lines; iy ++) { for (int ix = 0; ix < nr_pixels; ix ++) { hist[ src.p[iy][ix] ] ++; } } // グラフの縦方向のスケーリングをするためにヒストグラムの最大値を求める。 long int max_hist = hist[0]; // ヒストグラムの最大値 for (int ia = 0; ia < NR_GRAY_LEVEL; ia ++) { if (max_hist < hist[ia]) { max_hist = hist[ia]; } } // 処理済画像をクリアする。 for (int iy = 0; iy < nr_lines_of_histogram; iy ++) { for (int ix = 0; ix < NR_GRAY_LEVEL; ix ++) { dst.p[iy][ix] = MIN_GRAY_LEVEL; } } // グラフを画像化し処理済画像に縦棒を描画する。 double scaling = (double)nr_lines_of_histogram / (double)max_hist; int len_hist; for (int ix = 0; ix < NR_GRAY_LEVEL; ix ++) { len_hist = (int)(scaling * hist[ix]); for (int iy = 0; iy < len_hist; iy ++) { dst.p[nr_lines_of_histogram - (iy + 1)][ix] = MAX_GRAY_LEVEL; } } } // プログラムの開始位置 int main() { class image src; // 元画像クラスを宣言 class image dst; // 処理済画像クラスを宣言 src.gload(); // 元画像をBMPファイルから読み込む // BMPファイルを指定したい場合は, // src.gload("パス付きBMPファイル名"); // とする。 // 元画像(src)の輝度値のヒストグラムをグラフを処理済画像(dst)に入れる。 histogram_img( src, // 元画像クラス(入力) dst, // 処理済画像クラス(出力) 256); // ヒストグラムのグラフの縦方向の大きさ(入力) dst.gsave(); // 処理済画像をBMPファイルに保存する // BMPファイルを指定したい場合は, // dst.gsave("パス付きBMPファイル名"); // とする。 }