ソフトウェアトリガーで画像を表示・保存
概要
このサンプルは、ソフトウェアトリガーで画像を保存する方法を示しています。
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | SoftwareTrigger_cs_3.5.zip |
サンプル(VB.NET) | SoftwareTrigger_vb_3.5.zip |
サンプルツールの外観
icImagingControl1.LiveDisplayDefault = false;
icImagingControl1.DeviceTrigger = true; //トリガーモードオン
icImagingControl1.LiveCaptureLastImage = false; // Do not save an image on live stop.
icImagingControl1.LiveDisplay = false; //ライブ画像を表示しない
icImagingControl1.Sink = new FrameQueueSink(ShowBuffer, MediaSubtypes.RGB32, 5);
icImagingControl1.LiveStart();//ライブスタート
IcImagingControl1.LiveDisplayDefault = False
IcImagingControl1.DeviceTrigger = True 'トリガーモードオン
IcImagingControl1.LiveCaptureLastImage = False ' Do Not save an image On live Stop.
IcImagingControl1.LiveDisplay = False 'ライブ画像を表示しない
IcImagingControl1.Sink = New TIS.Imaging.FrameQueueSink(Function(img)
Return ShowImage(img)
End Function, New TIS.Imaging.FrameType(TIS.Imaging.MediaSubtypes.RGB32), 5)
DeviceTriggerでトリガーモードをオンにし、ライブスタートします。トリガーモード中、外部トリガー信号あるいはソフトウェアトリガー信号を入力しない限りカメラは画像を転送しません。SingleSnapなどを使用して順次処理をした場合、トリガーを待つ間ずっとプログラム処理が待ち状態になってしまうため、ShowImageなどのコールバック関数を使用することを推奨しています。
下記のような手順でソフトウェアトリガーを入力することができます。
Software TriggerのVDCPropertyのPushメソッドを使用するために、FindInterfaceメソッドの引数にインターフェースパスをパラメーターとして渡しSoftware Triggerプロパティにアクセスします。 ソフトウェアトリガーが入力されたタイミングでライブ表示、画像を取得、画像保存などのキャプチャモード(ShowImageイベント)を有効にするために、FrameQueueSinkをsinkに設定します。このモードでは自動的に全てのフレームがリングバッファにコピーされるようになります。また、 リングバッファへのフレームのコピーが完了するごとにShowImageのコールバック関数に送られるようになります。 また、ライブストップした最後のフレームを保存し表示しないためにオフにし、ShowImageのコールバック関数でLiveDisplayするようにするためにライブ画像を明示的にオフにします。
PC側でフレームを取得する速度よりもカメラの設定フレームレートを速く設定してください。 例えば、1秒間に50回トリガーを入力する場合にはカメラの設定フレームレートを50fps以上にする必要があります。
SoftwareTrigger = icImagingControl1.VCDPropertyItems.Find<VCDButtonProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_SoftwareTrigger);//宣言
ExposureMode = icImagingControl1.VCDPropertyItems.Find<VCDMapStringsProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_Trigger_ExposureMode);//
//トリガーDelay宣言
TriggerDelay = icImagingControl1.VCDPropertyItems.Find<VCDAbsoluteValueProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerDelay);
//DebounceTime宣言;
TriggerDebounceTime = icImagingControl1.VCDPropertyItems.Find<VCDAbsoluteValueProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerDebounceTime);
//MaskTime宣言
TriggerMaskTime = icImagingControl1.VCDPropertyItems.Find<VCDAbsoluteValueProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerMaskTime);
//NoiseSuppressionTime宣言
TriggerNoiseSuppressionTime = icImagingControl1.VCDPropertyItems.Find<VCDAbsoluteValueProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerNoiseSuppressionTime);//トリガーDelay宣言;
//BurstCount宣言;
TriggerBurstCount = icImagingControl1.VCDPropertyItems.Find<VCDRangeProperty>(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_Trigger_BurstCount);
//BurstInterval宣言;
TriggerBurstInterval = icImagingControl1.VCDPropertyItems.Find<VCDRangeProperty>(VCDGUIDs.VCDID_TriggerMode,
Guid.Parse("A9715AB3-69AE-454D-8DF5-7E06D87C109C"));
//トリガーOverlap宣言
TriggerOverlap = icImagingControl1.VCDPropertyItems.Find<VCDMapStringsProperty>(VCDGUIDs.VCDID_TriggerMode,
Guid.Parse("7685BF04-C9C9-4AE2-BA69-1278B77F97F6"));
SoftwareTrigger = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_SoftwareTrigger, VCDGUIDs.VCDInterface_Button)
ExposureMode = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
Guid.Parse("B6E013CA-76C7-4DDD-9AC8-A17E07C5E3F1"),
VCDGUIDs.VCDInterface_MapStrings)
'//トリガーDelay宣言
TriggerDelay = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerDelay,
VCDGUIDs.VCDInterface_AbsoluteValue)
'//DebounceTime宣言;
TriggerDebounceTime = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerDebounceTime,
VCDGUIDs.VCDInterface_AbsoluteValue)
'//MaskTime宣言
TriggerMaskTime = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerMaskTime,
VCDGUIDs.VCDInterface_AbsoluteValue)
'//NoiseSuppressionTime宣言
TriggerNoiseSuppressionTime = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
VCDGUIDs.VCDElement_TriggerNoiseSuppressionTime,
VCDGUIDs.VCDInterface_AbsoluteValue)
'//BurstCount宣言;
TriggerBurstCount = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
Guid.Parse("B4109964-77E4-4AF3-ACA8-45BBAA861B5C"),
VCDGUIDs.VCDInterface_Range)
'//BurstInterval宣言;
TriggerBurstInterval = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
Guid.Parse("A9715AB3-69AE-454D-8DF5-7E06D87C109C"),
VCDGUIDs.VCDInterface_Range)
'//トリガーOverlap宣言
TriggerOverlap = IcImagingControl1.VCDPropertyItems.Find(VCDGUIDs.VCDID_TriggerMode,
Guid.Parse("7685BF04-C9C9-4AE2-BA69-1278B77F97F6"),
VCDGUIDs.VCDInterface_MapStrings)
トリガーで使用するプロパティ(Debounce Time , Trigger mak Time, Delay, Burst Count等)の設定は下記のように、それぞれのVCDプロパティのインターフェースを取得し、値やプロパティの自動設定などのエレメントを調節してください。
※カメラによって実装されている機能とされていない機能があります。
private void Button1_Click(object sender, EventArgs e)
{
SoftwareTrigger.Push(); //ソフトウェアトリガー入力
}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SoftwareTrigger.Push()
End Sub
Pushメソッドを呼び出すことで簡単にソフトウェアトリガーを入力することができます。
private FrameQueuedResult ShowBuffer(IFrameQueueBuffer buffer)
{
icImagingControl1.DisplayImageBuffer(buffer);
//バッファの内容をJPEGファイルとしてディスクに保存します。
string filename = String.Format("test{0}.jpg", counter);
buffer.SaveAsJpeg(filename, 70);
counter++;
return FrameQueuedResult.ReQueue;
}
Function ShowImage(img As TIS.Imaging.IFrameQueueBuffer)
Try
IcImagingControl1.DisplayImageBuffer(img)
'//バッファの内容をJPEGファイルとしてディスクに保存します
Dim filename As String = String.Format("test{0}.jpg", counter)
img.SaveAsJpeg(filename, 70)
counter = counter + 1
Catch ex As System.Exception
System.Diagnostics.Trace.WriteLine(ex.Message)
End Try
Return TIS.Imaging.FrameQueuedResult.ReQueue
End Function
ソフトウェアトリガーを入力したタイミングでリングバッファへのフレームのコピーが完了し、ShowImageのコールバック関数が呼び出されます。バッファはICImagingControl.DisplayImageBufferを呼び出すことで表示することができます。
また、SaveAsJpegメソッドでバッファをJPEG形式などで保存することもできます。
ShowBufferはカメラからのフレームを取得する度毎に呼び出されます。
上記の例では、フレームを取得する度毎にJPEG保存をしていますが、処理時間がかかるロジックになりますとShowBufferの処理はシングルスレッドになっておりますので、ShowBufferの処理が終わらない限りカメラから送られてくるフレームはすべて無視されてしまいます。
なお、DriverFrameDropInformationDataクラスを使うことでフレーム落ちしたかどうか確認することができます。
デバイスの再接続方法とフレーム落ちの確認
IC Imaging Control Ver3.5(C#/VB.NET) サンプルプログラム