2013-01-08 2 views
2

Je travaille sur un compteur de personnes. Pour cela, j'ai le Microsoft Kinect installé sur la porte. Je travaille avec C# et EmguCV. J'ai extrait les têtes des gens, de sorte qu'ils apparaissent comme des taches blanches sur une image noire. Ensuite, j'ai créé une boîte de délimitation autour des têtes. Cela fonctionne bien. Donc, maintenant, je ai combien de blobs par image et j'ai aussi maintenant leur position. Cela fonctionne bien. Mais maintenant je veux suivre les blobs parce que je veux compter combien les gens entrent et sortent, mais je ne sais pas comment faire cela. Quelqu'un peut-il m'aider? Le problème est que chaque image, de nouveaux blobs peuvent apparaître et de vieilles gouttes peuvent disparaître. Quelqu'un peut-il me donner un algorithme ou peut-être du code? ou un papier. Merci beaucoup!Suivi des blobs avec Microsoft Kinect


Sure. Ceci est le code pour les blobs:

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: Je n'ai pas de chevauchement. Donc, ils ne doivent pas être considérés. – Lisi

+0

Pouvons-nous avoir le code que vous utilisez pour obtenir les blobs? – Kinected

Répondre

1

S'il vous plaît voir Emgu CV Blob Detection pour plus d'informations. En supposant que vous utilisez Emgu CV 2.1 ou supérieur, alors la réponse fonctionnera. Si vous utilisez la version 1.5 ou supérieure, voir this thread sur la façon de détecter facilement les blobs. Ou regardez le code ci-dessous

 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(); 

Espérons que cela aide!

EDIT

Je pense que vous devriez utiliser ce code dix images ou donc (~ 3 fois par seconde) et faire quelque chose comme ceci:

 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

On dirait que vous voulez juste identifier les blobs, on dirait que vous voulez McvBlob.ID. C'est l'identifiant du blob et vous pouvez vérifier quels identifiants sont toujours là et lesquels ne le sont pas. Je ferais toujours cela toutes les dix images pour ne pas le ralentir autant. Vous avez juste besoin d'un algorithme simple qui peut observer ce que sont les identifiants, et s'ils ont changé. Je voudrais stocker les ID dans un List<string> et vérifier cette liste pour les changements tous les quelques images. Exemple:

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

Merci pour la réponse. J'utilise 2.1 ou plus. Est-ce que cela signifie que je peux utiliser le code que vous avez posté? Je ne comprends pas le code. Comment ça marche? Devrait-il être exécuté à chaque image et si oui, comment cela sait-il si le blob a le même id que dans l'image suivante et si les blobs quittent l'image ou apparaissent dans l'image? – Lisi

+0

Vous pouvez toujours utiliser le code que j'ai posté, et le fil dit que certains utilisateurs ont eu des problèmes avec la vitesse du traitement en utilisant cet algorithme – Kinected

+0

ok merci beaucoup :) mais comment ça marche? devrait-il être exécuté à chaque image? Est-ce que je n'ai pas à sécuriser les vieilles gouttes pour les comparer avec les nouvelles? puis-je dessiner les trajectoires avec cette méthode? – Lisi

Questions connexes