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

Y16は16bitのグレイスケールフォーマットです。イメージバッファのピクセルは左から右へ、上から下へと組織されます。

メモリーレイアウト

すべてのピクセルは符号なしの16bit整数値で、little-endianで格納されています。カメラ自体は10bitか12bitまでしか対応していませんが、この場合の残りのbitsの中身については保証されません。

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

画像取り込みデバイス、ビデオフォーマット、FrameHandlerSinkクラスライブラリリファレンス>クラス>FrameHandlerSinkImageBuffersクラスライブラリリファレンス>クラス>FrameHandlerSink>FrameHandlerSink.ImageBuffers Property コレクション, これら画像データのカラーフォーマットを定義するためのものが全てセットアップされている必要があります。以下のコードはY16ピクセルデータにどようにアクセスし、調整するのかを順番に説明しています。
まず最初に、イメージバッファ内には何もありませんので、画像をキャプチャしなければなりません。そのためにライブ表示を開始し、FrameHandlerSink.SnapImageクラスライブラリリファレンス>クラス>FrameHandlerSink>FrameHandlerSink.SnapImage Method を呼び出します。

バッファにアクセスする

イメージバッファのデータにアクセスするために、まずは16bitの符号なし整数データとして取得する必要があります。System.Runtime.InteropServices.Marshal.ReadInt16を使用することによりヘルパー関数ReadY16が使えます。

[VB.NET]
Private Function ToUInt16(ByVal s As Int16) As UInt16
    If (s And &H8000) = 0 Then
        Return CType(s, UInt16)
    Else
        Return CType(UInt16.MaxValue + 1 + CType(s, Int32), UInt16)
    End If
End Function
 
Private Function ReadY16(ByVal buf As TIS.Imaging.ImageBuffer, ByVal row As Integer, ByVal col As Integer)
   As UInt16
    ' Y16  Y16 は上から下に配列されています。最初のラインのインデックスは0です。
    Dim offset As Integer = row * buf.BytesPerLine + col * 2

    Dim val As Int16 = System.Runtime.InteropServices.Marshal.ReadInt16(buf.GetIntPtr(), offset)

    Return ToUInt16(val)
End Function
[C#]
private UInt16 ReadY16(TIS.Imaging.ImageBuffer buf, int row, int col)
{
    // Y16 は上から下に配列されています。最初のラインのインデックスは0です。
    int offset = row * buf.BytesPerLine + col * 2;
    return (UInt16)System.Runtime.InteropServices.Marshal.ReadInt16(buf.GetIntPtr(), offset);
}

このサンプルでは、最初(左上側)の2ピクセルを取得します。

[VB.NET]
Dim val0 As UInt16 = ReadY16(buf, 0, 0)
Dim val1 As UInt16 = ReadY16(buf, 0, 1)
 
txtOutput.Text = "Image buffer pixel format is Y16" & vbCrLf
txtOutput.Text &= "Pixel 1: " & val0 & vbCrLf
txtOutput.Text &= "Pixel 2: " & val1
[C#]
UInt32 val0 = ReadY16(buf, 0, 0);
UInt32 val1 = ReadY16(buf, 0, 1);
 
txtOutput.Text = "Image buffer pixel format is Y16\r\n";
txtOutput.Text += "Pixel 1: " + val0 + "\r\n";
txtOutput.Text += "Pixel 2: " + val1;

イメージデータの操作

関数WriteY16をイメージデータの輝度値の書き込みに使用します。

[VB.NET]
Private Function ToInt16(ByVal us As UInt16) As Int16
    If (us And &H8000) = 0  Then
        Return CType(us, Int16)
    Else
        Return CType(CType(us, Int32) - UInt16.MaxValue - 1, Int16)
    End If
End Function
 
Private Sub WriteY16(ByVal buf As TIS.Imaging.ImageBuffer, ByVal row As Integer, 
                             ByVal col As Integer, ByVal value As UInt16)
      Dim offset As Integer = row * buf.BytesPerLine + col * 2
      System.Runtime.InteropServices.Marshal.WriteInt16(buf.GetIntPtr(), offset, ToInt16(value))
End Sub
[C#]
private void WriteY16(TIS.Imaging.ImageBuffer buf, int row, int col, UInt16 value)
{
    int offset = row * buf.BytesPerLine + col * 2;

    System.Runtime.InteropServices.Marshal.WriteInt16(buf.GetIntPtr(), offset, (short)value);
}

ここで画像中の左上にある3ピクセルに対して、黒、グレー、白を書き込みます。

[VB.NET]
WriteY16(buf, 0, 0, &H0) ' Black
WriteY16(buf, 0, 1, &H8000)    ' Gray
WriteY16(buf, 0, 2, &HFFFF)    ' White
 
buf.SaveAsTiff("y16.tiff")
[C#]
WriteY16(buf, 0, 0, 0x0000); // Black
WriteY16(buf, 0, 1, 0x8000); // Gray
WriteY16(buf, 0, 2, 0xFFFF); // White
 
buf.SaveAsTiff("y16.tiff");

結果を確認するために、保存されたイメージの左上を確認してください。以下の様になっているはずです。