コンテンツにスキップ

SingleImage + ROI デコード

GbE-2 から 1 フレームの圧縮データを取得し、コールバック関数を使わずに指定した領域(ROI: Region of Interest)だけをピンポイントで復号して、PGM形式(Portable Graymap)で保存するプログラムの作成手順です。

  1. ソースコードの記述

    メインファイル(GbE2_SingleImage_ROI.cpp など)を開き、以下のコードに書き換えます。

    #include <stdio.h>
    #include <stdlib.h>
    #include <PUCLIB.h> // PUCLIB ヘッダーの読み込み
    int main() {
    printf("INFINICAM GbE-2 ROIデコード処理開始...\n");
    // 1. SDKの初期化
    PUCRESULT ret = PUC_Initialize();
    if (ret != PUC_SUCCEEDED) {
    printf("エラー: SDKの初期化に失敗しました。ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 2. ネットワーク上の GbE-2 デバイスを検索
    PUC_DETECT_FILTER filter = { 0 };
    filter.nDeviceTypeFlags = PUC_DETECT_TARGET_HAWK; // GbE-2 を指定
    PUC_DETECT_INFO detectInfo = { 0 };
    ret = PUC_DetectDevice2(&filter, &detectInfo);
    if (ret != PUC_SUCCEEDED || detectInfo.nDeviceCount == 0) {
    printf("エラー: GbE-2 カメラが見つかりませんでした。ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 3. 検出した最初のデバイスをオープン
    PUC_HANDLE hDevice = NULL;
    ret = PUC_OpenDevice2(0, &hDevice);
    if (ret != PUC_SUCCEEDED) {
    printf("エラー: デバイスのオープンに失敗しました。ErrorCode: %d\n", ret);
    return EXIT_FAILURE;
    }
    // 4. 全体画像の解像度と量子化テーブルの取得
    UINT32 fullWidth = 0, fullHeight = 0;
    PUC_GetResolution(hDevice, &fullWidth, &fullHeight);
    unsigned short qVals[PUC_Q_COUNT] = { 0 };
    PUC_GetQuantization2(hDevice, qVals);
    printf("全体解像度: %u x %u ピクセル\n", fullWidth, fullHeight);
    // 5. ROI(関心領域)パラメータの設定
    // ※8x8ブロック単位で圧縮されているため、座標・サイズは必ず 8 の倍数で指定します
    UINT32 roiX = 200; // 復号開始 X 座標 (0 または 8の倍数)
    UINT32 roiY = 150; // 復号開始 Y 座標 (0 または 8の倍数)
    UINT32 roiWidth = 400; // ROI の幅 (8の倍数)
    UINT32 roiHeight = 300; // ROI の高さ (8の倍数)
    printf("ROI設定: 位置(%u, %u), サイズ %u x %u ピクセル\n", roiX, roiY, roiWidth, roiHeight);
    // 6. 転送データサイズの取得とバッファの確保
    UINT32 xferDataSize = 0;
    PUC_GetXferDataSize(hDevice, &xferDataSize);
    // 全体圧縮データ用バッファの確保
    unsigned char* pCompressedBuffer = (unsigned char*)malloc(xferDataSize);
    // ROI 復号データ用バッファの確保(切り出す ROI サイズ分のみ確保)
    UINT32 roiLineBytes = (roiWidth + 3) & ~3; // 4バイト境界に整列
    unsigned long roiDecodedSize = (unsigned long)roiLineBytes * roiHeight;
    unsigned char* pRoiDecodedBuffer = (unsigned char*)malloc(roiDecodedSize);
    if (pCompressedBuffer == NULL || pRoiDecodedBuffer == NULL) {
    printf("エラー: メモリ割り当てに失敗しました。\n");
    free(pCompressedBuffer);
    free(pRoiDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_FAILURE;
    }
    // 7. 1フレーム分の圧縮データをキャプチャ
    PUC_XFER_DATA_INFO xferDataInfo = { 0 };
    xferDataInfo.pData = pCompressedBuffer;
    xferDataInfo.nDataSize = xferDataSize;
    printf("キャプチャ実行中...\n");
    ret = PUC_GetSingleXferData(hDevice, &xferDataInfo);
    if (ret == PUC_SUCCEEDED) {
    // 8. 指定した ROI 領域のみを復号
    // nX, nY で切り出し位置、nWidth, nHeight で復号サイズを指定します
    ret = PUC_DecodeData(
    pRoiDecodedBuffer, // [out] ROI復号データの出力先
    roiX, roiY, // [in] 復号開始座標 (8の倍数)
    roiWidth, roiHeight,// [in] 復号する幅と高さ (8の倍数)
    roiLineBytes, // [in] 出力バッファの1行あたりバイト数
    pCompressedBuffer, // [in] キャプチャした圧縮データ
    qVals // [in] 量子化テーブル
    );
    if (ret == PUC_SUCCEEDED) {
    // 9. 復号した ROI 画像を PGM (P5) フォーマットで保存
    const char* filename = "roi_captured_image.pgm";
    FILE* fp = NULL;
    if (fopen_s(&fp, filename, "wb") == 0 && fp != NULL) {
    // PGM ヘッダーの書き込み(幅・高さには ROI のサイズを指定)
    fprintf(fp, "P5\n%u %u\n255\n", roiWidth, roiHeight);
    // 有効画像データ部分を 1 行ずつ書き込み
    for (UINT32 y = 0; y < roiHeight; y++) {
    fwrite(pRoiDecodedBuffer + (y * roiLineBytes), sizeof(unsigned char), roiWidth, fp);
    }
    fclose(fp);
    printf("SUCCESS: ROI切り出し画像 (PGM) を保存しました (%s)\n", filename);
    } else {
    printf("エラー: ファイルの保存に失敗しました。\n");
    }
    } else {
    printf("エラー: ROI復号処理に失敗しました。ErrorCode: %d\n", ret);
    }
    } else {
    printf("エラー: 画像データの取得に失敗しました。ErrorCode: %d\n", ret);
    }
    // 10. メモリ解放とデバイスのクローズ
    free(pCompressedBuffer);
    free(pRoiDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_SUCCESS;
    }
  2. ビルドと実行

    1. Ctrl + Shift + B でビルドします。
    2. Ctrl + F5 で実行します。
    3. 実行ディレクトリ内に 400x300 ピクセルの切り出し画像 roi_captured_image.pgm が出力されていれば成功です。

ROI デコードのメリットと設定ルール

Section titled “ROI デコードのメリットと設定ルール”

処理速度とメモリ使用量の削減

Section titled “処理速度とメモリ使用量の削減”

画像全体のデコードを行わず、必要な領域のみをピンポイントで復号するため、計算コスト(CPU負荷)を大幅に削減できます。関心のある領域だけを高速に解析・保存したいアプリケーションに最適です。