画像操作 実装例
[サンプルコード一覧]


画像のPack/Unpack/チャネル統合/結合/分割

/*
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, &params);
    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;
}


Documentation copyright © 2009-2024 FAST Corporation.
Generated on Fri Aug 9 16:38:48 2024 for FIEライブラリ by doxygen 1.5.6-FASTSP-p2