// グレイスケール画像をFFTを使って拡大するプログラム // プログラム名:enlarge_by_fft.cpp #include "eps-header.hh" #include "fft-header.hh" // 元画像(src)をFFTを使って拡大し処理済画像(dst)に入れる関数 void enlarge( class image& src, // 元画像クラス(入力) class image& dst, // 処理済画像クラス(出力) int times) // 拡大倍率 (2のべき乗) { if (src.p == NULL) { printf("元画像がありません。"); return; } printf("\nFFTを使って画像を拡大します。\n"); printf("拡大率:%d倍\n", times); int src_nr_lines = src.get_nr_lines(); // 元画像のライン数 (縦の画素数) int src_nr_pixels = src.get_nr_pixels(); // 元画像のピクセル数 (横の画素数) int dst_nr_lines = src_nr_lines * times; // 処理済画像のライン数 int dst_nr_pixels = src_nr_pixels * times; // 処理済画像のピクセル数 dst.gmake(dst_nr_lines, dst_nr_pixels); // 処理済画像の配列を確保 class fourier src_ft(src_nr_lines, src_nr_pixels); // 元画像用高速フーリエ変換クラスの宣言 // 実数部を元画像の輝度値,虚数部を0.0とする複素数を2次元配列に入れる。 for (int iy = 0; iy < src_nr_lines; iy ++) { for (int ix = 0; ix < src_nr_pixels; ix ++) { src_ft.p[iy][ix] = creal8((double)src.p[iy][ix], 0.0); } } src_ft.Forward_FFT(); // 2次元高速フーリエ変換 class fourier dst_ft(dst_nr_lines, dst_nr_pixels); // 処理済画像用高速フーリエ変換クラスの宣言 // 既に2次元複素数配列はゼロに初期化されている。 dst_ft.set_complex_type(COMPLEX_FREQ); // 周波数領域のデータとする。 for (int iy = 0; iy < src_nr_lines / 2; iy ++) { for (int ix = 0; ix < src_nr_pixels / 2; ix ++) { dst_ft.p[iy][ix] = src_ft.p[iy][ix]; } for (int ix = src_nr_pixels / 2; ix < src_nr_pixels; ix ++) { dst_ft.p[iy][ix + dst_nr_pixels - src_nr_pixels] = src_ft.p[iy][ix]; } } for (int iy = src_nr_lines / 2; iy < src_nr_lines; iy ++) { for (int ix = 0; ix < src_nr_pixels / 2; ix ++) { dst_ft.p[iy + dst_nr_lines - src_nr_lines][ix] = src_ft.p[iy][ix]; } for (int ix = src_nr_pixels / 2; ix < src_nr_pixels; ix ++) { dst_ft.p[iy + dst_nr_lines - src_nr_lines][ix + dst_nr_pixels - src_nr_pixels] = src_ft.p[iy][ix]; } } dst_ft.Backward_FFT(); // 2次元高速フーリエ逆変換 for (int iy = 0; iy < dst_nr_lines; iy ++) { for (int ix = 0; ix < dst_nr_pixels; ix ++) { dst_ft.p[iy][ix] /= ((double)src_nr_lines * (double)src_nr_pixels); } } for (int iy = 0; iy < dst_nr_lines; iy ++) { for (int ix = 0; ix < dst_nr_pixels; ix ++) { double pp = sqrt(norm(dst_ft.p[iy][ix])); if (pp >= (double)MAX_GRAY_LEVEL) pp = (double)MAX_GRAY_LEVEL; if (pp <= (double)MIN_GRAY_LEVEL) pp = (double)MIN_GRAY_LEVEL; dst.p[iy][ix] = (int)(pp + 0.5); } } } // プログラムの開始位置 int main() { class image src; // 元画像クラスを宣言 class image dst; // 処理済画像クラスを宣言 src.gload(); // 元画像をBMPファイルから読み込む // BMPファイルを指定したい場合は, // src.gload("パス付きBMPファイル名"); // とする。 // 元画像(src)をFFTを使って拡大し処理済画像(dst)に入れる enlarge( src, // 元画像クラス(入力) dst, // 処理済画像クラス(出力) 2); // 拡大倍率 (2のべき乗) dst.gsave(); // 処理済画像をBMPファイルに保存する // BMPファイルを指定したい場合は, // dst.gsave("パス付きBMPファイル名"); // とする。 }