/* 1ch, 24bit(あるいは32bit)のパッキングカラー画像を操作するサンプルです。 以下の3種類を提示します。 - 3ch, 8bitのカラー画像に変換し、特定のチャネルのみに処理を行う。 処理を行った後、1ch, 24bit(あるいは32bit)のカラー画像に戻し、出力する。 - 3ch, 8bitのカラー画像に変換し、特定のチャネルを切り出して処理を行う。 処理を行った後、パッキングカラー画像を直接操作し、出力する。 - 1ch, 8bitのグレースケール画像に変換し、処理を行う。 */ #include "fie.h" #include "oal_aloc.h" //------------------------------------------------ // 関数プロトタイプ INT fnSMP_mul_single_color(FHANDLE hsrc, FHANDLE hdst, INT ch, DOUBLE val); INT fnSMP_edge_detection_single_color(FHANDLE hsrc, FHANDLE hdst, INT ch, DOUBLE* f_color, F_EDGE_SOBEL_PARAMS* params); INT fnSMP_binarize_packing_color_img(FHANDLE hsrc, FHANDLE hdst, DOUBLE thresh); //------------------------------------------------ // パッキングカラー画像操作の実装 /* 3ch, 8bitのカラー画像に変換して特定のチャネルのみに処理を行う例。 fnFIE_unpacking_rgb()関数により、画像をアンパッキングし、3ch, 8bitのカラー画像に変換します。 変換された画像の単一チャネルに、fnFIE_img_child_alloc_single_ch()関数を用いて子画像を割り当てます。 割り当てられた子画像に対して処理(ここでは定数valをかける演算)を行うことで、目的のチャネルのみを操作します。 演算を行った後、fnFIE_packing_rgb()関数により、画像をパッキングし、出力します。 引数: [in] hsrc 入力画像(type: F_IMG_RGBQUAD, F_IMG_RGBTRIPLE, ch: 1) [out] hdst 出力画像(type: F_IMG_RGBQUAD, F_IMG_RGBTRIPLE, ch: 1) [in] ch 目的のチャネル(0以上2以下) [in] val 倍率 戻り値: F_ERR_NONE 正常終了 F_ERR_INVALID_IMAGE 画像が不正のとき F_ERR_INVALID_PARAM パラメータ不正 F_ERR_NOMEMORY メモリ不足エラー F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー */ INT fnSMP_mul_single_color(FHANDLE hsrc, FHANDLE hdst, INT ch, DOUBLE val) { INT err; FHANDLE hsrc_unpacked = NULL; FHANDLE hdst_unpacked = NULL; FHANDLE hsrc_child = NULL; FHANDLE hdst_child = NULL; INT channels_src, channels_dst; INT type_src, type_dst; INT width_src, width_dst; INT height_src, height_dst; INT offset_x, offset_y; // 画像パラメータの取得 err = fnFIE_img_get_params(hsrc, &channels_src, &type_src, NULL, &width_src, &height_src); if (err != F_ERR_NONE) goto exit; err = fnFIE_img_get_params(hdst, &channels_dst, &type_dst, NULL, &width_dst, &height_dst); if (err != F_ERR_NONE) goto exit; // エラーチェック err = F_ERR_INVALID_IMAGE; if (channels_src != 1) goto exit; if (channels_dst != 1) goto exit; if (type_src != F_IMG_RGBQUAD && type_src != F_IMG_RGBTRIPLE) goto exit; if (type_dst != F_IMG_RGBQUAD && type_dst != F_IMG_RGBTRIPLE) goto exit; if (width_src != width_dst) goto exit; if (height_src != height_dst) goto exit; err = F_ERR_INVALID_PARAM; if (ch < 0 || 2 < ch) goto exit; // アンパッキングカラー画像の領域確保(uc8, 3ch) err = F_ERR_NOMEMORY; hsrc_unpacked = fnFIE_img_root_alloc(F_IMG_UC8, 3, width_src, height_src); if (hsrc_unpacked == NULL) goto exit; hdst_unpacked = fnFIE_img_root_alloc(F_IMG_UC8, 3, width_dst, height_dst); if (hdst_unpacked == NULL) goto exit; // 画像のアンパッキング err = fnFIE_unpacking_rgb(hsrc, hsrc_unpacked); if (err != F_ERR_NONE) goto exit; // 画像コピー err = fnFIE_img_copy(hsrc_unpacked, hdst_unpacked); if (err != F_ERR_NONE) goto exit; // 子画像の割り当て // fnFIE_img_child_alloc_single_ch()関数によって、指定したチャネルの濃淡画像を取り出すことができます。 err = F_ERR_NOMEMORY; offset_x = 0; offset_y = 0; hsrc_child = fnFIE_img_child_alloc_single_ch(hsrc_unpacked, ch, offset_x, offset_y, width_src, height_src); if (hsrc_child == NULL) goto exit; hdst_child = fnFIE_img_child_alloc_single_ch(hdst_unpacked, ch, offset_x, offset_y, width_dst, height_dst); if (hdst_child == NULL) goto exit; // 子画像で演算 err = fnFIE_img_mul_const(hsrc_child, val, hdst_child); if (err != F_ERR_NONE) goto exit; // 画像のパッキング err = fnFIE_packing_rgb(hdst_unpacked, hdst); if (err != F_ERR_NONE) goto exit; err = F_ERR_NONE; exit: // 子画像の解放 fnFIE_free_object(hsrc_child); fnFIE_free_object(hdst_child); // 画像解放 fnFIE_free_object(hsrc_unpacked); fnFIE_free_object(hdst_unpacked); return err; } /* 3ch, 8bitのカラー画像に変換し、単一チャネルの画像を切り出して処理を行う例。 この例では、特定の色成分でエッジ検出をし、入力画像にエッジ点をプロットし出力します。 fnFIE_unpacking_rgb()関数により、画像をアンパッキングし、3ch, 8bitのカラー画像に変換します。 fnFIE_img_child_alloc()関数を用いて子画像を確保し、 fnFIE_img_child_attach_single_ch()関数によって割り当て先を変更します。 割り当てられた子画像に対してエッジ検出を行います。 パッキングカラー画像に直接描画して、結果を出力します。 引数: [in] hsrc 入力画像(type: F_IMG_RGBQUAD, F_IMG_RGBTRIPLE, ch: 1) [out] hdst 出力画像(type: F_IMG_RGBQUAD, F_IMG_RGBTRIPLE, ch: 1) [in] ch 目的のチャネル [in] f_color エッジ点の描画色 [in] params エッジ検出パラメータ 戻り値: F_ERR_NONE 正常終了 F_ERR_INVALID_IMAGE 画像が不正のとき F_ERR_INVALID_PARAM パラメータ不正 F_ERR_NOMEMORY メモリ不足 F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー */ INT fnSMP_edge_detection_single_color( FHANDLE hsrc, FHANDLE hdst, INT ch, DOUBLE* f_color, F_EDGE_SOBEL_PARAMS* params) { INT err; FHANDLE hsrc_unpacked = NULL; FHANDLE hsrc_child = NULL; INT channels_src, channels_dst; INT type_src, type_dst; INT width_src, width_dst; INT height_src, height_dst; UINT feat_mode; INT border_mode; DPNT_T offset; F_DEDGE * pedges = NULL; INT edge_num; INT i; DPNT_T pnt; // 画像パラメータの取得 err = fnFIE_img_get_params(hsrc, &channels_src, &type_src, NULL, &width_src, &height_src); if (err != F_ERR_NONE) goto exit; err = fnFIE_img_get_params(hdst, &channels_dst, &type_dst, NULL, &width_dst, &height_dst); if (err != F_ERR_NONE) goto exit; // エラーチェック err = F_ERR_INVALID_IMAGE; if (channels_src != 1) goto exit; if (channels_dst != 1) goto exit; if (type_src != F_IMG_RGBQUAD && type_src != F_IMG_RGBTRIPLE) goto exit; if (type_dst != F_IMG_RGBQUAD && type_dst != F_IMG_RGBTRIPLE) goto exit; if (width_src != width_dst) goto exit; if (height_src != height_dst) goto exit; err = F_ERR_INVALID_PARAM; if (ch < 0 || 2 < ch) goto exit; if (f_color == NULL) goto exit; if (params == NULL) goto exit; // 出力画像に入力画像をコピー err = fnFIE_img_copy(hsrc, hdst); if (err != F_ERR_NONE) goto exit; // アンパッキングカラー画像の領域確保(uc8, 3ch) err = F_ERR_NOMEMORY; hsrc_unpacked = fnFIE_img_root_alloc(F_IMG_UC8, 3, width_src, height_src); if (hsrc_unpacked == NULL) goto exit; // 画像のアンパッキング err = fnFIE_unpacking_rgb(hsrc, hsrc_unpacked); if (err != F_ERR_NONE) goto exit; // 子画像の割り当て // fnFIE_img_child_alloc_single_ch()関数によって、指定したチャネルの濃淡画像を取り出すことができます。 hsrc_child = fnFIE_img_child_alloc_single_ch(hsrc_unpacked, ch, 0, 0, width_src, height_src); if (hsrc_child == NULL) goto exit; // ソーベルフィルタを利用したエッジ検出(サブピクセル精度) feat_mode = F_EDGE_FEAT_NONE; border_mode = F_BORDER_NONE; offset.x = 0.0; offset.y = 0.0; err = fnFIE_edge_sobel_subpix(hsrc_child, NULL, params, feat_mode, border_mode, offset, &pedges, &edge_num); if (err != F_ERR_NONE) goto exit; // 取得したエッジ点をプロット for (i = 0; i < edge_num; i++) { pnt.x = pedges[i].x; pnt.y = pedges[i].y; err = fnFIE_draw_point(hdst, f_color, pnt); if (err != F_ERR_NONE) goto exit; } err = F_ERR_NONE; exit: // エッジ点解放 fnOAL_free(pedges); // 子画像の解放 fnFIE_free_object(hsrc_child); // 画像解放 fnFIE_free_object(hsrc_unpacked); return err; } /* 1ch, 8bitのグレースケール画像に変換し、処理を行う例。 この例では、1chの二値画像を生成します。 fnFIE_img_rgb_to_gray()関数によって、グレースケール化を行います。 得られたグレースケール画像を指定されたしきい値によって固定しきい値二値化し、結果を出力します。 引数: [in] hsrc 入力画像(type: F_IMG_RGBQUAD, F_IMG_RGBTRIPLE, ch: 1) [out] hdst 出力画像(type: F_IMG_BIN, ch: 1) [in] thresh 二値化閾値 戻り値: F_ERR_NONE 正常終了 F_ERR_INVALID_IMAGE 画像が不正のとき F_ERR_INVALID_PARAM パラメータ不正 F_ERR_NOMEMORY メモリ不足エラー F_ERR_CALC_IMPOSSIBLE 計算ができない F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー */ INT fnSMP_binarize_packing_color_img(FHANDLE hsrc, FHANDLE hdst, DOUBLE thresh) { INT err; FHANDLE hsrc_rgbq = NULL; FHANDLE hsrc_gray = NULL; INT channels_src, channels_dst; INT type_src, type_dst; INT width_src, width_dst; INT height_src, height_dst; DOUBLE coeff_r, coeff_g, coeff_b; INT mode; // 画像パラメータの取得 err = fnFIE_img_get_params(hsrc, &channels_src, &type_src, NULL, &width_src, &height_src); if (err != F_ERR_NONE) goto exit; err = fnFIE_img_get_params(hdst, &channels_dst, &type_dst, NULL, &width_dst, &height_dst); if (err != F_ERR_NONE) goto exit; // エラーチェック err = F_ERR_INVALID_IMAGE; if (channels_src != 1) goto exit; if (channels_dst != 1) goto exit; if (type_src != F_IMG_RGBQUAD && type_src != F_IMG_RGBTRIPLE) goto exit; if (type_dst != F_IMG_BIN) goto exit; if (width_src != width_dst) goto exit; if (height_src != height_dst) goto exit; // fnFIE_img_rgb_to_gray()関数は F_IMG_RGBTRIPLE に非対応なので、 // F_IMG_RGBQUAD の画像に入力画像をコピーしておく if (type_src == F_IMG_RGBTRIPLE) { err = F_ERR_NOMEMORY; hsrc_rgbq = fnFIE_img_root_alloc(F_IMG_RGBQUAD, 1, width_src, height_src); if (hsrc_rgbq == NULL) goto exit; err = fnFIE_img_copy(hsrc, hsrc_rgbq); if (err != F_ERR_NONE) goto exit; hsrc = hsrc_rgbq; } // グレースケール画像の領域確保 err = F_ERR_NOMEMORY; hsrc_gray = fnFIE_img_root_alloc(F_IMG_UC8, 1, width_src, height_src); if (hsrc_gray == NULL) goto exit; // グレースケール化 coeff_r = 0.299; coeff_g = 0.587; coeff_b = 0.114; mode = 0; err = fnFIE_img_rgb_to_gray(hsrc, hsrc_gray, coeff_r, coeff_g, coeff_b, mode); if (err != F_ERR_NONE) goto exit; // 二値化 err = fnFIE_binarize(hsrc_gray, hdst, thresh); if (err != F_ERR_NONE) goto exit; err = F_ERR_NONE; exit: // 画像解放 fnFIE_free_object(hsrc_rgbq); fnFIE_free_object(hsrc_gray); return err; } /* 24bit(あるいは32bit)パッキングカラー画像を操作する実行サンプル関数。 パッキングカラー画像のファイルを読込み、出力画像をファイルに保存します。 */ INT execute() { INT err; FHANDLE hsrc = NULL; FHANDLE hdst_amp_r = NULL; FHANDLE hdst_edge = NULL; FHANDLE hdst_bin = NULL; INT width, height; INT channels; INT ch; DOUBLE val; DOUBLE f_color[3] = {0, 0, 0}; DOUBLE thresh; // エッジ検出パラメータ F_EDGE_SOBEL_PARAMS params; // 1ch, 24bit(あるいは32bit)カラー画像の読込 // 適当な画像を指定してください err = fnFIE_load_png("test.png", &hsrc, F_COLOR_IMG_TYPE_RGBQ); if (err != F_ERR_NONE) goto exit; // 画像の幅と高さの取得 err = fnFIE_img_get_params(hsrc, NULL, NULL, NULL, &width, &height); if (err != F_ERR_NONE) goto exit; // 出力画像の領域確保 err = F_ERR_NOMEMORY; channels = 1; hdst_amp_r = fnFIE_img_root_alloc(F_IMG_RGBQUAD, channels, width, height); if (hdst_amp_r == NULL) goto exit; hdst_edge = fnFIE_img_root_alloc(F_IMG_RGBQUAD, channels, width, height); if (hdst_edge == NULL) goto exit; hdst_bin = fnFIE_img_root_alloc(F_IMG_BIN, channels, width, height); if (hdst_bin == NULL) goto exit; // 赤成分のみを2倍する ch = 0; val = 2; err = fnSMP_mul_single_color(hsrc, hdst_amp_r, ch, val); if (err != F_ERR_NONE) goto exit; // 緑成分のエッジ検出し、元画像にエッジをプロットしたものを出力する params.mag_threshold = 40; // 強度しきい値 params.nms_length = 1; // 非極大抑制のフィルタ片幅 ch = 1; f_color[1] = UC8_MAX; err = fnSMP_edge_detection_single_color(hsrc, hdst_edge, ch, f_color, ¶ms); if (err != F_ERR_NONE) goto exit; // 1ch二値画像にする thresh = 128; err = fnSMP_binarize_packing_color_img(hsrc, hdst_bin, thresh); if (err != F_ERR_NONE) goto exit; // 画像保存 // 適当にファイル名を指定してください err = fnFIE_save_png("result_amp_r.png", hdst_amp_r, -1); if (err != F_ERR_NONE) goto exit; err = fnFIE_save_png("result_edge.png", hdst_edge, -1); if (err != F_ERR_NONE) goto exit; err = fnFIE_save_png("result_bin.png", hdst_bin, -1); if (err != F_ERR_NONE) goto exit; err = F_ERR_NONE; exit: // 画像解放 fnFIE_free_object(hsrc); fnFIE_free_object(hdst_amp_r); fnFIE_free_object(hdst_edge); fnFIE_free_object(hdst_bin); return err; } INT main() { INT err; // ライブラリのセットアップ fnFIE_setup(); err = execute(); // ライブラリの終了処理 fnFIE_teardown(); return err; }