2015年9月3日木曜日

OpenCvSharpでWebカメラを表示する

Webカメラというか、USBビデオクラス(UVC)を使用するUSBカメラを表示するためのサンプル。USBカメラを表示したかったが録画する機能とかもいらないしサクッと作ってみた。

OpenCvSharpで読み込んでC#のフォームに表示してもいいが、今回は手っ取り早くOCvで表示まで行った。

ソースコードはオブジェクト指向とは思えないような感じになってる。がまぁ動作してるので。。。

文字列入力を読み込みたかったので、スレッドでQueue<string>にConsole.ReadLineを読み込んでいる。一般的には「CvのWindowで何かキーを押せば終了」だと思うが、このコードはConsoleにquitを入力することで終了する。Console.ReadLineは同期読み込みだから、途中で読み込みを止めたいと思っても止められない(はず)。ということで最後にユーザーがEnterを入力してやる必要がある。Inのストリームを引っ張ってきて自前で処理すればいいかもしれないが、今回は面倒だったのでやってない。

解像度は「適切な(縦横比の)解像度で縦横を連続して設定すると適用される」みたいな動作になってるのでハードコードしてやった。

リアルタイムで映像を表示するだけの機能しかないが、画角の確認だとかフォーカスの確認くらいなら可能。





using System;
using System.Collections.Generic;
using OpenCvSharp;
using System.Threading;

namespace UVCMonitor
{
    class Program
    {
        static void Main(string[] args)
        {
            bool IsLoop = true;

            Queue<string> ConsoleInput = new Queue<string>();

            Thread t = new Thread(new ThreadStart(delegate ()
            { while (IsLoop) { ConsoleInput.Enqueue(Console.ReadLine()); } }));

            t.Start();

            const string WindowName = "Camera";

            try
            {
                Cv.NamedWindow(WindowName);

                using (CvCapture Cap = Cv.CreateCameraCapture(0))
                {
                    Cap.SetCaptureProperty(CaptureProperty.FrameWidth, 320);
                    Cap.SetCaptureProperty(CaptureProperty.FrameHeight, 240);

                    while (IsLoop)
                    {
                        using (IplImage Image = Cap.QueryFrame())
                        { Cv.ShowImage(WindowName, Image); }

                        if (Cv.WaitKey(1) != -1)
                        //{ break; } /* breakのコメントアウトを解除すると表示画面でキーを押した時に終了 */
                        { } /* 上のブロックをまるごとコメントアウトするためのダミー */

                        while (ConsoleInput.Count > 0)
                        {
                            string Line = ConsoleInput.Dequeue();

                            if (Line.Equals("quit"))
                            { IsLoop = false; continue; }

                            if (Line.Equals("property"))
                            {
                                foreach(CaptureProperty prop in Enum.GetValues(typeof(CaptureProperty)))
                                {
                                    double Value = Cap.GetCaptureProperty(prop);
                                    if (Value == -1) { continue; }
                                    Console.WriteLine(Value + "\t" + prop.ToString());
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }

            Cv.DestroyAllWindows();

            /* おそらくスレッドで行読み込みが動いているのでユーザーに止めさせる */
            Console.WriteLine("終了します Enterキーを押して下さい");
        }
    }
}

0 件のコメント:

コメントを投稿