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 秒。恕我直言和经验,这是由于许多因素造成的。

就像素高度和宽度以及所使用的参数而言,处理 haar 级联的时间等于目标对象的大小。

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

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

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

在简单的较小的单个测试 jpg 图像上,它相当快,例如 200 毫秒。

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

就您的第一个问题而言:

1> 它不会检测到我的身体吗?

好的,您从 EMGU 示例中借用的代码片段是检测面部内部的眼睛。

  • 眼睛进入面部。
  • 在上半身内部没有发现下半身。

如果您使用 Hog 来查找身体的相对位置,然后将该图像片段传递给检测器以检测 haar lower 和 upper,它可能会显着加快响应速度,而不是扫描整个图像。

我认为你将不得不玩/调整设置才能找到任何东西。

还修复了在鞋帮中查找下限的逻辑。

于 2015-02-24T21:59:00.827 回答
0

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

有关 emguCV,请参阅此示例。至于您使用级联的代码,我从未尝试过这些预训练的级联,所以我不知道他们训练过哪种图像。

于 2013-10-01T17:27:36.693 回答