3

私は現在、EmguCV (OpenCV Wrapper) を使用してキュー内の人々を追跡するシステムを開発しようとしています。まず、ダウンロードした Emgu パッケージに含まれている VideoSurveilance の例を実行して理解することから始めました。例に基づいた私のコードは次のとおりです。

    private static void processVideo(string fileName)
    {
        Capture capture = new Capture(fileName);
        MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 
            1.0, 1.0);
        BlobTrackerAuto<Bgr> tracker = new BlobTrackerAuto<Bgr>();

        //I'm using a class that I implemented for foreground segmentation
        MyForegroundExtractor fgExtractor = new MyForegroundExtractor();

        Image<Bgr, Byte> frame = vVideo.QueryFrame();
        fgExtractor.initialize(frame);

        while (frame != null)
        {
            Image<Gray, Byte> foreground = fgExtractor.getForegroundImg(frame);
            tracker.Process(frame, foreground);

            foreach (MCvBlob blob in tracker)
            {
                if (isPersonSize(blob))
                {
                    frame.Draw((Rectangle)blob, new Bgr(0, 0, 255), 3);
                    frame.Draw(blob.ID.ToString(), ref font, 
                        Point.Round(blob.Center), new Bgr(255.0, 255.0, 255.0));
                }
            }
            CvInvoke.cvShowImage("window", frame);
            CvInvoke.cvWaitKey(1);

            frame = capture.QueryFrame();
        }
    }

上記のコードは、AVI ビデオの各フレームを処理し、処理されたフレームをシーン内の各人物の周りに赤い四角形で表示することを目的としています。VideoSurveilance の例で使用されているクラスを使用して取得した結果が気に入らなかったIBGFGDetector<Bgr>ため、CvInvoke.cvRunningAvg()、CvInvoke.cvAbsDiff()、CvInvoke などの Emgu の関数を使用して、独自の前景検出器を使用しようとしています。 cvThreshold() および cvErode/cvDilate()。いくつか問題があります:

  1. ビデオは、すでにシーンにいる数人から始まります。ビデオの開始時にシーンにいる人に対応するブロブを取得していません。
  2. 数フレームの間人を「失う」ことがあります。人の周りに赤い四角形を数秒間/フレーム描画し、消えてしばらくすると別の ID で再び描画されます。
  3. サンプル コードからわかるように、ブロブが高さと幅をチェックしている人物であるかどうかを確認し (isPersonSize() メソッド)、テストに合格したものだけに赤い四角形を描画します。人の大きさでないものをどのように削除できますか?
  4. 人がその場にいる時間を計測したい。ブロブがいつ消えたかを知る最良の方法は何ですか? 人々に対応すると思われるブロブのIDを配列に保存し、各ループでそれぞれがまだそこにあるかどうかを確認する必要がありtracker.GetBlobByID()ますか?
  5. ループ内のすべてのフレームを処理しないと、より良い結果が得られると思います。3 フレームごとに処理するカウンター変数と if ステートメントを追加しました。

    if (i % 3 == 0)
        tracker.Process(frame, foreground);
    

プログラムの実行が非常に遅かったので、if ステートメントを追加しました。でもそれをしたら、以前はできなかった人を追跡できるようになりました。

要約すると、OpenCV/EmguCV に慣れている人が、BlobTrackerAuto を使用して人々を追跡するのが良い方法であるかどうかを教えてくれたり、上記の問題について私を助けてくれたりして、本当に感謝しています。EmguCV が提供するツールを活用していないように感じます。

4

0 に答える 0