OpenCVとカメラを使ったフォームアプリケーション

はじめに

カメラで撮影した画像を、OpenCVで処理してからフォームアプリで表示させたかったので作成した。
撮影+画像処理はbackgroundWorker内で行い、timerでbackgroundWorkerを定期的に呼び出すことにした。

ツールのレイアウト

  • TableLayoutPanel
  • PictureBox
  • label
  • backgroundWorker
  • timer
    を配置する

コード

Nugetから「OpenCvSharp4」と「OpenCvSharp4.runtime.win」をインストール
backgroundWorkerやtimerの動作は、「Form1.cs[デザイン]」内の要素をダブルクリックするか、「Form1.Designer.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;  

namespace cvvideo  
{  
    public partial class Form1 : Form  
    {  
        MyImageProcessing MIP = new MyImageProcessing();  
        private Mat dstImg = new Mat(); //PictureBox表示用のmat  
        private int tickCount = 0; //撮影数をカウントする変数  


        public Form1()  
        {  
            InitializeComponent();  
        }  


        private void Form1_Load(object sender, EventArgs e) //Form起動時の処理  
        {  
            label1.Text = "START";  

            //backgroundworkerの設定  
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);  
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);  


            timer1.Enabled = false; //タイマーを止めておく  
            label1.Text = "PictureBoxクリックで撮影開始";  
        }  

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) //backgroundworkerで行う処理  
        {  
            Mat mat = new Mat();  
            MIP.TakePicture(mat);  
            mat = MIP.ImageProcessing(mat);  
            e.Result = mat; //結果を出力  
        }  

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) //backgroundworkerのDoWork終了時に行う処理  
        {  
            dstImg = (Mat)e.Result; //処理結果を受け取る。  
            updateImg();  
        }  

        private void timer1_Tick(object sender, EventArgs e) //timer起動時に行う処理  
        {  

            if (!backgroundWorker1.IsBusy) //backgroundがビジーでないことを確認  
            {  
                label1.Text = tickCount.ToString() + " tick";  
                tickCount++;  

                backgroundWorker1.RunWorkerAsync(); //backgroundworkerの処理実行  
            }  

        }  

        private void updateImg() //PictureBoxの画像を更新する。  
        {  
            pictureBox1.Image = MIP.MatToBitmap(dstImg);  
        }  


        private void pictureBox1_Click(object sender, EventArgs e)  
        {  
            timer1.Enabled = !timer1.Enabled; //タイマー動作/停止を切り替え  
            if (timer1.Enabled)  
            {  
                label1.Text = "timer enabled";  
            }  
            else  
            {  
                label1.Text = "timer unenabled";  
            }  
        }  


    }  

    public class MyImageProcessing //画像処理クラス  
    {  
        VideoCapture capture = new VideoCapture(0); //撮影用のクラス  

        public Bitmap MatToBitmap(Mat src) //matをbitmapに変換する  
        {  
            return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);  
        }  

        public void TakePicture(Mat dst) //カメラを使って撮影する  
        {  

            Mat img = new Mat();  
            capture.Read(img);  

            if (img.Empty()) //撮影失敗  
            {  

            }  
            else //撮影成功  
            {  
                img.CopyTo(dst);  
            }  

        }  

        public Mat ImageProcessing(Mat src) //画像処理  
        {  
            Mat mat = new Mat();  
            src.CopyTo(mat);  
            Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2GRAY);  
            Cv2.ApplyColorMap(mat, mat, ColormapTypes.Cividis);  

            return mat;  
        }  


    }  

}