2013-01-08 56 views
2

我正在使用人員計數器。爲此,我安裝了微軟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(); 

希望這有助於!

編輯

我認爲你應該使用此代碼每十幀左右(〜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

這聽起來像你只是想識別blob,這聽起來像你想McvBlob.ID。這是blob的ID,您可以檢查哪些ID仍然存在,哪些不存在。我仍然會每十幀做一次這樣的操作,以免影響速度。你只需要一個簡單的算法,可以觀察這些ID是什麼,以及它們是否已經改變。我會將ID存儲在List<string>中,並檢查每個幀的更改列表。例如:

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

好的非常感謝:)但它是如何工作的?這應該執行每幀?我不必安全舊斑點與新的比較呢?我可以用這種方法繪製軌跡嗎? – Lisi