【发布时间】:2011-06-21 15:23:09
【问题描述】:
我有一个 EMGU(openCV 包装器)程序,它从
中减去背景
一个摄像头馈送并提取漂亮干净的斑点。
现在我需要一些东西来跟踪这些 blob 并为它们分配 ID。
有什么建议/库吗?
谢谢,
软件
【问题讨论】:
标签: image-processing opencv computer-vision emgucv
我有一个 EMGU(openCV 包装器)程序,它从
中减去背景
一个摄像头馈送并提取漂亮干净的斑点。
现在我需要一些东西来跟踪这些 blob 并为它们分配 ID。
有什么建议/库吗?
谢谢,
软件
【问题讨论】:
标签: image-processing opencv computer-vision emgucv
如果您有多个要跟踪的对象,可以尝试Particle Filter。
粒子过滤器基本上是在图像上“布置”粒子,每个粒子都有一定的权重。然后在每个时间步长中,通过将它们与当时对象的实际测量值进行比较来更新这些权重。然后,具有高权重的粒子将在其方向上放置更多粒子(在该方向上添加一个轻微的随机部分)以用于下一个时间步长。 在几个时间步长之后,粒子将围绕对象测量位置进行分组。这就是为什么这种方法有时也被称为适者生存的方法......
所以这整个事情建立了一个圆圈:
Initialization ----> Sampling
> \
/ >
Updating Prediction
< /
\ <
Association
因此,这提供了一种在给定场景中跟踪对象的好方法。进行多对象跟踪的一种方法是在所有对象上使用这个粒子过滤器,这会起作用,但是当您尝试为对象提供 ID 以及对象相互交叉时有缺点,因为粒子云可能丢了一个,跟着另一个。
要解决这个问题,您可以尝试使用混合粒子过滤器(Vermaak 等人 [2003])。这个通过一个单独的粒子过滤器跟踪每个对象(当然需要较少的粒子)。
可以在这里找到一篇很好的论文:http://www.springerlink.com/content/qn4704415gx65315/ (如果你愿意,我还可以为你提供一些其他的东西,如果你会说德语,我什至可以给你一个我不久前在我的大学里举办过的演讲)
编辑:
忘了提一下:由于您尝试在 OpenCV 中执行此操作:据我所知,有一个冷凝算法的实现(第一个在整个图像上使用一个粒子滤波器的算法)是 OpenCV 分布的一部分,虽然它可能有点过时了。直接在 OpenCV 中可能有更新的粒子过滤器方法,但如果没有,如果您寻找 OpenCV 和粒子过滤器,您会在 Google 上找到很多结果
希望对您有所帮助...如果没有,请继续询问...
【讨论】:
您可以简单地改编一个 EMGU CV 示例,该示例使用 VideoSurveillance 命名空间:
public partial class VideoSurveilance : Form
{
private static MCvFont _font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0);
private static Capture _cameraCapture;
private static BlobTrackerAuto<Bgr> _tracker;
private static IBGFGDetector<Bgr> _detector;
public VideoSurveilance()
{
InitializeComponent();
Run();
}
void Run()
{
try
{
_cameraCapture = new Capture();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
_detector = new FGDetector<Bgr>(FORGROUND_DETECTOR_TYPE.FGD);
_tracker = new BlobTrackerAuto<Bgr>();
Application.Idle += ProcessFrame;
}
void ProcessFrame(object sender, EventArgs e)
{
Image<Bgr, Byte> frame = _cameraCapture.QueryFrame();
frame._SmoothGaussian(3); //filter out noises
#region use the background code book model to find the forground mask
_detector.Update(frame);
Image<Gray, Byte> forgroundMask = _detector.ForgroundMask;
#endregion
_tracker.Process(frame, forgroundMask);
foreach (MCvBlob blob in _tracker)
{
frame.Draw(Rectangle.Round(blob), new Bgr(255.0, 255.0, 255.0), 2);
frame.Draw(blob.ID.ToString(), ref _font, Point.Round(blob.Center), new Bgr(255.0, 255.0, 255.0));
}
imageBox1.Image = frame;
imageBox2.Image = forgroundMask;
}
}
【讨论】: