计算机视觉
图像处理

博客halcon学习经验总结(2)

基于Halcon的视频对象分割及跟踪方法总结

前面总结了利用HALCON进行模板匹配的一些方法,讨论了利用物体形状的轮廓进行匹配的步骤和如何来优化匹配的速度,提高匹配的精度和速度,当然这两者之间本身也存在着制约,而在这两者之间找到一个适合自己要求的结合点,正是我们要研究和实验的。模板匹配并不是单纯的一个任务,它是一些其他工作的一个必备环节,比如物体识别、对象跟踪、检验产品、零件统计等等一些机器视觉应用。在很多情况下,模板匹配是个不错的选择。在前面总结模板匹配方法的基础上,利用HALCON做了一些视频对象跟踪的实验,并多次试验来调整程序参数优化跟踪过程,采用标准视频进行测试,将这些方法作了如下总结。

首先来看看HALOCN中的帧采集器(FrameGrabber),HDevelop提供这样一个函数来开启你采用的帧采集器(这里我的理解就是图像采集卡或工业摄像机)open_framegrabber(),这个函数中指定了HALCON目前支持的一些帧采集器的文件参数,主要有’BARRACUDA’, ‘BaumerFCAM’, ‘BCAM1394’, ‘BitFlow’, ‘DahengCAM’, ‘DahengFG’, ‘DFG-BW’, ‘DFG-LC’, ‘DirectFile’, ‘DirectShow’, ‘DT315x’, ‘DT3162’, ‘File’, ‘FireGrab’, ‘FirePackage’, ‘FlashBus’, ‘FlashBusMX’, ‘Ginga++’, ‘GingaDG’, ‘IDS’, ‘INSPECTA’, ‘Leutron’, ‘MatrixVision’, ‘MeteorII’, ‘mEnable3’, ‘MultiCam’, ‘Opteon’, ‘p3i2’, ‘p3i4’, ‘PT1000CL’, ‘PX’, ‘PXC’, ‘PXD’, ‘PXR’, ‘SaperaLT’, ‘TAG’, ‘TWAIN’, ‘uEye’;除此之外,在官方网站上也在逐步推出新支持的一些采集卡,比如近期推出的支持大恒的DahengCAM的USB2.0接口(更多的信息请访问http://www.mvtec.com/halcon/news/)。由于实验条件有限,我在实验中只能采用标准的视频,有CIF和QCIF两种格式的。这个当中我也在摸索,read_sequence()只是读取无格式的图像数据,因为找不到如何直接打开视频文件,所以在实验时只能采用保存好的单帧图像。

在利用模板匹配进行跟踪之前,需要对选定的初始帧或者某一帧进行分割,比如在实验中,采用标准Akiyo视频文件(352×288),我选定初始帧进行分水岭的分割然后采用马儿可夫随机场的分类,分割出前景对象和背景;也可以直接利用watersheds_threshold()进行阈值化的分割,当然分割的方法还很多,比如基于边缘的,基于区域增长的,基于阈值的,其中基于阈值的用的较多,里面也分为二值化,自动阈值,动态阈值等,各具特点,使用针对图像特征采用不同的方法。如果想进一步的获取精确的分割,可以采用数学形态学算子,这个可以根据具体需要选择不同的膨胀、腐蚀、开、闭操作的结合,这里就不多说了。

对已经分割好的初始帧建立模板,这里没有再确定某个区域,因为是采用已分割的图像。也可以先确定感兴趣区域(ROI),然后在对该区域建立模板,但这样获得的模板就不怎么精确了。接下来的步骤就更按模板匹配的方法来进行,用create_shape_model()来对初始帧创建模板,但这里要注意一点,Metric有个可选项,use_polarity(匹配时要求有相同的对比度),ignore_global_polarity(在全局上有对比度的情况下仍可匹配),ignore_local_polarity(即使局部灰度发生变化,也可找到模板,可以应用于遮挡条件)如果在非常低对比度下找到模板,可将MinContrast设置为一个相应小的值;如果即使在严重重叠条件下,仍可以认识模板,MinContrast应该大于噪声造成的灰度波动范围,这是为了确保模板的位置和旋转能被精确的找到。之后获取轮廓,照样使用inspect_template()监视模板

再接下来就是跟踪的过程,因为是对单帧图像进行匹配,所以要读取这个视频文件的所有帧。如何自动读取多个图像文件也就成了一个问题?这里采用for循环,还是利用read_image(Image,E:/实验图像/Akiyo/+k$d)来读取,循环当中采用find_shape_model()来匹配,这个过程跟前面介绍的一样,不再细说。要重点总结的是如何来加速匹配以及模板更新的问题,因为考虑到由于视频对象变化过大,或者发生了非刚体的运动,这时某帧不能匹配,就需要重新针对该帧重新建立模板,便于后面帧的匹配。当然在这之前的跟踪过程中,对象与模板之间的测量匹配需设定一个阈值,两者之差在这个阈值之内,则认为是匹配的,否则是不匹配的。当出现不匹配时,记录下该帧;然后对这帧采用图像分割并分类,跟初始帧样建立新模板;于是继续后面的跟踪匹配。在实验中,我采用的视频图像有对象相对于背景变化不大的,比如新闻人、视频会议等;也有对象相对于背景变化大,但对象的运动是刚体运动;如果对于非刚体的运动,匹配过程会更复杂,考虑的问题也更多。

例如,采用claire标准视频图像序列(176×144),由于对象相对背景变化较小,在匹配中尽量不采用更新模板来匹配,这里可以放宽匹配的要求,比如在MaxOverlap参数设置中可以减小其值,将MinSocre的值尽量调小点,这样会增加匹配的时间,可以在匹配的前提下尽量增大Greediness的值,这个实验中我设置的值分别为MaxOverlap=0.3, MinSocre=0.35, Greediness=0.9,共有492帧,总共匹配的时间大约12秒左右。当然这里的时间还更计算机配置有关。对foreman视频序列,由于摄像机的运动,对象和背景都有较大变化,因此在这里匹配要放宽要求,在创建模板时将对比度设置大一点,而在优化过程中选取忽略局部对比度变化的参数,在找模板中将贪婪度(Greediness)设置较低值,并且匹配度也尽量设较低值,这样可以通过部分匹配来跟踪对象。

采用Vectra标准视频图像序列(352×288),汽车行走,可作为一个刚体运动,这时就需要更新模板了,因为在行走的过程中,汽车在转弯或遇到遮挡物时就无法跟踪了,这里暂时不考虑完全遮挡的情况。在这个视频中,汽车在途中会有一些树木的遮挡,遮挡面积不大,可以完整看到汽车的轮廓。这时在前面有转弯的地方,可以放宽匹配的要求,当遇到遮挡时,更新不能匹配的模板。这个视频有141帧,在前面100帧以内,可以很好的跟踪,而在以后出现了较大的偏差,这跟寻找模板的参数设置有关;由于更新模板需要消耗时间,所以整个跟踪匹配的时间会较长。在实际应用中,我们更应该考虑到跟踪的效果,即跟踪的准确性;如如何提高视频对象跟踪的精确性和快速性也是需要进一步研究实验的。

 

解决HALCON中的分割显示问题  

今天终于解决了困扰我很久的一个问题,在VC中调用HALCON中的分割函数后,在最后返回显示时总是报错,让我郁闷了很久,Undefined gray in get_image_pointer3 或Undefined gray in get_image_pointer。

原来问题出在对于bin_threshold、threshold等这些分割函数的返回值上面,把返回值当成Image变量直接赋给图像数据buffer,今天通过多次试验发现bin_threshold、threshold返回的是被分割后的Regions,因此从Rgions获取get_image_pointer1或get_image_pointer3时就会报错,提示函数没有灰度值。

这时需要将分割后的Regions连接起来生成一个大的区域,然后将区域进行相关操作转化成Image,HALCON提供了三种方法:region_to_bin、region_to_label、region_to_mean.

  1. region_to_bin(Region,BinImage,ForegroundGray,BackgroundGray,Width,Height)它将一个区域转化成一个二进制字节图像。给区域内的所有像素赋给前景灰度值,如果输入区域大于生成的图像,则会在图像边界处截断;
  2. region_to_label(Region,ImageLabel,Type,Width,Height)它将区域转化为一个标签图像,通过索引值:第一个区域赋予灰度值1,第二个区域赋予灰度值2,依此类推……这里仅仅使用正的灰度值,直到256。区域大于生成图像则会被适当地截断。如果区域重叠,则较高值的图像会被输出。如果想重叠,可以调用expand_region进行处理。Type=’int2’、’int4’、‘byte’
  3. region_to_mean(Regions,Image,ImageMean)用它们的均值来填充图像区域,返回Image。这个操作符主要用来可视化分割结果(正是我想要的^_^)

在VC中调用,分别针对256色灰度图像和24位灰度图像分别调用不同的函数,如下面例子所示:

针对256色灰度图像,只是截取主要部分程序,其他只是打开一幅图像,将图像数据放到m_pImageBuffer中。 char  Type[MAX_STRING];

gen_image1(&hImage,”byte”,width,height,(long)m_pImageBuffer); //将缓冲区的数据生成一幅Image

threshold(hImage,&Region,160,255); //对Image进行阈值分割

connection(Region,&ConnectedRegions); //将小区域连接成一个大区域

region_to_mean(ConnectedRegions,hImage,&ImageMean);  //转化为Image

get_image_pointer1(ImageMean,(long*)&m_pRed,Type,&width1,&height1); //从HALCON的Image中获得处理后的图像数据

for(i=size-1,j=0;i>=0;i–,j++)

m_pImageBuffer[j]=m_pRed[size-i-1];  //将数据放回buffer中,返回显示出结果

针对24位RGB图像

ExtractRGB24Channels(m_pImageBuffer,m_pRed,m_pGreen,m_pBlue); //从打开的图像数据中分别提取出R、G、B分量,用于生成HALCON的Image

gen_image3(&hImage,”byte”,width,height,(long)m_pRed,(long)m_pGreen,(long)Blue);  //获得Image

threshold(hImage,&Region,160,255); //对Image进行阈值分割

connection(Region,&ConnectedRegions); //将小区域连接成一个大区域

region_to_mean(ConnectedRegions,hImage,&ImageMean);  //转化为Image

get_image_pointer3(ImageMean,(long*)&m_pRed,(long*)&m_pGreen,(long*)&m_pBlue,Type,&width1,&height1); //从ImageMean中获得R、G、B三个分量的像素值

ComposeRGB24(m_pRed,m_pGreen,m_pBlue,m_pImageBuffer); //将处理后的图像数据放到buffer中,返回显示处理结果

附:

//从24位位图数据中提取红、绿、蓝三个分量

BOOL CTest1Doc::ExtractRGB24Channels(BYTE *data, BYTE *pRed, BYTE *pGreen, BYTE *pBlue)

{

int i,j,size;

size = width*height;

for (i=size-1,j=0; i>= 0; i–,j+=3)

{ pBlue[i] = data[j];}

for (i=size-1,j=1; i>=0; i–,j+=3)

{pGreen[i] = data[j];}

for (i=size-1,j=2; i>=0; i–,j+=3)

{pRed[i] = data[j]; }

return TRUE;

}

//将红、绿、蓝三个分量合成24位位图数据

BOOL CTest1Doc::ComposeRGB24(BYTE *pRed, BYTE *pGreen, BYTE *pBlue, BYTE *data)

{

int i,j,size;

size = width*height;

for (i=size-1,j=0; i>= 0; i–,j+=3)

{data[j] = pBlue[i]; }

for (i=size-1,j=1; i>=0; i–,j+=3)

{data[j] = pGreen[i]; }

for (i=size-1,j=2; i>=0; i–,j+=3)

{ data[j] = pRed[i];}

return TRUE;

}

要在VC中灵活地调用HALCON中的库函数,还需要不断地去试验和摸索,总结经验教训,方能更好运用HALCON进行二次开发。我还在学习的路上,愿与共同研究HALCON的人探讨,欢迎交流~

 

Halcon形状匹配在图像仿射变换中的应用

在机器视觉应用中,经常需要对图像进行仿射变换。

1、在基于参考的视觉检测中,由于待检图像与参考图像或多或少都会存在几何变化(平移、旋转、缩放等),所以在做比较之前一般都要对待检图像进行仿射变换以对齐图像。

2、要进行仿射变换,必须先获取变换矩阵,形状匹配是获取变换矩阵的一种高效的方法。

3、Halcon的如下几个函数是专门用于计算变换矩阵的:

vector_angle_to_rigid :Compute a rigid affine transformation from points and angles.

vector_to_rigid :Approximate a rigid affine transformation from point correspondences.

vector_to_similarity :Approximate an similarity transformation from point correspondences.

vector_to_hom_mat2d :Approximate an affine transformation from point correspondences.

4、Halcon中用于形状匹配的函数有:

find_shape_model :Find the best matches of a shape model in an image.

find_shape_models :Find the best matches of multiple shape models.

find_scaled_shape_model :Find the best matches of a scale invariant shape model in an image.

find_scaled_shape_models :Find the best matches of multiple scale invariant shape models.

5、单匹配计算刚性变换矩阵:vector_angle_to_rigid只需要一个点对及一个角度对即可计算刚性变换矩阵,所以可直接利用find_shape_model的结果,但精度可能稍低。

6、双匹配计算刚性变换矩阵:vector_to_rigid需要至少两个点对的支持,所以需要用两次find_shape_model或用一次find_shape_models,精度会比单匹配高,但仍局限于刚性变换。

7、双匹配计算相似变换矩阵:vector_to_similarity用于计算相似变换矩阵,需要至少两个点对的支持,所以需要用两次find_scaled_shape_model或用一次find_scaled_shape_models。

8、三匹配计算一般变换矩阵:vector_to_hom_mat2d用于计算一般的其次变换矩阵,需要至少三个点对的支持,所以需要用三次find_scaled_shape_model或用一次find_scaled_shape_models。

9、综上,在不同情况下,选用相应的变换矩阵类型、形状匹配方法,可以达到事半功倍的效果!

转载注明来源:CV视觉网 » 博客halcon学习经验总结(2)

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

1不错 1超赞 0无聊 0扯淡 0不解 1路过

评论 抢沙发

评论前必须登录!