2

我正在研究人员计数器。为此,我在门上安装了 Microsoft Kinect。我正在使用 C# 和 EmguCV。我已经提取了人的头部,使它们在黑色图像上显示为白色斑点。然后我在头部周围创建了一个边界框。这很好用。所以我现在每帧有多少个斑点,我现在也有它们的位置。这工作正常。但是现在我想跟踪 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;
                }

            }
        }
4

1 回答 1

1

有关详细信息,请参阅Emgu CV Blob 检测。假设您使用的是 Emgu CV 2.1 或更高版本,那么答案将起作用。如果您使用的是 1.5 或更高版本,请参阅此线程以了解如何轻松检测 blob。或者看下面的代码

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

编辑 2

听起来您只想识别 blob,听起来像您想要McvBlob.ID的。这是 blob 的 ID,您可以检查哪些 ID 仍然存在,哪些不存在。我仍然会每十帧执行一次,以免减慢速度。您只需要一个简单的算法来观察 ID 是什么,以及它们是否已更改。我会将 ID 存储在 a 中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();
于 2013-01-08T02:54:40.840 回答