许美珍,武建新
(内蒙古工业大学机械学院,内蒙古呼和浩特 010051)
雪糕棒检验是依据图像识别技术针对出口雪糕棒表面污染、破损、尺寸不合格等问题设计的在线产品检验的设备。该设备利用传送带将雪糕棒依次通过视觉检测设备完成次品的剔除。为了替代生产中人类检测雪糕棒的工作,同时效率也能兼备,故提出了比较高效的图像处理算法。
本设计采用的是版本是 OpenCV2.4.8,要在VS2010中利用OpenCV进行图像处理,需要在VS环境下对OpenCV做相应的配置,使得VS在编译的时候能够调用OpenCV中的库函数和头文件[1]。
不同类型的图像内部结构不同,需要根据图像的结构采用不同的方法将图像文中的数据读入内存。OpenCV是一个C函数库,既实现了基础设施的操作,也实现了图像处理和视觉函数[2]。IplImage数据结构是图像在内存内的数据组织形式。读取图像函数是cvLoad Image,即给定一个文件的路径,该函数从这个文件中读入一个图像,此文件存储的图像由工业相机捕捉。
在OpenCV中的highgui库,可以通过cvNamed-Window函数创建窗口,然后用cvShow Image函数在刚创建的窗口中显示图像,也就是通过IplImage指针指定的图像。
本设计程序应用了cvShow Image()来显示图像,就必须用到cvWaitKey()函数使程序暂停,cvWaitKey()是专门在OpenCV的GUI界面下等待键盘命令,能使用户很好观察到图像。cvReleaseImage()cvDestroyWindow()用于释放所占用的内存。雪糕棒检验需要处理大量的图像,在处理工程中这将会占用很大的内存,在运作工作中将会溢出导致工作中断,所以必须在处理图像后需释放内存,方便后续处理。
图像处理的效果在很大程度上取决于图像的质量,图像预处理旨在消除图像中的干扰信息,恢复真实信息,增强有关信息的可检测性和最大限度地简化数据,从而加强特征提取、图像分割、匹配和识别等图像处理的可靠性。
2.4.1 光源校正
如图1、2所示,对于图像光照不均匀的,其轮廓等将不能很好的显现处理。这种方法能够将图片中的细节更多地体现出来,从而纠正了检测过程中由于光线不足引起灰度不均匀,使得图像质量提高,提高了检测精度。运用VS并调用OpenCV视觉库编程,对其进行光源校正处理,纠正了检测过程中由于光线不足引起灰度不均匀。次品剔除程序中光源校正函数为Lightcorrection(IplImage* OriginalImage,IplImage*CorrectImage,double a[])。函数实现功能:对原始采集的图像进行光源的校正。
图1 雪糕棒原图像
图2 雪糕棒外接轮廓图像
2.4.2 图像的二值化
二值图像是每个像素都只有黑、白色的图像,首先设置一个阈值,然后将图像上的像素点值大于阈值的用255代替,小于阈值的用0取代。通过选择不同的阈值将256个灰度等级的原始图像转化为二值图像[3],并且转化后的二值图像依然能反映出原始图像的整体信息和局部特征点,并且有利于减小图像的信息量。二值化图像处理的阈值,可以跟据实际需要进行合理选择。经过对比,雪糕棒图像的阈值选取80。
2.4.3 图像寻找最大轮廓
OpenCV中绘制轮廓的函数:cvDrawContours,根据实际要求max_level取0(绘制轮廓的最大等级),为绘制单独的轮廓;thickness取1(绘制轮廓时所使用的线条的粗细度);line_type取8(线条的类型)。本程序查询雪糕棒最大轮廓CvSeq* cmax=first_contour;利用循环结构体指针查找最大轮廓。
图3 雪糕棒最小外接矩形
寻找到雪糕棒最大轮廓后,依据最小外接矩形函数,画出雪糕棒最大轮廓的最小外接矩,如图3,是为了得到矩形框上图像的数据,包括点的坐标等,为下一步算法的建立做铺垫。还需将图像旋转至水平(cvGetQuadrangleSubPix(pLighted Img,pRotatedImg,&cMat);)。
2.4.4 最大轮廓的填充
在次品剔除程序中对雪糕棒最大轮廓的填充,是为了区分轮廓内外的灰度值,从而依据迭代器算法判断灰度值对雪糕棒进行形状检测。
在OpenCV中迭代器cvInitLineIterator是对任意直线上的像素进行采样,只要定义了线段的起始点和终止点就可以对这条线段上所有点进行采样,这样就得到两点之间的像素点数目和每个像素点的灰度值等[4]。
在次品剔除程序中利用迭代器统计两点之间点个数,并且输出每个点的灰度值的功能将迭代器函数循环,判断二值化图像灰度值为255的点(即白色点)的个数,将统计得到宽/长度方向的白点个数与没有缺肉情况下标准白点个数比较从而判断是否有缺肉情况,达到形状检测的目的。
建立并初始化迭代器后,可以连续通过调用CV_NEXT_LINE_POINT获取线段上点的坐标。本程序首先建立了 pt[1]到 pt[2]和 pt[0]到 pt[3]两个迭代器,定义了ptd[10000]和 pte[10000]两个数组分别存放线段上点的坐标值。
提取坐标点的关键函数:offset=iterator1.ptr(uchar*)(mask->imageData);
为了验证迭代器取点的准确性以及为下一步程序做铺垫,次品剔除程序中采用了迭代器画线程序。函数原型:cvLine(CvArr* img,CvPoint pt1,CvPoint pt2,CvScalar color,int thickness=1,int line_type=8,int shift=0);指定线条颜色的时候用到的宏 CV_RGB(r,g,b)定义为#define CV_RGB(r,g,b)cvScalar((b),(g),(r),0),由此可见,实际上起作用的颜色是看cvScalar中的b,g,r顺序,线段颜色就不言而喻了。
对雪糕棒模板图像,即对最大外接轮廓填充后的图像进行迭代器算法。通过循环建立迭代器遍历图像内部所有像素点,判断灰度值并统计灰度值为255的点个数(即白点个数),将统计得到的白点个数与标准白点个数比较从而判断是否有缺肉情况,从而实现形状检测的目的。由于图像是未经过旋转轮廓的,所以遍历所有像素点要通过连续调用CV_NEXT_LINE_POINT(iterator)来实现从上一个像素点移到下一个像素点的功能。在检测程序中要定义一个一维数组并进行初始化,初始化函数为memset(a,0,sizeof(a));将统计得到的白点个数累加到该数组中,最后统计结果为:纵向白点个数为117左右,横向白点个数为1 396左右。
利用迭代器算法中iterator.ptr[]可以显示图像内部任意点的灰度值的功能,将迭代器循环建立遍历图像内部所有像素点的灰度值。这里用到的遍历方法与统计白点个数的相同,将所有点灰度值累加后除以点个数得到雪糕棒图像的灰度平均值[5]。本程序得到的灰度平均值为134,并且创建灰度级范围100~255的一维灰度直方图。
由运行结果,利用旋转轮廓图像处理程序的运行时间则为0.134 s左右,而利用迭代算法运行时间为0.013 s左右,分析可得采用迭代算法比旋转轮廓的检测效率高10倍左右,这样会大大提高企业在生产实际中的生产效率,节约成本。这也是本程序采用迭代算法要实现的最终目的。
针对出口雪糕棒表面污染、破损、尺寸不合格等问题设计合适的算法,通过Microsoft Visual Studio 2010和OpenCV2.4.8编制程序,最终通过雪糕棒图像预处理,包括二值化、寻找最大轮廓、轮廓填充、寻找最小外接矩形;并且运用迭代算法建立迭代器从而实现雪糕棒次品剔除的目的。
[1] 于仕琪,刘瑞祯.学习 OpenCV(中文版)[M].北京:清华大学出版社,2009.
[2] 章毓晋.图像处理和分析技术[M].第二版.北京:高等教育出版社,2008.
[3] 朱 虹.数字图像处理基础[M].北京:北京科学出版社,2005.
[4] 方 玫,喻擎苍,李华强,等.C++下基 于OpenCV的数字图像的处理[J].计算机工程与设计,2008,29(4):882-884.
[5] 黄 佳.基于0PENCV的计算机视觉技术研究[D].上海:华东理工大学,2012.