【C#】カメラでQRコード読み取り

前回のQRコード読み取りを利用して、カメラでQRコード解析してみました。

■参考記事
[【C#】PCカメラから映像を取得するアプリ](http://www.programmingtheworld.com/index.php/2020/04/11/cs-pc-camera-app/#AForgeNET)

## 事前準備
Nugetパッケージは、前回の記事同様に以下をインストール。
・OpenCvSharp3
・ZXing.Net

[AForge.NET](http://www.aforgenet.com/framework/downloads.html)
※「[ Download Libraries Only ]」のリンクからzipをダウンロードします。

![dll.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/46d244d1-96a1-80b8-5296-c5127743abf7.png)
「AForge.Video.DirectShow.dll」「AForge.Video.dll」のDLLを使用しました。

![dll2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/675b5572-4b08-0f9f-d67e-2f93ef84c8a0.png)
「参照の追加」でこの二つを追加。

## コード
### カメラの種類のコンボボックス
画面表示時の処理で呼ぶとよい。

        public void getCameraInfo()
        {
            try
            {
                // 端末で認識しているカメラデバイスの一覧を取得
                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                cmbCamera.Items.Clear();

                if (videoDevices.Count == 0)
                    throw new ApplicationException();

                foreach (FilterInfo device in videoDevices)
                {
                    //カメラデバイスの一覧をコンボボックスに追加
                    cmbCamera.Items.Add(device.Name);
                    cmbCamera.SelectedIndex = 0;
                    DeviceExist = true;
                }
            }
            catch (ApplicationException)
            {
                DeviceExist = false;
                cmbCamera.Items.Add("Deviceが存在していません。");
            }

        }
### 開始/終了ボタン
        private void btnExec_Click(object sender, EventArgs e)
        {
            if (btnExec.Text == "開始")
            {
                if (cmbCamera.Items.Count == 0)
                {
                    System.Windows.Forms.MessageBox.Show("カメラがありません。", "実行エラー");
                    return;
                }
                if (DeviceExist)
                {
                    videoSource = new VideoCaptureDevice(videoDevices[cmbCamera.SelectedIndex].MonikerString);
                    videoSource.NewFrame += new NewFrameEventHandler(videoRendering);
                    this.CloseVideoSource();

                    videoSource.Start();

                    btnExec.Text = "停止";
                }
            }
            else
            {
                if (videoSource.IsRunning)
                {
                    this.CloseVideoSource();
                    btnExec.Text = "開始";

                }
            }
        }

### カメラ読み取り中のイベント
        private void videoRendering(object sender, NewFrameEventArgs eventArgs)
        {
            Bitmap img = (Bitmap)eventArgs.Frame.Clone();

            try
            {
                qrRead(img);
                pictureBoxCamera.Image = img;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
            }
        }

### QR読み取り処理
       private void qrRead(System.Drawing.Image image)
        {


            try
            {
                Bitmap myBitmap = new Bitmap(image);

                string text = string.Empty;

                using (Mat imageMat = OpenCvSharp.Extensions.BitmapConverter.ToMat(myBitmap))
                {

                    // QRコードの解析
                    ZXing.BarcodeReader reader = new ZXing.BarcodeReader();

                    //テンポラリパス
                    for (int i = 0; i < maxFilterSize; i++)
                    {

                        //奇数にする必要があるので、さらに加算
                        i++;

                        //偶数を指定するとExceptionが発生します。
                        int filterSize = i;

                        //別変数のMATにとる
                        using (Mat imageMatFilter = imageMat.GaussianBlur(new OpenCvSharp.Size(filterSize, filterSize), 0))
                        {
                            //ビットマップに戻します
                            using (Bitmap filterResult = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(imageMatFilter))
                            {
                                try
                                {
                                    //QRコードの解析
                                    ZXing.Result result = reader.Decode(filterResult);

                                    //これでQRコードのテキストが読める
                                    if (result != null)
                                    {
                                        text = result.Text;
                                        System.Windows.Forms.MessageBox.Show(text, "読み取り値"); //メッセージポップアップ
                                        return;
                                    }
                                }
                                catch
                                {
                                }

                            }


                        }

                    }
                }

            }
            catch (Exception ex)
            {
                //システムエラー発生時
                System.Windows.Forms.MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
                this.Close();
            }
            finally
            {

            }
        }

## git
ソースは一式、ここにあります。
某クラウドソーシングで、提案の際にプロトとして作ってみたものです。不採用でしたが・・。
コードは、整理しきれていませんが、プロトタイプということで・・。
https://github.com/ogayasuhito/QrcodeAndCamera.git

## 実行
対象のカメラの種類を選んで、「開始」ボタンで読み取り開始されます。
QRコードが読み取られると、メッセージボックスで内容が表示されます。（読み取り値のやつ）
カメラに写っているのは、下のピクチャーボックスに表示
![qr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/5f3dc7f7-f796-b19b-bac0-c22e62a7fe68.png)

何かの機能追加の際とかに、コピペで使える・・かも？