イメージバッファにアクセスする - RGB24 -

RGB24は24bit 、カラーのフォーマットです。 すべてのピクセルが3バイトで表されますが、1バイトがそれぞれ1色の値に対応します。'RGB' は それぞれRed (赤)、Green (緑)、Blue (青) を意味し、 3つのバイトがそれぞれRed, Green, Blueの値を表しているということになります。
RGB という呼び方は誤解を招く可能性があるかもしれません。というのもピクセルの最初のバイトが必ずしもRedの値を表すということではないためです。Windows© 環境においては、RGB データは大抵BGRの順に並んでいます。つまり最初のバイトがBlue,次にGreen, Redとなっているということです。IC Imaging Control はBGR 順になっており、イメージバッファのピクセルは左から右へ、下から上へと組織されます。

ピクセルデータの読み込み、書き込みの方法

画像取り込みデバイス、ビデオフォーマット、 画像データのカラーフォーマットを定義するMemBufferCollectionクラスライブラリリファレンス>クラス>MemBufferCollectionを持つFrameHandlerSinkクラスライブラリリファレンス>クラス>FrameHandlerSinkがセットアップされている必要があります。記ではRGB24のピクセルデータにどようにアクセスし、操作するかを順番に説明しています。
まず最初に、イメージバッファ内には何もありませんので、画像をキャプチャしなければなりません。そのためにライブ表示を開始しGrabber::snapImagesクラスライブラリリファレンス>クラス>Grabber>Grabber::snapImages Methodをコールします。

バッファにアクセスする

次のコードは画像データへの1バイトのポインタを取得します。ピクセルのコンポーネントにアクセスするために構造体RGB24Pixelを使用しRGB8のレベルにまで座標計算量を減らします。。

struct RGB24Pixel {
  BYTE b;
  BYTE g;
  BYTE r;
};
RGB24Pixel* pbImgData = (RGB24Pixel*) pActiveBuf->getPtr();

今回の例では、画像中の(左上から)最初の2ピクセル分の読み出した後、3ピクセル分を操作します。先ほど説明したようにRGB 画像は下から上に保存されるため、pbImgDataはイメージの最後の行の最初のピクセルをポイントします。1行目の最初のピクセルにアクセスしたい場合には下記のようにして算出する必要があります。

// 左上のピクセルのインデックスを算出
// 画像はイメージバッファ内に上下逆に保存されます
SIZE dim = pActiveBuf->getFrameType().dim;
int iOffsUpperLeft = (dim.cy-1) * dim.cx;

まず最初に、画像の高さと幅をピクセル数で取得します。そして左上のピクセルへのオフセットが計算されます。全てのピクセルのサイズは1バイトなので、このように計算することができます。

(Height-1) * Width

最初のピクセルのオフセットを取得したので読み出します。

printf( "\nImage buffer pixel format is eRGB24\n" );
// 注:RGBの各値は次の順番で保存されています(B,G,R)
printf( "Pixel 1(RGB): %d %d %d\n", pbImgData[iOffsUpperLeft].r,    //RED
                     pbImgData[iOffsUpperLeft].g,    //GREEN
                   pbImgData[iOffsUpperLeft].b );    //BLUE
printf( "Pixel 1(RGB): %d %d %d\n", pbImgData[iOffsUpperLeft+1].r,    //RED
                     pbImgData[iOffsUpperLeft+1].g,    //GREEN
                   pbImgData[iOffsUpperLeft+1].b );    //BLUE

画像データを操作する

ピクセルデータの読み込みを行うだけでなく、データを操作するという事も可能です。次のコードは左上のピクセルをRed、そして次の2つのピクセルをそれぞれGreen、Blueとします。この操作後、画像をBMPファイルとして保存します。

// 最初の3つのピクセルを上書きしてディスクに画像を保存する
// 最初のピクセルをREDに設定
pbImgData[iOffsUpperLeft].b = 0;    // BLUE
pbImgData[iOffsUpperLeft].g = 0;    // GREEN
pbImgData[iOffsUpperLeft].r = 255;    // RED

// 2番目のピクセルをGREENに設定
pbImgData[iOffsUpperLeft+1].b = 0;    // BLUE
pbImgData[iOffsUpperLeft+1].g = 255;    // GREEN
pbImgData[iOffsUpperLeft+1].r = 0;    // RED

// 3番目のピクセルをBLUEに設定
pbImgData[iOffsUpperLeft+2].b = 255;    // BLUE
pbImgData[iOffsUpperLeft+2].g = 0;    // GREEN
pbImgData[iOffsUpperLeft+2].r = 0;    // RED

saveToFileBMP( *pActiveBuf, "RGB24.bmp" );

確認のために保存されたか画像の左上のピクセルを見てみましょう。このようになっているはずです。