2

私はピープルカウンターで働いています。このために、Microsoft Kinect をドアの上に設置しました。私は C# と EmguCV を使用しています。人々の頭を抽出して、黒い画像に白い塊として表示されるようにしました。次に、頭の周りにバウンディング ボックスを作成しました。それはうまくいきます。フレームごとにいくつのブロブがあり、その位置もわかりました。これはうまくいきます。しかし、出入りする人の数を数えたいので、ブロブを追跡したいのですが、これを行う方法がわかりません。誰でも私を助けることができますか?問題は、すべてのフレームで、新しいブロブが表示され、古いブロブが消える可能性があることです。アルゴリズムやコードを教えてもらえますか? または紙。どうもありがとう!


もちろん。ブロブのコードは次のとおりです。

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 ブロブ検出を参照してください。Emgu CV 2.1以降を使用していると仮定すると、答えは機能します。バージョン 1.5 以降を使用している場合は、ブロブを簡単に検出する方法についてこのスレッドを参照してください。または、以下のコードを見てください

     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 フレームごと (1 秒間に約 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

ブロブを識別したいだけのように聞こえますMcvBlob.ID. これはブロブの ID であり、まだ存在する ID と存在しない ID を確認できます。それほど遅くならないように、10 フレームごとにこれを行います。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();
于 2013-01-08T02:54:40.840 に答える