我想使用带有Emgu的C#编写程序,可以检测来自摄像头的图像上的白色斑点并跟踪它。此外,程序可以返回跟踪blob的ID
答案 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;
}