画像処理を施す

自分で画像処理機能を作成する方法について説明します。
今回のサンプルプログラムのVB.NET 、C#用のソースコードはMy Documents/IC Imaging Control 3.4内の以下のディレクトリに格納されています。
samples\VB *\Image Processing
samples\C# *\Image Processing

プロジェクトの新規作成

新しいプロジェクトを作成し、IC imaging Controlをフォームに追加してください。プログラムを実行する前に、 はじめに: Visual Studio .NETプログラマーズガイド>Visual Studioでスタート にあるように映像デバイスの選択、入力方式、ビデオフォーマットを選択してください。もしくはデバイスを選択せずにプログラムを実行してください。その際はIC Imaging Controlによってデバイス選択のダイアログが出現します。選択をせずにダイアログを閉じた場合、プログラムはエラーメッセージを表示し、終了します。
フォームに3つのボタンを追加し、 CaptionプロパティをそれぞれStart LiveStop LiveProcessとします。またcmdStartLivecmdStopLivecmdProcessと名前を付けます。
これらのボタンのClickイベントに以下のコードを追加します。

[VB.NET]
Private Sub  cmdStartLive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles cmdStartLive.Click
     IcImagingControl1.LiveStart()

     ' VideoHasStarted の中にビデオストリームをこれまでに開始した
     ' ことがあるかどうかの値を格納。VideoHasStartedがTrueであれば
     ' 処理が可能な画像が存在するということを確認できます。
     VideoHasStarted = True

     ' ビデオストリームは開始されたばかりなので、
     ' VideoHasStopped の値はFalseになります。
     VideoHasStopped = False
End Sub
[C#]
private void  cmdStartLive_Click_1(object sender, EventArgs e)
{
     icImagingControl1.LiveStart();

     // VideoHasStarted の中にビデオストリームをこれまでに開始した
     // ことがあるかどうかの値を格納。VideoHasStartedがTrueであれば
     // 処理が可能な画像が存在するということを確認できます。
     VideoHasStarted = true;

     // ビデオストリームは開始されたばかりなので、
     // VideoHasStopped の値はFalseになります。
     VideoHasStopped = false;
}

[VB.NET]
Private Sub  cmdStopLive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles cmdStopLive.Click
     IcImagingControl1.LiveStop()

     If VideoHasStarted = True Then
         VideoHasStopped = True
     End If
End Sub
[C#]
private void  cmdStopLive_Click(object sender, EventArgs e)
{
     icImagingControl1.LiveStop();

     if (VideoHasStarted == true)
     {
         VideoHasStopped = true;
     }
}

[VB.NET]
Private Sub  cmdProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles cmdProcess.Click
     Dim ImgBuffer As TIS.Imaging.ImageBuffer
     Dim x As Integer, y As Integer
     Dim BytesPerLine As Integer
     Cursor = Cursors.WaitCursor
     Try
         ' ビデオストリームをこれまでに開始したことがあるかどうかをチェック。
         ' もしあった場合には, 次の2つの状況が想定されます。
         ' 1) 現在ライブ表示中である。この場合はライブ表示を停止して
         '    最後のフレームの取得、処理、表示ができるようにします。
         ' 2) ライブ表示がすでに停止している状態。この場合は最後のフレームが
         '    自動的に取り込まれ、処理、表示が可能になります。

         If VideoHasStarted Then
             If VideoHasStopped = False Then
                 IcImagingControl1.LiveStop()
             End If

             ImgBuffer = IcImagingControl1.ImageActiveBuffer
             ' カラーフォーマットとイメージバッファの1ライン当たりのピクセル数から
             ' 1ラインあたりのバイト数を算出
             BytesPerLine = ImgBuffer.BitsPerPixel / 8 * ImgBuffer.PixelPerLine - 1
             For y = 0 To ImgBuffer.Lines - 1
                 For x = 0 To BytesPerLine
                     ImgBuffer(x, y) = 255 - ImgBuffer(x, y)
                 Next x
             Next y
            IcImagingControl1.Display()
         Else
             MessageBox.Show("Please click the Start Live button first!", _
                             "Image Processing", _
                             MessageBoxButtons.OK, _
                             MessageBoxIcon.None)
         End If
     Catch ex As System.Exception
         MessageBox.Show(ex.Message)
     End Try
     Cursor = Cursors.Default
End Sub
[C#]
private void  cmdProcess_Click(object sender, EventArgs e)
{
     TIS.Imaging.ImageBuffer ImgBuffer;
     int x, y;
     int BytesPerLine;

     Cursor = Cursors.WaitCursor;
     try
     {
         // ビデオストリームをこれまでに開始したことがあるかどうかをチェック。
         // もしあった場合には, 次の2つの状況が想定されます。
         // 1) 現在ライブ表示中である。この場合はライブ表示を停止して
         //    最後のフレームの取得、処理、表示ができるようにします。
         // 2) ライブ表示がすでに停止している状態。この場合は最後のフレームが
         //    自動的に取り込まれ、処理、表示が可能になります。
         if (VideoHasStarted)
         {
             if (VideoHasStopped == false)
             {
                 icImagingControl1.LiveStop();
             }

             ImgBuffer = icImagingControl1.ImageActiveBuffer;
             // 1ラインあたりのバイト数を算出
             BytesPerLine = ImgBuffer.BitsPerPixel / 8 * ImgBuffer.PixelPerLine;
             unsafe
             {
                 byte* pDatabyte = ImgBuffer.GetImageData();
                 for (y = 0; y < ImgBuffer.Lines; y++)
                 {
                     for (x = 0; x < BytesPerLine; x++)
                     {
                         *pDatabyte = (byte)(255 - *pDatabyte);
                         pDatabyte++;
                     }
                 }
             }

             icImagingControl1.DisplayImageBuffer(ImgBuffer);
         }
         else
         {
             MessageBox.Show("Please click the Start Live button first!",
                 "Image Processing",
                 MessageBoxButtons.OK,
                 MessageBoxIcon.None);
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
     Cursor = Cursors.Default;
}

まず最初に、LiveStopクラスライブラリリファレンス>クラス>ICImagingControl>ICImagingControl.LiveStop Method メソッドが呼び出された時点で自動的に画像がキャプチャされます。この処理は直接Stop Liveボタンをクリックすることで、もしくはProcessボタンをクリックすることで暗黙的に行う事も可能です。変数VideoHasStartedはこれまでにライブ表示が行われたことがあるかどうかをチェックし、画像処理を施すことが可能かどうかを判断します。
そしてアクティブなバッファが呼び出されます。これは以前に取り込まれた画像を保持しているバッファです。画像データにはItemクラスライブラリリファレンス>クラス>ImageBuffer>ImageBuffer.Item Propertyプロパティでアクセスすることができます。ネスティングされた2つの for..next文ループは画像処理アルゴリズムとしては典型的なもので、画像の中の各ピクセルの座標を指定しながら個別にアクセスするようにしています。ここで紹介するアルゴリズムは単に画像を反転させるものです。
上記のサンプルコードは8-bit もしくは 24-bit の画像データを必要とします。
よってMemoryCurrentGrabberColorformatクラスライブラリリファレンス>クラス>ICImagingControl>ICImagingControl.MemoryCurrentGrabberColorformat Propertyプロパティで適切な値を選択する必要があります。


カラーフォーマットを使用する

ピクセルあたりのデータが8bit を超えるビデオフォーマットが選択された場合でも、イメージバッファの1ラインあたりのピクセル数は変わらず同じではあります。しかしそのピクセルあたりのデータが1byteを超えていまうということは、バッファのサイズは大きくなるということを意味します。例えばそのビデオフォーマットが RGB24(640x480)でピクセルあたり 3 byteであるとすれば、 イメージバッファのサイズとしては1920x480と同じになります。
RGB24では、ピクセルデータは次の通りに解読されます。: 行の1つめのバイトが 最初のピクセルのBlueの値、2つめのバイトが同ピクセルのGreenの値、3つめのバイトが同ピクセルのRedの値、そして4つめのバイトが次のピクセルのBlueの値...となります。
処理によって、次のような画像を得ることが可能です


必要なケース以外では、VideoFormatクラスライブラリリファレンス>クラス>VideoFormatMemoryCurrentGrabberColorformatクラスライブラリリファレンス>クラス>ICImagingControl>ICImagingControl.MemoryCurrentGrabberColorformat Property で異なるフォーマットを選択することは避けてください。画像データの変換が必要となるため、パフォーマンスの低下を招きます。