画像処理を施す
自分で画像処理機能を作成する方法について説明します。
今回のサンプルプログラムの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 Live、Stop Live、Processとします。またcmdStartLive、cmdStopLive、cmdProcessと名前を付けます。
これらのボタンのClickイベントに以下のコードを追加します。
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
private void cmdStartLive_Click_1(object sender, EventArgs e)
{
icImagingControl1.LiveStart();
// VideoHasStarted の中にビデオストリームをこれまでに開始した
// ことがあるかどうかの値を格納。VideoHasStartedがTrueであれば
// 処理が可能な画像が存在するということを確認できます。
VideoHasStarted = true;
// ビデオストリームは開始されたばかりなので、
// VideoHasStopped の値はFalseになります。
VideoHasStopped = false;
}
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
private void cmdStopLive_Click(object sender, EventArgs e)
{
icImagingControl1.LiveStop();
if (VideoHasStarted == true)
{
VideoHasStopped = true;
}
}
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
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クラスライブラリリファレンス>クラス>VideoFormat と MemoryCurrentGrabberColorformatクラスライブラリリファレンス>クラス>ICImagingControl>ICImagingControl.MemoryCurrentGrabberColorformat Property で異なるフォーマットを選択することは避けてください。画像データの変換が必要となるため、パフォーマンスの低下を招きます。