使用haarcascade的emgucv bodydetection

时间:2013-09-29 11:17:24

标签: c# winforms emgucv

我正在尝试开发一种应用程序,通过网络摄像头检测人的上半身和下半身。我试着看看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;
    }  

2 个答案:

答案 0 :(得分:0)

我认为找到一个直立位置的人体的最佳方法是随OpenCV附带的行人探测器。您不需要任何培训,因为它已经在HogDescriptor中实现。

有关emguCV的信息,请参阅this example。至于使用级联的代码,我从未尝试过这些预先训练过的级联,所以我不知道他们接受过哪种训练。

答案 1 :(得分:0)

这是旧的,但我更感兴趣的是时间成本。

正如你所说

  

“但要解决这两个问题”

  1. 是它不会检测到我的身体和
  2. 它不再是实时的。它延迟了3秒钟?
  3. 首先从#2开始:

    让我们假设3秒你的意思是需要3秒才能应用haar级联。恕我直言经验,这是由于许多因素造成的。

    处理haar级联的时间与像素高度和宽度的数量以及所使用的参数的目标对象的大小相当。

    此外,DetectMultiScale参数将影响性能。在我相当强壮的机器上,我看到MP4框架宽度为1280x720需要1.5秒来处理具有以下设置的图像:

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

    “webm”720p能够在1秒内处理相同的设置。您可以通过播放这些设置来调整分类器以使其更快或更慢。我在屏幕上放了一些控件用于我的我的样品并调整了一下。

    在简单的小型单测试jpg图像上,它的速度相当于200毫秒。

    HOG FindPedestrian.Find非常快速准确地在大约1/10的时间内找到整个身体150ms,几乎足够快到大约7 fps(每秒帧数),这是我的I7(不使用GPU) 。

    关于你的第一个问题:

    1&GT;是它不会检测到我的身体吗?

    好的,你从EMGU样本中借来的代码片段是一个人脸检测眼睛。

    • 眼睛盯着脸。
    • 在上半身内部未发现下体。

    如果您使用Hog找到身体的相对位置,然后将该图像片段传递给检测器,以便更低和更低。它可能是响应速度明显更快,而不是扫描整个图像。

    我认为您必须使用设置进行播放/调整才能找到任何内容。

    还要修复在鞋帮内找到较低的逻辑。