emgucv bodydetection с использованием haarcascade

116
11

Я пытаюсь разработать приложение, которое будет обнаруживать верхнюю часть тела и нижнюю часть тела человека через веб-камеру. Я попытался посмотреть на обнаружение лица 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;
}

спросил(а) 2021-01-25T22:23:41+03:00 4 месяца, 2 недели назад
1
Решение
100

Это старый, но стоимость времени для меня больше интересна.

Как ты говоришь

"но рассмотрите обе проблемы"

заключается в том, что он не обнаружит моего тела и это не в реальном времени. Он задерживается на 3 секунды?

Начиная с №2:

Предположим, что на 3 секунды вы намереваетесь принять 3 секунды, чтобы применить каскады хара. ИМХО и опыт, что связано с рядом факторов.

Время обработки каскада хара эквивалентно размеру целевого объекта с точки зрения количества высоты и ширины пикселей, а также используемых параметров.

Кроме того, параметры 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 времени 150 мс, что почти достаточно быстро для примерно 7 кадров в секунду (кадров в секунду) снова, что на моем I7 (не используя графический процессор).

С точки зрения вашей первой проблемы:

1> заключается в том, что он не обнаружит моего тела и?

Хорошо, фрагмент кода, который вы заимствовали из образца EMGU, является обнаружением Глаза внутри лица.

    Глаза идут внутри лица. Нижние тела не находятся внутри верхних тел.

Если вы использовали Hog, чтобы найти относительное местоположение тела, а затем передать этот фрагмент изображения в детектор для более низкого и верхнего уровня, это может быть значительно более быстрые ответы, а не сканирование всего изображения.

Я думаю, что вам придется играть/настраивать настройки, чтобы найти что-нибудь.

Также исправьте логику найти нижнюю часть внутри верхней.

ответил(а) 2021-01-25T22:23:41+03:00 4 месяца, 2 недели назад
45

Я думаю, что лучший способ найти человеческое тело в вертикальном положении - это пешеходный детектор, который поставляется с OpenCV. Вам не требуется никакого обучения, поскольку оно уже реализовано в HogDescriptor.

См. Этот пример для emguCV. Что касается вашего кода с использованием каскада, я никогда не пробовал этот предварительно подготовленный каскад, поэтому я не знаю, для какого типа изображения они были обучены.

ответил(а) 2021-01-25T22:23:41+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема