OpenCVSharpで動画ファイルを再生するサンプル

上野公園内之景 コンピュータ
出典:国立国会図書館「NDLイメージバンク」 (https://rnavi.ndl.go.jp/imagebank/)
OpenCVで動画ファイルをフレーム単位で画像を取り出すことが出来たので、WinFormでGUIを用意してみました。
音声はなしですが動画再生しますし、トラックバーの移動に合わせて再生位置を変更することが出来ました。

dotnetバージョン

 dotnet --version
6.0.301

プロジェクトの作成


dotnet new winforms -n MovieSample
cd MovieSample
dotnet add package OpenCvSharp4
dotnet add package OpenCvSharp4.Extensions
dotnet add package OpenCvSharp4.runtime.win

プログラムソース

ファイル名:Form1.cs

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 OpenCvSharp;
using OpenCvSharp.Extensions;

namespace MovieSample
{
    public partial class Form1 : Form
    {
        PictureBox picbox1 = new PictureBox
        {
            Dock = DockStyle.Fill,
        };
        Button button1 = new Button
        {
            Dock = DockStyle.Bottom,
            Text = "Start",
            Height = 80,
        };
        TrackBar trackBar1 = new System.Windows.Forms.TrackBar
        {
            Dock = DockStyle.Bottom,
        };
        VideoCapture vc;
        System.Timers.Timer timer = new System.Timers.Timer();

        string path = @"C:\Users\karet\Videos\sample.mov";

        private void readFrame()
        {
            using(var mat = new Mat())
            {
                if (this.vc.Read(mat))
                {
                    if (mat.IsContinuous())
                    {
                        picbox1.Invoke(new Action(() =>
                        {
                            if (picbox1.Image != null)
                            {
                                picbox1.Image.Dispose();
                            }
                            picbox1.Image = BitmapConverter.ToBitmap(mat);
                        }));
                    }
                }
            }
        }

        public Form1()
        {
            InitializeComponent();


            this.Controls.Add(button1);
            this.Controls.Add(picbox1);
            this.Controls.Add(trackBar1);

            this.vc = new VideoCapture(path);
            if (!this.vc.IsOpened())
            {
                MessageBox.Show("読み込めません!");
                return;
            }
            this.timer.Interval = (int)(1000/vc.Fps);

            trackBar1.Maximum = (int)vc.FrameCount;

            this.timer.Elapsed += (s, e) =>
            {
                try
                {
                    timer.Stop();
                    readFrame();
                    trackBar1.Invoke(new Action(() =>
                    {
                        trackBar1.Value = (int)this.vc.PosFrames;
                    }));
                }
                finally
                {
                    timer.Start();
                }
            };
            this.Load += (s, e) =>
            {
                this.button1.Text = "Start";
                this.trackBar1.Enabled = true;
                this.timer.Stop();
                readFrame();
            };

            this.FormClosed += (s, e) =>
            {
                timer.Stop();
                using(timer){}
            };

            this.button1.Click += (s, e) =>
            {
                if (this.button1.Text == "Start")
                {
                    this.button1.Text = "Stop";
                    trackBar1.Enabled = false;
                    this.timer.Start();
                }
                else
                {
                    this.button1.Text = "Start";
                    trackBar1.Enabled = true;
                    this.timer.Stop();
                }
            };

            trackBar1.ValueChanged += (s, e) =>
            {
                if (this.button1.Text == "Start")
                {
                    this.vc.PosFrames = trackBar1.Value;

                    readFrame();
                }
            };

        }// Form1
    }// class
}// ns

実行例

起動するとpathで指定した動画ファイルが読み込まれ最初のフレームが表示される。動画の再生は停止状態。

トラックバーのつまみを動かすとフレームが移動する。

「Start」ボタンを押すと動画が再生される。

「Stop」ボタンを押すと動画が停止します。ボタンの押し込みがすり抜けて再生し続ける現象あり。
機能確認が出来たのでチャプターを打つアプリを作りたいと思います。

コメント