2013-01-08 1 views
2

저는 사람들 카운터에서 일하고 있습니다. 이를 위해 Microsoft Kinect를 설치했습니다. C# 및 EmguCV로 작업하고 있습니다. 나는 사람들의 머리를 뽑아서 검은 색 이미지에 하얀 얼룩처럼 보입니다. 그런 다음 머리 주위에 경계 상자를 만들었습니다. 그건 잘 작동합니다. 이제 프레임 당 얼마나 많은 얼룩이 있는지, 그리고 나는 그들의 위치를 ​​알게되었습니다. 이것은 잘 작동합니다. 하지만 지금은 얼마나 많은 사람들이 들어오고 나가는 지 계산하기를 원하기 때문에 얼룩을 추적하고 싶습니다. 그러나 어떻게 해야할지 모르겠습니다. 누구든지 나를 도울 수 있습니까? 문제는 매 프레임마다 새로운 얼룩이 나타나고 오래된 얼룩이 사라질 수 있다는 것입니다. 누구나 내게 알고리즘이나 코드를 줄 수 있습니까? 또는 종이. 감사합니다.Microsoft Kinect로 BLOB 추적


확실히. 다음은 blob 코드입니다.

using (MemStorage stor = new MemStorage()) 
     { 



      Contour<System.Drawing.Point> contours = head_image.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL, stor); 



      for (int i = 0; contours != null; contours = contours.HNext) 
      { 

       i++; 



       //if ((contours.Area > Math.Pow(sliderMinSize.Value, 2)) && (contours.Area < Math.Pow(sliderMaxSize.Value, 2))) 
       { 

        MCvBox2D box = contours.GetMinAreaRect(); 

        blobCount++; 

        contour_image.Draw(box, new Bgr(System.Drawing.Color.Red), 1); 


        new_position = new System.Drawing.Point((int)(box.center.X), (int)(box.center.Y)); 
        new_x = box.center.X; 
        new_y = box.center.Y; 
       } 

      } 
     } 
+0

btw : 오버랩이 없습니다. 따라서 그들은 고려할 필요가 없습니다. – Lisi

+0

얼룩을 가져 오는 데 사용할 코드를 사용할 수 있습니까? – Kinected

답변

1

자세한 내용은 Emgu CV Blob Detection을 참조하십시오. Emgu CV 2.1 이상을 사용한다고 가정하면 대답이 적용됩니다. 버전 1.5 이상을 사용하는 경우 얼룩을 쉽게 감지하는 방법은 this thread을 참조하십시오. 또는 아래 코드를 참조하십시오.

 Capture capture = new Capture(); 

    ImageViewer viewer = new ImageViewer(); 

    BlobTrackerAutoParam param = new BlobTrackerAutoParam(); 
    param.ForgroundDetector = new ForgroundDetector(Emgu.CV.CvEnum.FORGROUND_DETECTOR_TYPE.FGD); 
    param.FGTrainFrames = 10; 
    BlobTrackerAuto tracker = new BlobTrackerAuto(param); 

    Application.Idle += new EventHandler(delegate(object sender, EventArgs e) 
    { 
     tracker.Process(capture.QuerySmallFrame().PyrUp()); 
     Image<Gray, Byte> img = tracker.GetForgroundMask(); 
     //viewer.Image = tracker.GetForgroundMask(); 

     MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0); 
     foreach (MCvBlob blob in tracker) 
     { 
      img.Draw(Rectangle.Round(blob), new Gray(255.0), 2); 
      img.Draw(blob.ID.ToString(), ref font, Point.Round(blob.Center), new Gray(255.0)); 
     } 
     viewer.Image = img; 
    }); 
    viewer.ShowDialog(); 

희망이 있습니다.

편집

나는이 코드 매 10 프레임 정도 (2 ~ 3 회 초)를 사용하고 같은 것을 수행해야한다고 생각 :

 Capture capture = new Capture(); 

    ImageViewer viewer = new ImageViewer(); 

    BlobTrackerAutoParam param = new BlobTrackerAutoParam(); 
    param.ForgroundDetector = new ForgroundDetector(Emgu.CV.CvEnum.FORGROUND_DETECTOR_TYPE.FGD); 
    param.FGTrainFrames = 10; 
    BlobTrackerAuto tracker = new BlobTrackerAuto(param); 
    int frames = 0; 
    Application.Idle += new EventHandler(delegate(object sender, EventArgs e) 
    { 
     frames++;//Add to number of frames 
     if (frames == 10) 
     { 
     frames = 0;//if it is after 10 frames, do processing and reset frames to 0 
     tracker.Process(capture.QuerySmallFrame().PyrUp()); 
     Image<Gray, Byte> img = tracker.GetForgroundMask(); 
     //viewer.Image = tracker.GetForgroundMask(); 

     int blobs = 0; 

     MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0); 
     foreach (MCvBlob blob in tracker) 
     { 
      //img.Draw(Rectangle.Round(blob), new Gray(255.0), 2); 
      //img.Draw(blob.ID.ToString(), ref font, Point.Round(blob.Center), new Gray(255.0)); 
      //Only uncomment these if you want to draw a rectangle around the blob and add text 
      blobs++;//count each blob 
     } 
     blobs = /*your counter here*/; 
     blobs = 0; //reset 
     viewer.Image = img;//get next frame 
    }); 
    viewer.ShowDialog(); 

EDIT 2

그냥 방울을 식별하려는 것처럼 들리 겠지만, 당신이 원하는 것처럼 들린다. McvBlob.ID. 이것은 얼룩의 ID이며 어떤 ID가 아직 있고 어떤 ID가 아닌지 확인할 수 있습니다. 나는 그것을 줄이거 나하지 않도록 매 10 프레임마다 여전히 이것을 할 것이다. ID가 무엇인지, ID가 변경되었는지를 관찰 할 수있는 간단한 알고리즘 만 있으면됩니다. List<string>에 ID를 저장하고 몇 프레임마다 변경 사항 목록을 확인합니다. 예 :

List<string> LastFrameIDs, CurrentFrameIDs; 

     Capture capture = new Capture(); 

    ImageViewer viewer = new ImageViewer(); 

    BlobTrackerAutoParam param = new BlobTrackerAutoParam(); 
    param.ForgroundDetector = new ForgroundDetector(Emgu.CV.CvEnum.FORGROUND_DETECTOR_TYPE.FGD); 
    param.FGTrainFrames = 10; 
    BlobTrackerAuto tracker = new BlobTrackerAuto(param); 
    int frames = 0; 
    Application.Idle += new EventHandler(delegate(object sender, EventArgs e) 
    { 
     frames++;//Add to number of frames 
     if (frames == 10) 
     { 
     frames = 0;//if it is after 10 frames, do processing and reset frames to 0 
     tracker.Process(capture.QuerySmallFrame().PyrUp()); 
     Image<Gray, Byte> img = tracker.GetForgroundMask(); 
     //viewer.Image = tracker.GetForgroundMask(); 

     int blobs = 0, i = 0; 

     MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0); 
     foreach (MCvBlob blob in tracker) 
     { 
      i++; 
      //img.Draw(Rectangle.Round(blob), new Gray(255.0), 2); 
      //img.Draw(blob.ID.ToString(), ref font, Point.Round(blob.Center), new Gray(255.0)); 
      //Only uncomment these if you want to draw a rectangle around the blob and add text 
      CurrentFrameIDs.Add(blob.ID.ToString()); 
      if (CurrentFrameIDs[i] == LastFrameIDs[i]) 
       img.Draw(Rectangle.Round(blob), new Gray(0,0), 2);//mark the new/changed blob 
      blobs++;//count each blob 
     } 
     blobs = /*your counter here*/; 
     blobs = 0; //reset 
     i = 0; 
     LastFrameIDs = CurrentFrameIDs; 
     CurrentFrameIDs = null; 
     viewer.Image = img;//get next frame 
    }); 
    viewer.ShowDialog(); 
+0

답변 해 주셔서 감사합니다. 나는 2.1 이상을 사용하고있다. 이것은 내가 게시 한 코드를 사용할 수 있다는 것을 의미합니까? 코드를 이해할 수 없습니다. 어떻게 작동합니까? 모든 프레임을 실행해야합니까? 그렇다면 blob이 다음 이미지와 동일한 id를 갖고 있는지, blob이 이미지를 떠나거나 이미지에 나타나는지 어떻게 알 수 있습니까? – Lisi

+0

내가 게시 한 코드를 계속 사용할 수 있으며 스레드는 일부 사용자가이 알고리즘을 사용하여 처리 속도에 문제가 있다고 말합니다. – Kinected

+0

ok 고맙습니다 :) 그러나 어떻게 작동합니까? 이것이 각 프레임마다 실행되어야 하는가? 나는 오래 된 얼룩을 새로운 것과 비교하기 위해 안전해야하지 않습니까? 이 방법으로 궤도를 그릴 수 있습니까? – Lisi