イメージバッファにアクセスする - YGB0 -
YGB0 は10bit 、モノクロのフォーマットです。全てのピクセルが2バイトで表されます。2バイト=16bitのうち10bitのみが画像の情報を含み、残りの6bitは使用されません。 イメージバッファのピクセルは左から右へ、上から下へと組織されます。
メモリーレイアウト
上の図の通り、low byte が2から9までのビットを持ち、0と1のビットはhigh byteに格納されています。イメージバッファの2バイトを画像処理の際に使えるよう16bit値(0~1023)に変換するために、これらのバイトの位置の入れ替え、右側へのシフトを行う必要があります。次のコードはYGB0フォーマットへの変換、またはその反対のYGB0フォーマットからの変換をどのように行っているかを表しています。
Private Function IntValueFromYGB0Bytes(ByVal b1 As Byte, ByVal b2 As Byte) As Integer
Return (((CInt(b1) << 8) Or CInt(b2)) >> 6)
End Function
Private Function YGB0BytesFromIntValue(ByVal val As Integer, ByRef b1 As Byte, ByRef b2 As Byte)
val <<= 6
b1 = CByte(val >> 8)
b2 = CByte(val & 255)
End Function
private UInt16 UInt16ValueFromYGB0Bytes(byte b1, byte b2)
{
return (UInt16)(((b1 << 8) | b2) >> 6);
}
private void YGB0BytesFromUInt16Value(UInt16 val, out byte b1, out byte b2)
{
val <<= 6;
b1 = (byte)(val >> 8);
b2 = (byte)(val & 0xff);
}
関数UInt16ValueFromYGB0Bytesはイメージバッファより16bitの値を受け取り、0から1023の範囲でそのピクセルの論理輝度値として変換してします。
YGB0BytesFromUInt16Valueはその逆の動作をするもので、輝度値を変換してイメージバッファの中で保持できる数字に変換します。
ピクセルデータの読み込み、書き込みの方法
画像取り込みデバイス、ビデオフォーマット、 FrameHandlerSinkクラスライブラリリファレンス>クラス>FrameHandlerSink と ImageBuffersクラスライブラリリファレンス>クラス>FrameHandlerSink>FrameHandlerSink.ImageBuffers Property コレクション, これら画像データのカラーフォーマットを定義するためのものが全てセットアップされてなければなりません。以下のコードはYGB0ピクセルデータにどようにアクセスし、調整するのかを順番に説明しています。
まず最初に、イメージバッファ内には何もありませんので、画像をキャプチャしなければなりません。そのためにライブ表示を開始し、FrameHandlerSink.SnapImageクラスライブラリリファレンス>クラス>FrameHandlerSink>FrameHandlerSink.SnapImage Method を呼び出します。
バッファにアクセスする
イメージバッファのデータにアクセスするために、C# なら buf[column,line]、VB.NETであれば buf(column,line)を記述します。
今回の例では、画像中の最初の(一段左上から)2ピクセル分の読み出しをします。 次のステップでは最初の3ピクセルを扱います。RGB 画像は下から上に保存されるため、最初のラインのインデックスはilines-1となります。
ピクセルデータのX座標を計算するため、1ピクセルあたりに必要なバイト数(2)に取得される縦のピクセルを掛けます。その後、ピクセルのRedかGreen,もしくはBlueコンポーネントにアクセスするためのオフセットが加えられます。
ピクセルデータを輝度値に変換する為に、上で紹介した関数UInt16ValueFromYGB0Bytesが使われます。
' YGB0 はトップダウンなので最初のラインのインデックスは0となります。
Dim y As Integer = 0
Dim val0 As Integer = IntValueFromYGB0Bytes(buf(0, y), buf(1, y))
Dim val1 As Integer = IntValueFromYGB0Bytes(buf(2, y), buf(3, y))
txtOutput.Text = "Image buffer pixel format is YGB0" & vbCrLf
txtOutput.Text &= "Pixel 1: " & val0 & vbCrLf
txtOutput.Text &= "Pixel 2: " & val1
// YGB0 はトップダウンなので最初のラインのインデックスは0となります。
int y = 0;
UInt16 val0 = UInt16ValueFromYGB0Bytes(buf[0 * 2 + 0, y], buf[0 * 2 + 1, y]);
UInt16 val1 = UInt16ValueFromYGB0Bytes(buf[1 * 2 + 0, y], buf[1 * 2 + 1, y]);
txtOutput.Text = "Image buffer pixel format is YGB0\r\n";
txtOutput.Text += "Pixel 1: " + val0 + "\r\n";
txtOutput.Text += "Pixel 2: " + val1;
画像データを調整する
では、左上の3つのピクセルを黒、グレー、白とします。上で紹介した関数YGB0BytesFromUInt16Value は輝度値からピクセルデータへの変換に使用されます。
Dim b1, b2 As Byte
YGB0BytesFromIntValue(0, b1, b2)
buf(0, y) = b1
buf(1, y) = b2
YGB0BytesFromIntValue(512, b1, b2)
buf(2, y) = b1
buf(3, y) = b2
YGB0BytesFromIntValue(1023, b1, b2)
buf(4, y) = b1
buf(5, y) = b2
buf.SaveAsBitmap("ygb0.bmp", TIS.Imaging.ICImagingControlColorformats.ICY800)
byte b1, b2;
YGB0BytesFromUInt16Value(0, out b1, out b2);
buf[0 * 2 + 0, y] = b1;
buf[0 * 2 + 1, y] = b2;
YGB0BytesFromUInt16Value(512, out b1, out b2);
buf[1 * 2 + 0, y] = b1;
buf[1 * 2 + 1, y] = b2;
YGB0BytesFromUInt16Value(1023, out b1, out b2);
buf[2 * 2 + 0, y] = b1;
buf[2 * 2 + 1, y] = b2;
buf.SaveAsBitmap("ygb0.bmp", TIS.Imaging.ICImagingControlColorformats.ICY800);
結果をチェックするために保存された画像を開き、左上のピクセルを見てください。次のように表示されるかと思います。