2013-09-29 4 views
0

나는 웹캠을 통해 사람의 상체와 하체를 감지하는 응용 프로그램을 개발하려고합니다. 나는 emgu의 얼굴 탐지를보고 "haarcascade_upperbody.xml"과 "haarcascade_lowerbody.xml"을 다운로드하려고했습니다. 주어진 얼굴 인식과 동일한 코드를 시도했습니다.haarascascade를 사용하는 emgucv bodydetection

그러나 문제는 내 몸을 감지하지 못하고 실시간으로 더 이상 보이지 않는 것입니다. 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; 
    } 
+0

문제를 명확하게 공식화 할 수 있습니까? "실시간"은 충분히 명확하지 않습니다. 사진의 해상도는 어떻게됩니까? 초당 프레임 수는 얼마입니까? 다른 상체를 감지합니까? –

+0

문제는 시스템에서 아무 것도 감지 할 수 없다 ... 캡쳐 된 상체에 직사각형을 그려야하지만 그리지는 않는다 ... 내 모든 코드는 위에 명시되어있다 ... – newbie07

+0

매우 간단한 방법을 시도 했습니까? 이 일을하기 전에 테스트? 상체를 탐지하려고하는 것만 큼? 왜냐하면 지금 당장 상체를 찾으려고하고, 발견하면 하체를 찾으십시오. 이 2 개가 하나의 이미지에서 발견 될 확률은 매우 낮습니다. 사람들을 찾으려면 HoGDescriptor에서 PeopleDetector를 사용해야합니다. –

답변

0

내가 가장 좋은 방법은 수직으로 인체를 찾을 수 있음을 OpenCV와 함께 제공되어 제공 보행자 감지기 생각합니다. 이미 HogDescriptor에 구현되어 있으므로 교육이 필요하지 않습니다.

emguCV는 this example을 참조하십시오. 캐스케이드를 사용하는 코드의 경우 이러한 사전 훈련 된 캐스케이드를 사용해 본 적이 없으므로 어떤 종류의 이미지가 훈련되었는지 알 수 없습니다.

+0

하지만 물건은 상체와 하체를 구별 할 필요가 있습니다 ... 상체는 다른 측정 값을 가지고 있습니다 ... 하체도 마찬가지입니다 ... 보행자를 사용하면 전신 만 탐지합니다. ... – newbie07

+0

오! 나는 그것을 몰랐다! 그런 다음 보행자 감지기를 사용하여 전신을 탐지하고 ROI를 작성한 다음 작은 영역에서 하얼 폭포를 달릴 수 있습니다. 그것은 매우 빠르며 그것을 발견 할 수있는 더 큰 기회를 가질 것입니다. 하지만 상체가있는 경우에만 하체를 감지하려고하지 않습니다. 각각을 개별적으로 찾으십시오. 하나를 발견 한 경우 (예 : 하체), 총체의 높이에서 하체를 뺀 값을 빼서 상체의 높이를 외삽 할 수 있습니다. 그냥 생각! 너의 상상력을 사용해라 :) –

0

이것은 오래되었지만 시간이 오래 걸릴 때가 많습니다.

  1. "하지만 모두 문제를 해결"말하는 것처럼 내 몸을 검색하지 않습니다 및
  2. 는 더 이상 실시간에없는 것입니다 . 3 초 지연됩니까? 첫째 # 2를 시작으로

:

은의 당신이 하르 폭포를 적용하는 3 초 복용 의미 삼초에 의해 가정하자. IMHO & 경험, 그것은 여러 가지 요인 때문입니다.

하얼 폭포를 처리하는 데 걸리는 시간은 픽셀 높이 및 너비의 매개 변수 및 사용 된 매개 변수와 관련하여 대상 개체의 크기와 동일합니다.

또한 DetectMultiScale 매개 변수는 성능에 영향을줍니다.

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

A "WEBM"720 1 초에 같은 설정을 처리 할 수 ​​있습니다 : 내 상당히 살이 찐 기계, 나는 다음과 같은 설정으로 이미지를 처리하는 데 1.5 초를 복용 1280 * 720의 MP4 프레임 폭을보고 있어요. 이러한 설정으로 재생하면 분류자를 더 빠르게 또는 더 느리게 조정할 수 있습니다. 내 샘플을위한 화면에 몇 가지 컨트롤을 넣고 약간 조정했습니다.

단순한 작은 단일 테스트 jpg 이미지에서 200ms와 같이 상당히 빠릅니다.

HOG FindPedestrian.Find는 시간당 약 1/10의 시간 내에 전신을 찾아내는 데 꽤 빠르며 정확합니다. 이것은 약 7fps (초당 프레임) 정도로 충분히 빠릅니다. 내 I7 (GPU를 사용하지 않음)). 당신의 첫번째 문제의 관점에서

:

1>은 내 몸을 감지하지 것입니다?

EMGU 샘플에서 빌린 코드 스 니펫은 얼굴 안의 눈을 감지합니다.

  • 눈은 안쪽으로 간다.
  • 상체에서 하체를 찾을 수 없습니다.

당신이 몸의 상대적 위치를 찾은 다음이 아니라 전체 이미지를 스캔보다 낮은 하르의 검출기에 & 위가 될 수 상당히 빠른 응답을 해당 이미지 조각을 전달하는 돼지를 사용한 경우.

나는 당신이 아무것도 발견하기 위해 설정으로 재생/조정해야 할 것이라고 생각합니다.

상단의 안쪽을 찾는 논리를 수정하십시오.