全フレームリアルタイム画像処理しながらNG判定を静止画保存、同時に録画
概要
ICImagingControlを使用してTheImagingSourceのデバイスで取得できる画像を全フレームリアルタイムに画像処理とライブ表示を行いながら、任意のタイミングで録画を開始し、任意のタイミングあるいは画像処理NG時に静止画保存をするためのサンプルプログラムです。FrameQueueSinkがメインのAPIです。
処理内容とタイミング | 1.ライブ表示のみ | 2.静止画保存 | 3.任意のタイミングで画像処理と静止画保存を同時に処理 | 4.録画しながら任意のタイミングで静止画保存 | 5.全フレームリアルタイム画像処理しながら、NG判定を静止画保存 | 6.全フレームリアルタイム画像処理しながらNG判定を静止画保存、同時に録画 | |
---|---|---|---|---|---|---|---|
処理タイミング
|
ライブ 表示 |
〇 LiveDisplay | 〇 LiveDisplay | 〇 LiveDisplay | 〇 LiveDisplay | - | - |
画像 処理 |
× | × | 〇 SnapSingle | × | - | - | |
静止画 保存 |
× | 〇 SnapSingle | 〇 SnapSingle |
〇
SetStringParameter (FrameFilter) |
- | - | |
動画 保存 |
× | × | × |
〇
LiveStart (MediaStreamSink) |
- | - | |
処理タイミング
|
ライブ 表示 |
- | - | - | - | 〇 DisplayImageBuffer | 〇 DisplayImageBuffer |
画像 処理 |
- | - | - | - | 〇 FrameQueueSinkQueueSink | 〇 FrameQueueSinkQueueSink | |
静止画 保存 |
- | - | - | - |
〇
SaveAsBitmap (コールバック関数内で定義) |
〇
SaveAsBitmap (コールバック関数内で定義) |
|
動画 保存 |
- | - | - | - | × | 〇 Windows API | |
メインになる ICImagingControl Sinkクラス |
FrameNotificationSink | FrameSnapsink | FrameSnapsink | MediaStreamSink | FrameQueueSink | FrameQueueSink | |
使用例 | 拡大観察してモニター表示しているものを作業者がモニターで目視チェック。 | モニター表示による拡大観察と作業者による画像保存操作。 | オフラインでの寸法測定と測定画像の保存。 | オフラインでの寸法測定と測定画像の保存と作業内容の録画。 | インラインの画像検査。NG判定画像保存でトレサビ管理。 | インラインの画像検査。NG判定画像保存でトレサビ管理と、録画によるラインの監視。 | |
sinkのオブジェクトが用意している コールバック関数 |
有り (コールバック関数はあるが全フレーム取得は保証されていない) |
無し | 無し | 無し | 有り | 有り | |
Sinkの切り替え | 無し | 無し | 無し | 有り | 無し | 無し |
サンプルプログラム
Software | IC Imaging Control 3.5, Visual Studio™ 2019 |
---|---|
サンプル(C#) | multi_process6_cs_3.5.zip |
サンプルツールの外観
フォームを立ち上げたときのイベント
public string _FileName = ""video.mp4"";
private FrameFilter _saveImageFrameFilter;
private FrameQueueSink _frameQueueSink;
private MFTestSharp.H264Writer _writer = null;
private bool blnDiplayOnOff = true;
private bool blnImageProcessON = false;
private bool blnRecordON = false;
private void Form1_Load( object sender, EventArgs e )
{
// カメラの設定した解像度に合わせて表示画面を変更
icImagingControl1.LiveDisplayDefault = false;
icImagingControl1.LiveDisplaySize = icImagingControl1.Size;
icImagingControl1.LiveDisplay = false;
_frameQueueSink = new FrameQueueSink(Callback_FrameQueueSink, MediaSubtypes.RGB32, 5);
icImagingControl1.Sink = _frameQueueSink;
//静止画保存するための準備(フレームフィルタの定義)
_saveImageFrameFilter = FrameFilter.Create(""Save Image"");
if (_saveImageFrameFilter == null)
{
MessageBox.Show($""Failed to load the \""Save Image\"" frame filter!"", ""Error"", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
icImagingControl1.DeviceFrameFilters.Add(_saveImageFrameFilter);
MediaFoundationApi.Startup();
}
"最初に、グローバル変数としてFrameQueueSink、画面表示ON/OFFを制御するフラグblnDiplayOnOff、画像処理ON/OFFを制御するフラグblnImageProcessON、録画開始ON/OFFを制御するフラグblnRecordONなどを宣言しています。
その後icImagingControl1コントロールのSinkプロパティに、画像処理をするための新しいTIS.Imaging.FrameQueueSinkオブジェクトを設定します。
FrameQueueSinkのSinkではIC Imaging Controlが自動的にライブストリームを表示しないようにLiveDisplay = falseにします。
画面表示は後述するCallback_FrameQueueSinkコールバック関数の中でフレームを受け取るたび毎にicImagingControl1.DisplayImageBuffer(buffer);で表示するようにしています。
リアルタイム画像処理中の任意のタイミングで静止画像保存ができるように、FrameFilter.Createメソッドを使用してSave Imageフレームフィルターを作成し、icImagingControl1.DeviceFrameFiltersコレクションに追加します。
※補足 フレームフィルターとは:
通常は、SnapSingleメソッドで静止画保存をします。しかし、リアルタイムに画像処理をしながらSnapSingleメソッドを使う事はできないので、連続画像処理をしながら静止画保存をするためにフレームフィルターを用いる必要があります。フレームフィルターは様々な種類があり、レンズの歪曲収差補正、デノイズ処理、画像の回転などがあります。ここでは、Save Imageフレームフィルターを用いています。Save Imageフィルターを使う為に、以下のファイルを実行ファイルと同じディレクトリに配置する必要があります。
SaveImageFrameFilter32.ftf | Save Imageのフィルター画像処理で画像保存するための設定情報が定義されたXML形式のファイル(32bitアプリケーション向け) |
---|---|
SaveImageFrameFilter64.ftf | Save Imageのフィルター画像処理で画像保存するための設定情報が定義されたXML形式のファイル(64bitアプリケーション向け) |
tis_udshl12.dll | ftfファイルの読み込む時に必要となるファイル(32bitアプリケーション向け) |
tis_udshl12_x64.dll | ftfファイルの読み込む時に必要となるファイル(64bitアプリケーション向け) |
最後にMediaFoundationApi.Startup();を呼び出しています。
通常、録画をする時はMediaStreamSinkを使いますが、このサンプルではライブ表示・画像処理・動画保存・静止画保存の4つの処理を同時に行う為に、FrameQueueSinkのSinkを既に使っています。
ICImagingControlでは同時に2つ以上のSinkを使う事はできないので、ここではMediaStreamSinkの代わりにNAudio.MediaFoundationを使用します。MediaFoundationApi.Startup();を呼び出しておくことで録画時にMedia Foundation APIを使えるようにしてます。
[デバイス選択 ShowDeviceSettingsDialog]ボタンをクリックしたときの処理
private void cmdDeviceFrameQueueSink_Click(object sender, EventArgs e)
{
if (icImagingControl1.LiveVideoRunning)
{
icImagingControl1.LiveStop();
}
// デバイスダイアログを表示する
icImagingControl1.ShowDeviceSettingsDialog();
icImagingControl1.LiveStart();
}
[デバイス選択 ShowDeviceSettingsDialog]ボタンをクリックしたときのイベントです。最初にライブモードが停止していること(LiveStartメソッドを呼んでいないこと)を確認するために、LiveVideoRunningプロパティを確認しています。ShowDeviceSettingsDialogメソッドを呼び出して、下図のようなデバイス設定ダイアログを表示し、ダイアログにてカメラの選択、ビデオフォーマットの設定、フレームレートの設定を行い、OKを押下してデバイス設定ダイアログを閉じます。その後、icImagingControl1.LiveStart();にてカメラのリアルタイムの映像を画面に表示します。
[プロパティ ShowPropertyDialog]ボタンをクリックしたときの処理
private void cmdPropertiesFrameQueueSink_Click(object sender, EventArgs e)
{
icImagingControl1.ShowPropertyDialog();
}
[プロパティ ShowPropertyDialog]ボタンをクリックしたときのイベントです。下図のようなIC Imaging Controlのプロパティダイアログを表示します。プロパティダイアログには、カメラのゲイン、露光時間、ホワイトバランス、明るさ、コントラストなどのカメラの機能に関する設定が含まれており、それらの設定をプロパティダイアログ上で変更することができます。
[画面表示ON blnDiplayOnOff=True]ボタンをクリックしたときの処理
private void cmdDisplayON_Click(object sender, EventArgs e)
{
blnDiplayOnOff = true;
}
[画面表示ON blnDiplayOnOff=True]ボタンを押下したときのイベントです。フォーム上のICImagingControlのコントロール(画面上)にカメラの映像を表示させるか、または非表示にするか切り替えるために使用されます。
FrameSnapSinkやMediaStreamSinkでは表示非表示をicImagingControl1.LiveDisplay で切り替えていましたが、FrameQueueSinkのときはblnDiplayOnOffでDisplayImageBufferメソッドで画面表示/非表示を切り替えています。FrameQueueSinkではコールバック関数ImageProcess内でDisplayImageBufferメソッドを呼び出しており、LiveStartを呼び出し中でもblnDiplayOnOffを切り替えることができます。
[画面表示OFF blnDiplayOnOff=False]ボタンをクリックしたときの処理
private void cmdDisplayOFF_Click(object sender, EventArgs e)
{
blnDiplayOnOff = false;
}
[画面表示OFF blnDiplayOnOff=False]ボタンを押下したときのイベントです。フォーム上のICImagingControlのコントロール(画面上)にカメラの映像を表示させるか、または非表示にするか切り替えるために使用されます。
FrameSnapSinkやMediaStreamSinkでは表示非表示をicImagingControl1.LiveDisplay で切り替えていましたが、FrameQueueSinkのときはblnDiplayOnOffでDisplayImageBufferメソッドで画面表示/非表示を切り替えています。FrameQueueSinkではコールバック関数ImageProcess内でDisplayImageBufferメソッドを呼び出しており、LiveStartを呼び出し中でもblnDiplayOnOffを切り替えることができます。
[ライブスタート LiveStart(FrameQueueSink)]ボタンをクリックしたときの処理
private void cmdLiveStartFrameQueueSink_Click(object sender, EventArgs e)
{
//画像処理OFF
blnImageProcessON = false;
if (!icImagingControl1.LiveVideoRunning)
icImagingControl1.LiveStart();
//録画開始OFF
blnRecordON = false;
}
//非同期処理の定義
public delegate void ImageProcessDelegate(IFrameQueueBuffer imgBuffer);
//非同期処理の実行
private FrameQueuedResult Callback_FrameQueueSink(IFrameQueueBuffer buffer)
{
BeginInvoke(new ImageProcessDelegate(ImageProcess), buffer);
return FrameQueuedResult.ReQueue;
}
private void ImageProcess(IFrameQueueBuffer imgBuffer)
{
//録画開始
if (_writer != null & blnRecordON ) _writer.Write(imgBuffer);
//画像処理
if (blnImageProcessON) makeImageNegative(imgBuffer);
//画面表示
if (blnDiplayOnOff) icImagingControl1.DisplayImageBuffer(imgBuffer);
}
上記はIC Imaging ControlのLiveStartを定義したものです。
cmdLiveStartFrameQueueSink_Clickメソッドは、【ライブスタート LiveStart(FrameQueueSink)】ボタンがクリックされたときに呼び出されます。
LiveStartをすることで「■フォームを立ち上げたときのイベント」にて_frameQueueSink = new FrameQueueSink(Callback_FrameQueueSink, MediaSubtypes.RGB32, 5);と定義したコールバック関数ImageProcessが呼び出されます。
//画像処理OFF
事前に【画像処理開始 FrameQueueSink】ボタンを押下していると画像処理が実行されているので、画面表示のみを行う為に画像処理ON/OFFを制御するフラグblnImageProcessONをfalseにしています。
//録画開始OFF
事前に【録画開始 NAudio】ボタンを押下していると録画開始が実行されているので、画面表示のみを行う為に録画開始ON/OFFを制御するフラグblnRecordONをfalseにします。
//非同期処理の定義
録画開始、画像処理、画面表示を非同期で実行する為にIFrameQueueBufferを引数に取るデリゲートとしてImageProcessDelegateを宣言し、非同期処理の定義をします。
//非同期処理の実行
Callback_FrameQueueSinkメソッドはカメラから送られた画像を受け取ったタイミングで呼び出されます。その後、Callback_FrameQueueSinkメソッド内でBeginInvokeを使用して非同期処理を実行し、ImageProcessメソッドに引き渡します。次に、Callback_FrameQueueSinkの戻り値に、コールバック関数内で処理したフレームを使用するために再びキューに入れています。
//録画開始
ImageProcessメソッド内ではcmdLiveStartFrameQueueSink_Clickメソッド内でblnRecordONをFalseにしているため、録画開始で行う _writer.Writeメソッドはスルーします。
//画像処理
ImageProcessメソッド内ではcmdLiveStartFrameQueueSink_Clickメソッド内でblnImageProcessONはFalseとしているため、makeImageNegativeメソッドはスルーします。
//画面表示
最後にFrameQueueBufferに格納された画像を「 if (blnDiplayOnOff) icImagingControl1.DisplayImageBuffer(buffer);」に引き渡し、DisplayImageBufferで受け取った画像を画面表示しています。
[画像処理開始 FrameQueueSink]ボタンをクリックしたときの処理
private void cmdImageProcessStartFrameQueueSink_Click(object sender, EventArgs e)
{
//画像処理ON
blnImageProcessON = true;
if (!icImagingControl1.LiveVideoRunning)
icImagingControl1.LiveStart();
}
//非同期処理の定義
public delegate void ImageProcessDelegate(IFrameQueueBuffer imgBuffer);
//非同期処理の実行
private FrameQueuedResult Callback_FrameQueueSink(IFrameQueueBuffer buffer)
{
BeginInvoke(new ImageProcessDelegate(ImageProcess), buffer);
return FrameQueuedResult.ReQueue;
}
private void ImageProcess(IFrameQueueBuffer imgBuffer)
{
//録画開始
if (_writer != null & blnRecordON ) _writer.Write(imgBuffer);
//画像処理
if (blnImageProcessON) makeImageNegative(imgBuffer);
//画面表示
if (blnDiplayOnOff) icImagingControl1.DisplayImageBuffer(imgBuffer);
}
private int imageNumber = 0;
private void makeImageNegative(TIS.Imaging.IFrame imgBuffer)
{
int bytesPerLine = imgBuffer.FrameType.BytesPerLine;
int lines = imgBuffer.FrameType.Height;
double sum = 0.0;
int count = 0;
bool blnOK = true;
string fileName_imageprocess = ""Image_imageprocess "" + imageNumber + "".bmp"";
unsafe
{
//画像処理
byte* pDatabyte = imgBuffer.Ptr;
for (int y = 0; y < lines; y++)
{
for (int x = 0; x < bytesPerLine; x++)
{
*pDatabyte = (byte)(255 - *pDatabyte);
byte value = *pDatabyte;
sum += value;
count++;
pDatabyte++;
}
}
}
double average = sum / count;
//輝度値平均値が150だったらNG判定としています。
if (average > 150) blnOK = false;
else blnOK = true;
//NGのものだけを保存
if (blnOK == false)
{
TIS.Imaging.FrameExtensions.SaveAsBitmap(imgBuffer, fileName_imageprocess);
imageNumber += 1;
}
}
上記はIC Imaging ControlのLiveStartを定義したものです。
cmdImageProcessStartFrameQueueSink_Clickメソッドは、【画像処理開始 FrameQueueSink】ボタンがクリックされたときに呼び出されます。
LiveStartをすることで「■フォームを立ち上げたときのイベント」にて_frameQueueSink = new FrameQueueSink(Callback_FrameQueueSink, MediaSubtypes.RGB32, 5);と定義したコールバック関数Callback_FrameQueueSinkが呼び出されます。
//画像処理ON
画像処理を開始するために、画像処理ON/OFFを制御するフラグblnImageProcessONをONにしています。
//非同期処理の定義
画像処理、画面表示を非同期で実行する為にIFrameQueueBufferを引数に取るデリゲートとしてImageProcessDelegateを宣言し、非同期処理の定義をします。
//非同期処理の実行
Callback_FrameQueueSinkメソッドはカメラから送られた画像を受け取ったタイミングで呼び出されます。その後、Callback_FrameQueueSinkメソッド内でBeginInvokeを使用して非同期処理を実行し、ImageProcessメソッドに引き渡します。次に、Callback_FrameQueueSinkの戻り値に、コールバック関数内で処理したフレームを使用するために再びキューに入れています。
//録画開始
blnRecordON(録画開始フラグON)の時にはFrameQueueBufferに格納された画像imgBufferを使ってWriteメソッド(MediaFoundationのAPIをラップしたメソッド)で録画開始(シンク ライターにビデオ フレームを送信)しています。
//画像処理
ImageProcessメソッド内ではcmdImageProcessStartFrameQueueSink_Clickメソッド内でblnImageProcessONはtrueとしているため、makeImageNegativeメソッドを実行します。
makeImageNegative関数内ではFrameQueueBufferに格納された画像imgBufferを使って画像処理を実行します。まず、imgBuffer.FrameType.BytesPerLineやimgBuffer.FrameType.Heightで取得した画像のピクセルサイズを取得します。次にポインタを使って画像データへ直接アクセスするためにunsafeを使っています。ポインタ使ってバッファの1画素1画素にアクセスし、その輝度値を反転させるために、バッファー内の各ピクセル値を255から引いています。そして、輝度値平均を求めて輝度値平均が150以上だったらNG判定するようにしています。NG判定の時にはBitmap形式で画像処理後のバッファを保存するようにしています。
//画面表示
次に、ImageProcessメソッド内で【画面表示ON blnDiplayOnOff=True】ボタンと【画面表示False blnDiplayOnOff=False】ボタンで切り替えられたフラグ:blnDiplayOnOffをもとに画像処理後のバッファを画面上にDisplayImageBufferメソッドで表示しています。
[画像処理停止 FrameQueueSink]ボタンをクリックしたときの処理
private void cmdImageProcessStopFrameQueueSink_Click(object sender, EventArgs e)
{
//画像処理OFF
blnImageProcessON = false;
}
"cmdImageProcessStopFrameQueueSink_Clickメソッドは、[画像処理停止 FrameQueueSink]ボタンがクリックされたときに呼び出されます。 FrameQueueSinkのSinkでLiveStartした状態の時に呼び出されるコールバック関数内で画像処理しないようにblnImageProcessONをFalseにしています。"
[録画開始 NAudio]ボタンをクリックしたときの処理
private void cmdRecordStartFrameQueueSink_Click(object sender, EventArgs e)
{
if (!icImagingControl1.LiveVideoRunning)
icImagingControl1.LiveStart();
//録画開始ON
blnRecordON = true
int BITRATE = 60 * 1000000;
_writer = new MFTestSharp.H264Writer(_FileName, icImagingControl1.VideoFormatCurrent.FrameType, (int)icImagingControl1.DeviceFrameRate, BITRATE);
_writer.Begin();
}
//非同期処理の定義
public delegate void ImageProcessDelegate(IFrameQueueBuffer imgBuffer);
//非同期処理の実行
private FrameQueuedResult Callback_FrameQueueSink(IFrameQueueBuffer buffer)
{
BeginInvoke(new ImageProcessDelegate(ImageProcess), buffer);
return FrameQueuedResult.ReQueue;
}
private void ImageProcess(IFrameQueueBuffer imgBuffer)
{
//録画開始
if (_writer != null & blnRecordON ) _writer.Write(imgBuffer);
//画像処理
if (blnImageProcessON) makeImageNegative(imgBuffer);
//画面表示
if (blnDiplayOnOff) icImagingControl1.DisplayImageBuffer(imgBuffer);
上記はIC Imaging ControlのLiveStartを定義したものです。cmdRecordStartFrameQueueSink_Clickメソッドは、【録画開始 NAudio】ボタンがクリックされたときに呼び出されます。
LiveStartをすることで「■フォームを立ち上げたときのイベント」にて_frameQueueSink = new FrameQueueSink(Callback_FrameQueueSink, MediaSubtypes.RGB32, 5);と定義したコールバック関数ImageProcessが呼び出されます。
//録画開始ON
録画処理をするため、録画を開始するためにMicrosoft Media Foundationを使ってビットレートは60*1,000,000(60M) bpsでH.264コーデックでビデオファイルを保存する処理をするために、MediaFoundationのH264WriterメソッドでH.264コーデックの録画の開始するための準備をしています。その後、録画開始ON/OFFを制御するフラグblnRecordONをONにしています。
//非同期処理の定義
録画開始、画像処理、画面表示を非同期で実行する為にIFrameQueueBufferを引数に取るデリゲートとしてImageProcessDelegateを宣言し、非同期処理の定義をします。
//非同期処理の実行
Callback_FrameQueueSinkメソッドはカメラから送られた画像を受け取ったタイミングで呼び出されます。その後、Callback_FrameQueueSinkメソッド内でBeginInvokeを使用して非同期処理を実行し、ImageProcessメソッドに引き渡します。次に、Callback_FrameQueueSinkの戻り値に、コールバック関数内で処理したフレームを使用するために再びキューに入れています。
//録画開始
blnRecordON(録画開始フラグON)の時にはFrameQueueBufferに格納された画像imgBufferを使ってWriteメソッド(MediaFoundationのAPIをラップしたメソッド)で録画開始(シンク ライターにビデオ フレームを送信)しています。
//画像処理
次に、blnImageProcessON(画像処理フラグON)の時に画像処理を実行するようにしています。画像処理についてmakeImageNegativeメソッド内にて処理しています(詳細は「■【画像処理開始 FrameQueueSink】ボタンをクリックしたときの処理」をご確認ください)。
//画面表示
最後に、ImageProcessメソッド内で【画面表示ON blnDiplayOnOff=True】ボタンと【画面表示False blnDiplayOnOff=False】ボタンで切り替えられたフラグ:blnDiplayOnOffをもとに画像処理後のバッファを画面上にDisplayImageBufferメソッドで表示しています。
[録画の中断・再開]チェックボックスを変更したときの処理
public static bool blnRecordPauseON = false;
private void checkBoxRecordPause_CheckedChanged(object sender, EventArgs e)
{
blnRecordPauseON = !blnRecordPauseON;
}
グローバル変数blnRecordPauseONを定義し、blnRecordPauseONのフラグでNAudioのAPIでフレームバッファの一時停止できるように処理を追加しています。blnRecordPauseONのフラグをFalse/Trueにすると録画の一時停止/再開になります。ただしblnRecordPauseON プロパティをFalseにしても、デバイスからのライブストリーミング自体は動いていますので、[画面表示ON LiveDisplay=True]ボタンをクリックした場合はライブ表示され、右上のカウンターもカウントアップされます。blnRecordPauseONをFalseにした後にTrueに戻すと、録画ファイルに継続して録画をし続けることができます。
[録画停止 NAudio]ボタンをクリックしたときの処理
private void cmdRecordStopFrameQueueSink_Click(object sender, EventArgs e)
{
//録画開始OFF
blnRecordON = false;
if (_writer != null)
{
_writer.End();
_writer = null;
}
}
録画の停止は[録画停止 NAudio]ボタンをクリックしたときの処理_writer.Begin();を停止すればいいので、LiveStopしなくても _writer.End();をすれば録画が正常に終了されます。録画停止後でもFrameQueueSinkでLiveStartの状態は維持されます。
[静止画保存 FrameFilter]ボタンをクリックしたときの処理
private void cmdSnapFrameQueueSink_Click(object sender, EventArgs e)
{
if (_saveImageFrameFilter != null && icImagingControl1.DeviceValid && icImagingControl1.LiveVideoRunning)
{
imageCounter++;
string imageFileName = String.Format(""Image{0}.jpg"", imageCounter);
_saveImageFrameFilter.SetStringParameter(""ImageName"", imageFileName);
}
}
ICImagingControlのFrameFilterを使用して、静止画をキャプチャして保存しています。Form_Loadの関数内で画像保存するためのFrameFilterインスタンスを_saveImageFrameFilterで作成していますので、saveImageFrameFilterのパラメータにアクセスするだけで、フィルタの設定(画像保存)を呼び出すことができます。フィルタの設定(画像保存)を呼び出すにはSetStringParameterメソッドの引数に有効なパラメーター「ImageName」を指定することでフィルターを使用することができます。FrameFilterを使うことでFrameQueueSinkを使いながらでも静止画保存の処理を割り込んで処理することができます。
[ライブストップ LiveStop]ボタンをクリックしたときの処理
private void cmdLiveStopFrameQueueSink_Click(object sender, EventArgs e)
{
icImagingControl1.DisplayImageBufferClear();
icImagingControl1.LiveStop();
if (_writer != null)
{
_writer.End();
_writer = null;
}
blnRecordON = false;
blnImageProcessON= false;
}
上記はIC Imaging ControlのLiveStopを定義したものです。cmdLiveStopFrameQueueSink_Clickメソッドは、【ライブストップ LiveStop】ボタンがクリックされたときに呼び出されます。LiveStopメソッドは、カメラからのライブストリーミングを停止します。
また、録画していたら正常に停止するために_writer.End();で録画停止メソッドを呼び出します。
最後にLiveStart時に勝手に画像処理や録画開始しないように、画像処理ON/OFFを制御するフラグblnImageProcessONと録画開始ON/OFFを制御するフラグblnRecordONを、falseにしています。
フレームカウントやフレームレートを記載する処理
//FrameQueueSinkに対して受け取ったフレーム数とドロップ数をカウント
long _countOfFramesCopied = 0;
long _countOfFramesDropped = 0;
if (_frameQueueSink != null)
{
//このSinkの出力キューにコピーされたフレーム数を返します。
_countOfFramesCopied = _frameQueueSink.CountOfFramesCopied;
//このSinkがドロップしたフレーム数を返します。
_countOfFramesDropped = _frameQueueSink.CountOfFramesDropped;
}
lbltext2.Text = _countOfFramesCopied.ToString() + ""/"" + _countOfFramesDropped.ToString() ;
画面右上にあるカメラから送られてくるフレーム数のカウントアップやフレーム落ちのカウントはDriverFrameDropInformationのプロパティを使っています。詳細については別のサンプルページにて解説を行っておりますので下記を参照ください。
上記とは別に「FrameQueueSink」の欄に、FrameQueueSinkのSinkがコピーしたフレーム数とフレーム落ちした数の順でスラッシュ(/)区切りで表示しています。