C# 基于haarcascade的emgucv人体检测

C# 基于haarcascade的emgucv人体检测,c#,winforms,emgucv,C#,Winforms,Emgucv,我正试图开发一个应用程序,通过网络摄像头检测人的上半身和下半身。我试图查看emgu的人脸检测,并下载了“haarcascade_upperbody.xml”和“haarcascade_lowerbody.xml”。我试着用给定的人脸检测编码相同的东西 但问题是它不会检测到我的身体,也不再是实时的。延迟3秒 这是我的密码。我希望有人能帮助我: private void ProcessFrame(object sender, EventArgs arg) { Image<

我正试图开发一个应用程序,通过网络摄像头检测人的上半身和下半身。我试图查看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;
    }  
private void ProcessFrame(对象发送方,事件args arg)
{
Image ImageFrame=capture.QueryFrame();
FittingBox.Image=ImageFrame;
检测时间长;
列表上限=新列表();
List lower=新列表();
检测(ImageFrame,“haarcascade_upperbody.xml”、“haarcascade_lowerbody.xml”、upper、lowerbody、out检测时间);
foreach(上部为矩形)
图像框。绘制(向上,新Bgr(颜色。红色),2);
foreach(下部为低矩形)
ImageFrame.Draw(低,新Bgr(颜色.蓝色),2);
}
公共静态无效检测(图像图像、字符串upperFileName、字符串lowerFileName、列表upperbody、列表lowerbody、out long detectionTime)
{
秒表;
if(GpuInvoke.HasCuda)
{
使用(GpuCascadeClassifier upper=新的GpuCascadeClassifier(upperFileName))
使用(GpuCascadeClassifier lower=新的GpuCascadeClassifier(lowerFileName))
{
watch=Stopwatch.StartNew();
使用(GpuImage GpuImage=新的GpuImage(图像))
使用(GpuImage gpuGray=GpuImage.Convert())
{
矩形[]upperRegion=upper.DetectMultiScale(gpuGray,1.1,10,Size.Empty);
upperbody.AddRange(upperRegion);
foreach(上部区域中的矩形f)
{
使用(GpuImage upperImg=gpuGray.GetSubRect(f))
{
使用(GpuImage clone=upperImg.clone())
{
矩形[]lowerRegion=lower.DetectMultiScale(克隆,1.1,10,大小.空);
foreach(下部区域中的矩形e)
{
矩形lowerRect=e;
低误差偏移量(f.X,f.Y);
lowerbody.Add(lowerRect);
}
}
}
}
}
看,停;
}
}
其他的
{
使用(CascadeClassifier upper=新的CascadeClassifier(upperFileName))
使用(CascadeClassifier lower=新的CascadeClassifier(lowerFileName))
{
watch=Stopwatch.StartNew();
使用(Image gray=Image.Convert())
{
灰色;
矩形[]UpperDetected=upper.DetectMultiScale(
灰色
1.1,
10,
新尺寸(50,50),
尺寸(空);
foreach(上部为矩形f)
{
gray.ROI=f;
矩形[]lowerDetected=lower.DetectMultiScale(
灰色
1.1,
10,
新尺寸(50,50),
尺寸(空);
gray.ROI=Rectangle.Empty;
foreach(矩形e位于下部检测)
{
矩形lowerRect=e;
低误差偏移量(f.X,f.Y);
lowerbody.Add(lowerRect);
}
}
}
看,停;
}
}
检测时间=watch.elapsedmillyses;
}  

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


有关emguCV,请参阅。至于您使用cascade的代码,我从未尝试过这些经过预训练的cascade,因此我不知道它们是针对哪种图像进行训练的。

这是一个旧代码,但我更感兴趣的是时间成本

正如你所说

“但同时解决这两个问题”

  • 它不会探测到我的身体
  • 它不再是实时的了。延迟3秒
  • 首先从#2开始:

    让我们假设3秒,你的意思是应用哈尔级联需要3秒。IMHO和经验,这是由许多因素造成的

    处理haar级联的时间在像素数、高度和宽度以及使用的参数方面与目标对象的大小相等

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

        scaleFactor = 1.07
        minNeighbors = 2 
        minSize = 8,8
        maxSize = 200,200 
    
    “webm”720p能够在1秒内处理相同的设置。通过使用这些设置,您可以调整分类器,使其更快或更慢。我在屏幕上为我的样本设置了一些控件,并对它们进行了一些调整

    在简单较小的单次测试jpg图像上,速度相当快,大约为200毫秒

    HOG FindPederstrian.Find在150毫秒的1/10时间内就可以快速准确地找到整个身体,这几乎足够我的I7(不使用GPU)以每秒7帧的速度找到整个身体

    关于你的第一个问题:

    1> 它不会探测到我的身体和身体吗? 好的,代码片段是您借用的