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

UYVY は基本的には16ビットのカラーフォーマットです。RGBフォーマットとは違い、それにはred,green,blueのような値は含んでおりません。その代わりに輝度と色度を使用します。Yは輝度を表し、U (or Cb) と V (or Cr) が色度を表します。

http://www.fourcc.org

イメージバッファ内のピクセルは左から右、そして上から下に組織されます。

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

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

バッファにアクセスする

次のコードは画像データへの1バイトのポインタを取得します。ペアになっているピクセルのそれぞれのコンポーネントにアクセスするためにUYVYQuad構造体を使用します。

// UYVY ではイメージは上から順にで保存されていくので左上のピクセルからバイト0として始まります。
// 4バイト分が隣り合う2つのピクセルの色を表現します。
//
// [ U0 | Y0 | V0 | Y1 ]
//
// Y0 はピクセル0の輝度を、Y1 がピクセル1の輝度を表します。
// U0 と V0 は2つのピクセルの色を表現します。
struct UYVYQuad
{
     BYTE U0;
     BYTE Y0;
     BYTE V0;
     BYTE Y1;
};
UYVYQuad* pImgData = (UYVYQuad*)pActiveBuf->getPtr();

今回の例では、画像中の(左上から)最初の4ピクセルを読み出した後、6ピクセル分を操作したいと思います。 UYVY 画像は下から上に保存されるため、 左上の2ピクセルのインデックスは0になります。

// 左上のピクセルのインデックスを算出
// イメージは上から順に保存されていくため、最初の2ピクセルのインデックスは0となる
int iOffsUpperLeft = 0;

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

printf( "\nImage buffer pixel format is eUYVY\n" );
printf( "Pixel 1 (Y U V): %d %d %d\n", pImgData[iOffsUpperLeft].Y0, 
	pImgData[iOffsUpperLeft].U0, pImgData[iOffsUpperLeft].V0 );
printf( "Pixel 2 (Y U V): %d %d %d\n", pImgData[iOffsUpperLeft].Y1,
	pImgData[iOffsUpperLeft].U0, pImgData[iOffsUpperLeft].V0 );
printf( "Pixel 3 (Y U V): %d %d %d\n", pImgData[iOffsUpperLeft+1].Y0,
	pImgData[iOffsUpperLeft+1].U0, pImgData[iOffsUpperLeft+1].V0 );
printf( "Pixel 4 (Y U V): %d %d %d\n", pImgData[iOffsUpperLeft+1].Y1,
	pImgData[iOffsUpperLeft+1].U0, pImgData[iOffsUpperLeft+1].V0 );

2つのピクセルは別々のY(輝度値)を持っていますが、色値であるUとVについては共有していることに注意してください。

画像データを操作する

ピクセルデータの読み込みだけでなく、操作することももちろん可能です。次のコードは左上から6ピクセルをRed, Light Red, Green, Dark Green, Blue, Light Blueと設定します。その後イメージをBMPファイルとして保存します。

// 最初の6ピクセルを上書きしイメージをディスクに保存
// 2ピクセルをREDに設定
pImgData[0].U0 = 90;
pImgData[0].V0 = 240;
pImgData[0].Y0 = 82;
pImgData[0].Y1 = 164;  // 2つ目のピクセルを明るくする

// 3、4番目をGREENにに設定
pImgData[1].U0 = 54;
pImgData[1].V0 = 34;
pImgData[1].Y0 = 145;
pImgData[1].Y1 = 72;  // 4つ目のピクセルを明るくする

// 5,6番目をBLUEに設定
pImgData[2].U0 = 240;
pImgData[2].V0 = 110;
pImgData[2].Y0 = 41;
pImgData[2].Y1 = 82;  // 6つ目のピクセルを明るくする

// 上記の値は次の式をもとに算出される。
//
//  Y  =  (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
//  V  =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
//  U  = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
//
// バッファをRGB24として保存しているので他のソフトウェアで見ることが可能
saveToFileBMP( *pActiveBuf, "UYVY.bmp", eRGB24 );

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