使用HAARCASCADE的EMGUCV身体检测
本文关键字:检测 EMGUCV HAARCASCADE 使用 | 更新日期: 2023-09-27 18:33:22
我正在尝试开发一个应用程序,该应用程序可以通过网络摄像头检测一个人的上半身和下半身。我试着看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;
}
立姿势人体的最佳方法是OpenCV附带的行人探测器。你不需要任何培训,因为它已经在HogDescriptor中实现。
有关 emguCV,请参阅此示例。至于你使用级联的代码,我从来没有尝试过这些预先训练的级联,所以我不知道它们被训练了哪种图像。
这是旧的,但时间成本对我来说更感兴趣。
正如你所说
"但解决这两个问题"
- 是它不会检测到我的身体和
- 它不再是实时的。它延迟了 3 秒?
首先从 #2 开始:
让我们假设 3 秒的意思是应用 haar 级联需要 3 秒。恕我直言和经验,这是由于许多因素。
处理 haar 级联的时间等同于目标对象的大小,包括像素高度和宽度的数量以及使用的参数。
此外,检测多尺度参数将影响性能。 在我相当强大的机器上,我看到 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 的 150 毫秒时间内找到整个身体,这几乎足以达到大约 7 fps(每秒帧数(的速度,这在我的 I7(不使用 GPU(上
。就您的第一个问题而言:
1>是它不会检测到我的身体吗?
好的,您从 EMGU 示例中借用的代码片段是检测面部内部的眼睛。
- 眼睛进入脸内。
- 下半身不在上半身内部。
如果你使用Hog找到身体的相对位置,然后将该图像片段传递给haar Lower and Upper的探测器,则可能会明显更快地响应,而不是扫描整个图像。
我认为您将不得不玩/调整设置才能找到任何东西。
还修复了在上层中找到下层的逻辑。