Pet*_*ter 3 c# opencv emgucv template-matching
我正在构建一个跟踪未知对象的对象跟踪程序.用户必须在实时视频流中选择应跟踪的区域.我的项目与此视频类似.
http://www.youtube.com/watch?v=G5GLIKIkd6E
我尝试了一种方法,但它不够健壮,跟踪器移动了很多.所以我再次从头开始.
任何人都知道如何在视频中提出一个方法?我是emgucv的新手,截至目前我真的不知道从哪里开始.
视频建议模板匹配由于速度的原因,我预计它更有可能成为FFT(快速傅里叶变换)方法,这在EMGU中相当容易实现,但是要完美它很难.
首先,模板匹配方法我已经制作了一个方法,它将匹配您输入到其中的图像中的对象.FFT仅适用于单个光谱图像的颜色,您必须分割光谱并将结果矩阵添加到一起:
Point Location;
private bool Detect_object(Image<Gray, Byte> Area_Image, Image<Gray, Byte> image_object)
{
bool success = false;
//Work out padding array size
Point dftSize = new Point(Area_Image.Width + (image_object.Width * 2), Area_Image.Height + (image_object.Height * 2));
//Pad the Array with zeros
using (Image<Gray, Byte> pad_array = new Image<Gray, Byte>(dftSize.X, dftSize.Y))
{
//copy centre
pad_array.ROI = new Rectangle(image_object.Width, image_object.Height, Area_Image.Width, Area_Image.Height);
CvInvoke.cvCopy(Area_Image, pad_array, IntPtr.Zero);
pad_array.ROI = (new Rectangle(0, 0, dftSize.X, dftSize.Y));
//Match Template
using (Image<Gray, float> result_Matrix = pad_array.MatchTemplate(image_object, TM_TYPE.CV_TM_CCOEFF_NORMED))
{
Point[] MAX_Loc, Min_Loc;
double[] min, max;
//Limit ROI to look for Match
result_Matrix.ROI = new Rectangle(image_object.Width, image_object.Height, Area_Image.Width - image_object.Width, Area_Image.Height - image_object.Height);
result_Matrix.MinMax(out min, out max, out Min_Loc, out MAX_Loc);
Location = new Point((MAX_Loc[0].X), (MAX_Loc[0].Y));
success = true;
Results =result_Matrix.Convert<Gray,Double>();
}
}
return success;
}
Run Code Online (Sandbox Code Playgroud)
大多数人忘记的事情是用零填充数组,类似于我们使用零的模板的大小,因为这对fft方法没有影响.我们填充矩阵,否则我们不会正确处理边缘数据,我们可能会错过匹配的项目.
第二点,我不能强调这是多么重要的是FFT方法此刻会返回对象左上角的对象.result_Matrix.MinMax找到对象最可能匹配的位置.有很多你需要进行试验,所以在这里或EMGU会有更多问题,我会尽力帮助.我也将复制并粘贴此解决方案.
好吧,由于时间紧迫,我会让您编写大部分代码,但实际上用户使用paintbox的click事件来查找图像中对象的set eX和eY位置.模板的大小固定为100x100
Image<Gray, Byte> template_img = Main_Image.Copy(new Rectangle(x, y, 100, 100);
Run Code Online (Sandbox Code Playgroud)
然后,他在对象周围的原始图像上设置ROI,这会影响移动.在我们的例子中,我们想要一个50像素模板周围的缓冲区(ROI).这相当于以下的初始投资回报率:
Main_Image.ROI = new Rectangle(x - 50, y - 50, 200, 200);
Run Code Online (Sandbox Code Playgroud)
现在,由于使用图像的ROI,我们可以减慢处理速度,并且再次显示原始图像,所以做这样的事情要好得多:
using( Image<Gray, Byte> img_ROI = Main_Image.Copy(new Rectangle(x - 50, y - 50, 200, 200))
{
Detect_object(img_ROI, template_img)
}
Run Code Online (Sandbox Code Playgroud)
我们使用using语句,因为当我们完成并释放资源时,它会处理额外的图像数据.
现在,对于技巧,ROI实际上由Detect_object的结果控制,这就是我们将Location保持为全局变量的原因.一旦我们成功匹配模板,我们的using语句将更像:
using( Image<Gray, Byte> img_ROI = Main_Image.Copy(new Rectangle(Location.X - 50, Location.Y - 50, 200, 200))
{
...
}
Run Code Online (Sandbox Code Playgroud)
除了ROI的矩形和模板,大小和位置之外,如果您遇到问题,请告诉我,但代码应该很容易在那里,
干杯,
克里斯
| 归档时间: |
|
| 查看次数: |
16633 次 |
| 最近记录: |