SourceChordスマートフォン用の表示で見るSourceChordC#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。OpenCVOpenCvSharpネタの続きです。今度はOpenCvSharpを使って、動画ファイルの再生をしてみます。動画ファイルの再生手順1.動画ファイルの読み込み動画ファイルを再生する時にはCvCaptureというクラスを使います。↓のように、CvCaputureクラスのコンストラクタに、ファイルのパスを渡してインスタンスを生成します。動画の各フレームは、QueryFrameメソッドを呼ぶと取得できます。このメソッドは動画の最後まで行くとnullを返すようになります。capture.QueryFrame();3.WriteableBitmapへの変換QueryFrame()メソッドではIplImage型の画像が取得できるので、これをWPFのウィンドウで表示できるように変換します。変換処理はWriteableBitmapConverterクラスに色々と用意されています。今回は以下の二つの方法を使ってみました。dst);このメソッドでは、既存のWriteableBitmap上にIplImageの内容をコピーすることができます。BackgroundWorkerを使ってシンプルに実装とりあえず、BackgroundWorkerを使ってシンプルにやってみます。OpenCV側の画像をWPF用の画像クラスに変換する処理は、IplImageに用意されているToWriteableBitmap拡張メソッドを使っています。}とてもシンプルにできました。こんな風にウィンドウ上で動画の再生が行われます。タスクマネージャでメモリ消費を見てみると、モリモリとメモリ使用量が増えていきます。(ある程度増えたところでGCされてますが。)毎フレームごとに、ToWriteableBitmap()メソッドで、新規WriteableBitmapインスタンスを生成しているためですね。WriteableBitmapConverter.ToWriteableBitmapメソッドを使う無駄なメモリ消費をしないように、一度作成したWriteableBitmapを使いまわすように修正します。WriteableBitmapConverterのToWriteableBitmapメソッドを使うと、既存のWriteableBitmapに上書きすることができます。引数にコピー元のIplImageとコピー先のWriteableBitmapを渡して、↓こんな風に使います。wb);ちょっと手抜きですが、WriteableBitmapのメンバ変数を用意して、各フレームのコピーの際に使いまわすようにしてみました。}こうすると、動画のフレームを更新していってもメモリ消費が増えなくなります。async/awaitを使ってもう少しモダンに書いてみる時代はasync/awaitでしょ!!ってことで、BackgroundWorkerを使わずにasync/await構文を使って書いてみました。}}適当にasync/awaitを使って書いてみましたが、よくよく見なおしてみると、UIスレッド上でフレームのキャプチャ処理とかすべてを行っています。UIスレッドにあまり負荷をかけるのは良くないだろうということで、ちょっと修正してみました。QueryFrameを呼び出してIplImageを取得する部分をAsyncなメソッドにしてます。各フレームの画像に画像処理とかする場合は、この非同期メソッド中で行えば、UIスレッドに負荷をかけずに複雑な処理ができます。awaitできる形で、非同期にフレームの取得を行います。アプリ開発Windows開発者はてなブログをはじめよう!minami_SCさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。