SingleImage + DC成分抽出
GbE-2 から 1 フレームの圧縮データを取得し、DC成分(各 8×8 ブロックの平均輝度)のみを取り出して復号することで、縦横 1/8 サイズの軽量プレビュー画像を高速に生成し、PGM形式(Portable Graymap)で保存するプログラムの作成手順です。
-
ソースコードの記述
メインファイル(
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;} -
ビルドと実行
Ctrl+Shift+Bでビルドします。Ctrl+F5で実行します。- 実行ディレクトリ内に 縦横 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 縮小画像)を瞬時に生成できます。
主な活用シーン
Section titled “主な活用シーン”- リアルタイム・モニター表示: CPUリソースを主処理・解析に集中させつつ、監視画面用として軽量に描画したい場合
- 関心領域(ROI)の位置検出: 高速な DC 展開で画像全体のオブジェクト位置を検出し、特定した領域だけを ROI デコードで全解像度復号するパイプライン処理の構築
