如何在Emgu上进行视频或相机捕捉的白色斑点追踪?

时间:2010-04-17 21:05:23

标签: c# opencv blob tracking

我想使用带有Emgu的C#编写程序,可以检测来自摄像头的图像上的白色斑点并跟踪它。此外,程序可以返回跟踪blob的ID

第1帧:http://www.freeimagehosting.net/uploads/ff2ac19054.jpg

第2帧:http://www.freeimagehosting.net/uploads/09e20e5dd6.jpg

3 个答案:

答案 0 :(得分:1)

Emgu.CV.Example解决方案(Emgu.CV.Example.sln)中的Emgu示例项目“VideoSurveilance”演示了blob跟踪并为其分配ID。

我是OpenCV的新手,但在我看来,仅跟踪“白色”斑点可能比听起来更难。例如,你的样本图片中的blob不是真的“白”吗?我认为你真正想做的是“获得比背景更亮一些量的斑点”,即在黑色背景上找到灰色斑点或在灰色背景上找到白色斑点。

答案 1 :(得分:0)

这取决于你的背景是什么样的。如果它在您附着的那些图像上一直是黑暗的,那么您应该能够提取具有一定阈值的那些“白色”斑点。对于任何更智能的分割,您还需要使用其他一些功能(例如,如果您的对象颜色一致,则需要进行关联)。

答案 2 :(得分:0)

我不能说代码会起作用,因为我还没有测试过。

一般的想法是采取捕获的帧(假设您正在捕获帧)并通过修改饱和度和值(亮度)来滤除噪声。然后将该修改的HSV图像处理为灰度。可以通过循环遍历跟踪器生成的blob集合并分配id和边界框来标记Blob。

此外,您可能对AForge.net和相关文章感兴趣:Hands Gesture Recognition关于使用直方图进行计算机视觉的机制和实现。

这是自定义跟踪器代码found on the nui forums的修改版本:

static void Main(){
    Capture capture = new Capture(); //create a camera captue
    Image<Bgr, Byte> img = capture.QuerySmallFrame();

    OptimizeBlobs(img);

    BackgroundStatisticsModel bsm = new BackgroundStatisticsModel(img, Emgu.CV.CvEnum.BG_STAT_TYPE.FGD_STAT_MODEL);
    bsm.Update(img);

    BlobSeq oldBlobs = new BlobSeq();
    BlobSeq newBlobs = new BlobSeq();

    ForgroundDetector fd = new ForgroundDetector(Emgu.CV.CvEnum.FORGROUND_DETECTOR_TYPE.FGD);
    BlobDetector bd = new BlobDetector(Emgu.CV.CvEnum.BLOB_DETECTOR_TYPE.CC);
    BlobTracker bt = new BlobTracker(Emgu.CV.CvEnum.BLOBTRACKER_TYPE.CC);

    BlobTrackerAutoParam btap = new BlobTrackerAutoParam();
    btap.BlobDetector = bd;
    btap.ForgroundDetector = fd;
    btap.BlobTracker = bt;
    btap.FGTrainFrames = 5;

    BlobTrackerAuto bta = new BlobTrackerAuto(btap);


    Application.Idle += new EventHandler(delegate(object sender, EventArgs e)
    {  //run this until application closed (close button click on image viewer)

        //******* capture image ******* 
        img = capture.QuerySmallFrame();

        OptimizeBlobs(img);

        bd.DetectNewBlob(img, bsm.Foreground, newBlobs, oldBlobs);

        List<MCvBlob> blobs = new List<MCvBlob>(bta);

        MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0);
        foreach (MCvBlob blob in blobs)
        {
           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));
        }

        Image<Gray, Byte> fg = bta.GetForgroundMask();
    });
}

public Image<Gray, Byte> OptimizeBlobs(Image<Gray, Byte img)
{
    // can improve image quality, but expensive if real-time capture
    img._EqualizeHist(); 

    // convert img to temporary HSV object
    Image<Hsv, Byte> imgHSV = img.Convert<Hsv, Byte>();

    // break down HSV
    Image<Gray, Byte>[] channels = imgHSV.Split();
    Image<Gray, Byte> imgHSV_saturation = channels[1];   // saturation channel
    Image<Gray, Byte> imgHSV_value      = channels[2];   // value channel

    //use the saturation and value channel to filter noise. [you will need to tweak these values]
    Image<Gray, Byte> saturationFilter = imgHSV_saturation.InRange(new Gray(0), new Gray(80));
    Image<Gray, Byte> valueFilter = imgHSV_value.InRange(new Gray(200), new Gray(255));

    // combine the filters to get the final image to process.
    Image<Gray, byte> imgTarget = huefilter.And(saturationFilter);

    return imgTarget;
}