0

ウェブカメラを通して人の上半身と下半身を検出するアプリケーションを開発しようとしています。emguの顔検出について調べてみたところ、「haarcascade_upperbody.xml」と「haarcascade_lowerbody.xml」をダウンロードしました。与えられた顔検出と同じものをコーディングしようとしました

しかし問題は、それが私の体を検出できず、もはやリアルタイムではないことです。3秒遅れ?

これが私のコードです。誰かが私を助けてくれることを願っています:

private void ProcessFrame(object sender, EventArgs arg)
    {
        Image<Bgr, Byte> ImageFrame = capture.QueryFrame();
        FittingBox.Image = ImageFrame;

        long detectionTime;

        List<Rectangle> upper = new List<Rectangle>();
        List<Rectangle> lower = new List<Rectangle>();
        Detect(ImageFrame,"haarcascade_upperbody.xml","haarcascade_lowerbody.xml",upper,lower,out detectionTime);
        foreach (Rectangle up in upper)
            ImageFrame.Draw(up, new Bgr(Color.Red), 2);
        foreach (Rectangle low in lower)
            ImageFrame.Draw(low, new Bgr(Color.Blue), 2);
    }



 public static void Detect(Image<Bgr, Byte> image, String upperFileName, String lowerFileName, List<Rectangle> upperbody, List<Rectangle> lowerbody, out long detectionTime)
    {
        Stopwatch watch;

        if (GpuInvoke.HasCuda)
        {
            using (GpuCascadeClassifier upper = new GpuCascadeClassifier(upperFileName))
            using (GpuCascadeClassifier lower = new GpuCascadeClassifier(lowerFileName))
            {
                watch = Stopwatch.StartNew();
                using (GpuImage<Bgr, Byte> gpuImage = new GpuImage<Bgr, byte>(image))
                using (GpuImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>())
                {
                    Rectangle[] upperRegion = upper.DetectMultiScale(gpuGray, 1.1, 10, Size.Empty);
                    upperbody.AddRange(upperRegion);
                    foreach (Rectangle f in upperRegion)
                    {
                        using (GpuImage<Gray, Byte> upperImg = gpuGray.GetSubRect(f))
                        {
                            using (GpuImage<Gray, Byte> clone = upperImg.Clone())
                            {
                                Rectangle[] lowerRegion = lower.DetectMultiScale(clone, 1.1, 10, Size.Empty);

                                foreach (Rectangle e in lowerRegion)
                                {
                                    Rectangle lowerRect = e;
                                    lowerRect.Offset(f.X, f.Y);
                                    lowerbody.Add(lowerRect);
                                }
                            }
                        }
                    }
                }
                watch.Stop();
            }
        }
        else
        {
            using (CascadeClassifier upper = new CascadeClassifier(upperFileName))
            using (CascadeClassifier lower = new CascadeClassifier(lowerFileName))
            {
                watch = Stopwatch.StartNew();
                using (Image<Gray, Byte> gray = image.Convert<Gray, Byte>())
                {
                    gray._EqualizeHist();
                    Rectangle[] upperDeteced = upper.DetectMultiScale(
                        gray,
                        1.1,
                        10,
                        new Size(50, 50),
                        Size.Empty);

                    foreach (Rectangle f in upperDeteced)
                    {
                        gray.ROI = f;

                        Rectangle[] lowerDetected = lower.DetectMultiScale(
                            gray,
                            1.1,
                            10,
                            new Size(50, 50),
                            Size.Empty);
                        gray.ROI = Rectangle.Empty;

                        foreach (Rectangle e in lowerDetected)
                        {
                            Rectangle lowerRect = e;
                            lowerRect.Offset(f.X, f.Y);
                            lowerbody.Add(lowerRect);
                        }
                    }
                }
                watch.Stop();
            }
        }
        detectionTime = watch.ElapsedMilliseconds;
    }  
4

2 に答える 2

0

これは古いものですが、時間のコストは私にとってより興味深いものです。

あなたが言うように

"しかし、両方の問題に対処"

  1. それは私の体を検出しないということです
  2. もはやリアルタイムではありません。3秒遅れ?

最初に #2 から始めます。

3 秒で、haar カスケードを適用するのに 3 秒かかることを意味すると仮定しましょう。私見と経験、それは多くの要因によるものです。

ハール カスケードを処理する時間は、高さと幅のピクセル数、および使用されるパラメーターの点で、ターゲット オブジェクトのサイズに相当します。

さらに、DetectMultiScale パラメータはパフォーマンスに影響します。私のかなり頑丈なマシンでは、次の設定で画像を処理するのに 1.5 秒かかる 1280x720 の MP4 フレーム幅が表示されます。

    scaleFactor = 1.07
    minNeighbors = 2 
    minSize = 8,8
    maxSize = 200,200 

「webm」720p は、同じ設定を 1 秒で処理できます。これらの設定をいじることで、分類器を調整して速度を上げたり下げたりすることができます。鉱山サンプルの画面にいくつかのコントロールを配置し、少し調整しました。

単純で小さい単一のテスト jpg 画像では、200 ミリ秒のようにかなり高速です。

HOG FindPedestrian.Find は、150 ミリ秒の約 1/10 の時間で体全体を見つけるのに非常に高速で正確です。これは、私の I7 (GPU を使用していない) で再び約 7 fps (フレーム/秒) に十分な速さです。

あなたの最初の問題に関して:

1>それは私の体を検出しないということですか?

わかりました、EMGU サンプルから借用したコード スニペットは、顔の中の目を検出するものです。

  • 目は顔の内側に入ります。
  • 下半身は上半身の中にありません。

Hog を使用して体の相対的な位置を見つけ、その画像スニペットを haar の下部と上部の検出器に渡すと、画像全体をスキャンするよりも応答が大幅に速くなる可能性があります。

何かを見つけるには、設定をいじったり微調整したりする必要があると思います。

また、アッパー内のロワーを検索するロジックを修正します。

于 2015-02-24T21:59:00.827 に答える