コンテンツにスキップ

SingleImage + DC成分抽出

GbE-2 から 1 フレームの圧縮データを取得し、DC成分(各 8×8 ブロックの平均輝度)のみを取り出して復号することで、縦横 1/8 サイズの軽量プレビュー画像を高速に生成し、PGM形式(Portable Graymap)で保存するプログラムの作成手順です。

  1. ソースコードの記述

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

    #include <stdio.h>
    #include <stdlib.h>
    #include <PUCLIB.h> // PUCLIB ヘッダーの読み込み
    int main() {
    printf("INFINICAM GbE-2 DC成分抽出処理開始...\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);
    printf("全体解像度: %u x %u ピクセル\n", fullWidth, fullHeight);
    // 5. DC成分画像のサイズ計算(縦横 1/8 のブロックサイズになります)
    UINT32 dcWidth = fullWidth / 8;
    UINT32 dcHeight = fullHeight / 8;
    printf("DC画像解像度 (1/8縮小): %u x %u ピクセル\n", dcWidth, dcHeight);
    // 6. 転送データサイズの取得とバッファの確保
    UINT32 xferDataSize = 0;
    PUC_GetXferDataSize(hDevice, &xferDataSize);
    // 全体圧縮データ用バッファの確保
    unsigned char* pCompressedBuffer = (unsigned char*)malloc(xferDataSize);
    // DC復号データ用バッファの確保(1/64 の画素サイズで十分です)
    unsigned long dcDecodedSize = (unsigned long)dcWidth * dcHeight;
    unsigned char* pDcDecodedBuffer = (unsigned char*)malloc(dcDecodedSize);
    if (pCompressedBuffer == NULL || pDcDecodedBuffer == NULL) {
    printf("エラー: メモリ割り当てに失敗しました。\n");
    free(pCompressedBuffer);
    free(pDcDecodedBuffer);
    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. DC成分(1/8 縮小画像)のみを抽出・復号
    // 引数: 出力バッファ, 開始ブロックX, 開始ブロックY, ブロック数X, ブロック数Y, 圧縮データ
    ret = PUC_DecodeDCData(pDcDecodedBuffer, 0, 0, dcWidth, dcHeight, pCompressedBuffer);
    if (ret == PUC_SUCCEEDED) {
    // 9. 抽出した DC 画像を PGM (P5) フォーマットで保存
    const char* filename = "dc_captured_image.pgm";
    FILE* fp = NULL;
    if (fopen_s(&fp, filename, "wb") == 0 && fp != NULL) {
    // PGM ヘッダーの書き込み(幅・高さには DC 画像のサイズを指定)
    fprintf(fp, "P5\n%u %u\n255\n", dcWidth, dcHeight);
    // DC 復号データを書き込み
    fwrite(pDcDecodedBuffer, sizeof(unsigned char), dcDecodedSize, fp);
    fclose(fp);
    printf("SUCCESS: DC成分抽出画像 (PGM) を保存しました (%s)\n", filename);
    } else {
    printf("エラー: ファイルの保存に失敗しました。\n");
    }
    } else {
    printf("エラー: DC成分の復号処理に失敗しました。ErrorCode: %d\n", ret);
    }
    } else {
    printf("エラー: 画像データの取得に失敗しました。ErrorCode: %d\n", ret);
    }
    // 10. メモリ解放とデバイスのクローズ
    free(pCompressedBuffer);
    free(pDcDecodedBuffer);
    PUC_CloseDevice(hDevice);
    return EXIT_SUCCESS;
    }
  2. ビルドと実行

    1. Ctrl + Shift + B でビルドします。
    2. Ctrl + F5 で実行します。
    3. 実行ディレクトリ内に 縦横 1/8 サイズに縮小された dc_captured_image.pgm が出力されていれば成功です。

DC成分抽出(Fast Preview)のメリットと活用場面

Section titled “DC成分抽出(Fast Preview)のメリットと活用場面”

超高速・低負荷なプレビュー生成

Section titled “超高速・低負荷なプレビュー生成”

INFINICAM の固定長圧縮(DCTベース)では、8×8 ブロックの先頭データ(DC成分)にそのブロック全体の平均輝度情報が書き込まれています。

逆DCT計算などの複雑な復号演算を行わずにDC成分だけを抜き出すため、計算量が極めて少なく、CPU負荷をほぼ掛けずに全体画像のサムネイル(1/8 縮小画像)を瞬時に生成できます。

  • リアルタイム・モニター表示: CPUリソースを主処理・解析に集中させつつ、監視画面用として軽量に描画したい場合
  • 関心領域(ROI)の位置検出: 高速な DC 展開で画像全体のオブジェクト位置を検出し、特定した領域だけを ROI デコードで全解像度復号するパイプライン処理の構築