2016/12/26 【OpenCVSharp,c#】Webカメラの映像を保存する
半年程前にAndroidをWebカメラの代わりにして画像処理をする記事を書いたのですが、
この時に撮った映像を保存したいときにはどうするの?
という質問を頂いたのでここに書いておきます。
OpenCVSharpで動画ファイルを作成する方法ですが、
OpenCVSharpの中に入っているCvVideoWriterというクラスを使用すれば
AVI形式の動画ファイルを作成することができるみたいです。
cvVideoWriterの基本的な使い方としては、
初期化、書き込み、終了の3つの処理を書いておけば良いようです。
初期化の処理は下の通りです。
CvVideoWriter video = new CvVideoWriter("video.avi", FourCC.MJPG, 60, new CvSize(320, 240));第一引数がファイル名、第二引数が動画の圧縮の方法、
第三引数がFPS、第四引数が動画のサイズです。
第二引数の動画の圧縮方法についてはあまり詳しくはないのですが、
使っているパソコンにどのcodecが入っているかによって
使える圧縮方法が違ってくるのではないか?と思います。
この部分にFourCC.DIBを指定すると圧縮せずに動画を作ることが出来ますが、
動画の容量が凄いことになったので止めておきました。
書き込みの処理は次のようになりました。
video.WriteFrame(image);
書き込みたい動画のWriteFrame()関数を呼び出してIplImage型の変数(image)を与えると
動画の一番後ろに1フレーム書き込んでくれるみたいです。
ですので、この関数を何度も呼び出しながら動画を作っていくことになります。
終了の処理は下のようになりました。
video.Dispose();
また、このクラスを使ってWebカメラの映像を保存するプログラムを作ってみました。
フォームの外観は下のような感じで、pictureBoxIpl1にWebカメラの映像を映しながら
Recボタンが押されているときにはその映像を保存するようにします。
プログラムは下のようになりました。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Drawing.Drawing2D; using OpenCvSharp; using OpenCvSharp.Extensions; namespace cSharpOpenCV { public partial class cSharpOpenCV : Form { BackgroundWorker worker; CvVideoWriter video; public cSharpOpenCV() { InitializeComponent(); worker = new BackgroundWorker(); // 非同期をキャンセルさせる worker.WorkerSupportsCancellation = true; // ProgressChangedイベントを発生させるようにする worker.WorkerReportsProgress = true; // ReportProgressメソッドで呼ばれるProgressChangedのイベントハンドラを追加 worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); // RunWorkerAsyncメソッドで呼ばれるDoWorkに、 // 別スレッドでUSBカメラの画像を取得し続けるイベントハンドラを追加 worker.DoWork += new DoWorkEventHandler(worker_DoWork); } private void worker_DoWork(object sender, DoWorkEventArgs e) { // カメラからの映像を受け取る using (var capture = Cv.CreateCameraCapture(CaptureDevice.Any)) { IplImage frame; while (true) { frame = Cv.QueryFrame(capture); // 新しい画像を取得したので、 // ReportProgressメソッドを使って、ProgressChangedイベントを発生させる worker.ReportProgress(0, frame); } } } private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { // frameがe.UserStateプロパティにセットされて渡されてくる IplImage image = (IplImage)e.UserState; CvSize size = new CvSize(320, 240); IplImage reImage = new IplImage(size, image.Depth, image.NChannels); Cv.Resize(image, reImage, Interpolation.NearestNeighbor); if (label1.Text == "Rec") { // 動画ファイルに書き込み video.WriteFrame(reImage); } pictureBoxIpl1.ImageIpl = reImage; } private void Form1_Load(object sender, EventArgs e) { // .aviファイルを開く video = new CvVideoWriter("video.avi", FourCC.MJPG, 60, new CvSize(320, 240)); // DoWorkイベントハンドラの実行を開始 worker.RunWorkerAsync(); } private void cSharpOpenCV_FormClosing(object sender, FormClosingEventArgs e) { // 動画ファイルを閉じる video.Dispose(); } private void recButton_Click(object sender, EventArgs e) { label1.Text = "Rec"; } private void stopButton_Click(object sender, EventArgs e) { label1.Text = "Stop"; } } }フォームを開いたときに.aviファイルを開いて、
フォームを閉じるときに.aviファイルも閉じるようにしています。
カメラの映像を映す部分は前回の記事と同じです。
3行書くだけで動画を作ってくれるので
OpenCVSharpは便利だなぁーと改めて感じました。
-
Please
- feedly
- hatena bookmark
- Google plus
Share!