1、 K 均值聚类在基于 OpenCV 的图像分割中的应用 摘要 :基于人类视觉将图像分割成若干个有意义的区域是目标检测和模式识别的基础。 图像分割属于图像处理中一种重要的图像分析技术。图像分割的基本方法是对灰度图像分割,处理图像的亮度分量,简单快速。 本论文介绍了传统的图像分割与 K-均值聚类算法分割,然后利用 OpenCV函数将其实现,并介绍了OpenCV 中图像分割相关的基本函数。 关键词: K 均值聚类,图像分割, OpenCV 一、前言 根据抽象程度和处理方法的不同,图像技术可以分为三个层次: 图像处理、图像分析和图像理解 , 这三个层次的 有机结合也可以称为图像工程 。图像处理是较低层
2、的操作,主要在图像像素级上进行操作。有代表性的图像处理技术包括图像降噪、图像编码和图像分割。 图像分割是一种关键的图像处理技术 。作为后续图像分析和图像理解的基础,图像分割技术一直是图像理论发展的瓶颈之一。图像分割在实际中的应用非常广泛,对图像目标的提取、测量都离不开图像分割, 是图象处理、模式识别和人工智能等多个领域中一个十分重要且又十分困难的问题。 分割的准确性直接影响后续任务的有效性 ,因此具有十分重要的意义。 图像分割又是一种特殊的图像处理技术。像素级的 图像处理可以分成两类, 一类是针对像素值的处理 , 另一类是把像素分类的处理 。图像降噪技术、图像编码技术、数字水印技术等虽然各有其
3、特点和应用领域,但其实质都是针对像素值的操作。不同于这些技术, 图像分割,其实质是一个按照像素属性(灰度、纹理、颜色等)进行聚类的过程 。 二、图像分割概述 图像分割是一种重要的图像分析技术。在对图像的研究和应用中,人们往往仅对图像中的某些部分感兴趣。这些部分常称为目标或前景(其他部分称为背景)。它们一般对应图像中特定的、具有独特性质的区域。为了辨识和分析图像中的目标,需要将它们从图像中分 离提取出来,在此基础上才有可能进一步对目标进行测量,对图像进行利用。 图像分割就是把图像分成各具特性的区域并提取出感兴趣目标的技术和过程。 现有的图像分割方法主要分以下几类: 基于阈值的分割方法、基于区域的
4、分割方法、基于边缘的分割方法以及基于特定理论的分割方法等。 1、基于阈值的分割方法 包括全局阈值、自适应阈值、最佳阈值等等。阈值分割算法的关键是确定阈值,如果能确定一个合适的阈值就可准确地将图像分割开来。阈值确定后,将阈值与像素点的灰度值比较和像素分割可对各像素并行地进行,分割的结果直接给出图像区域。全局阈值是 指整幅图像使用同一个阈值做分割处理,适用于背景和前景有明显对比的图像。它是根据整幅图像确定的: T=T(f)。但是这种方法只考虑像素本身的灰度值,一般不考虑空间特征,因而对噪声很敏感。常用的全局阈值选取方法有利用图像灰度直方图的峰谷法、最小误差法、最大类间方差法、最大熵自动阈值法以及其
5、它一些方法。 2、基于边缘的分割方法 检测灰度级或者结构具有突变的地方,表明一个区域的终结,也是另一个区域开始的地方。这种不连续性称为边缘。不同的图像灰度不同,边界处一般有明显的边缘,利用此特征可以分割图像。图像中边缘处像素的灰 度值不连续,这种不连续性可通过求导数来检测到。对于阶跃状边缘,其位置对应一阶导数的极值点,对应二阶导数的过零点 (零交叉点 )。因此常用微分算子进行边缘检测。常用的一阶微分算子有 Roberts 算子、 Prewitt 算子和 Sobel 算子,二阶微分算子有 Laplace算子和 Kirsh算子等。在实际中各种微分算子常用小区域模板来表示,微分运算是利用模板和图像卷
6、积来实现。这些算子对噪声敏感,只适合于噪声较小不太复杂的图像。 3、基于聚类分析的图像分割方法 特征空间聚类法进行图像分割是将图像空间中的像素用对应的特征空间点表 示,根据它们在特征空间的聚集对特征空间进行分割,然后将它们映射回原图像空间,得到分割结果。其中, K 均值、模糊 C 均值聚类 (FCM)算法是最常用的聚类算法。 K均值算法先选 K个初始类均值,然后将每个像素归入均值离它最近的类并计算新的类均值。迭代执行前面的步骤直到新旧类均值之差小于某一阈值。模糊 C均值算法是在模糊数学基础上对 K均值算法的推广,是通过最优化一个模糊目标函数实现聚类,它不像 K 均值聚类那样认为每个点只能属于某
7、一类,而是赋予每个点一个对各类的隶属度,用隶属度更好地描述边缘像素亦此亦彼的特点,适合处理事物内在 的不确定性。利用模糊 C 均值 (FCM)非监督模糊聚类标定的特点进行图像分割,可以减少人为的干预,且较适合图像中存在不确定性和模糊性的特点。 三、 K 均值聚类分割算法 3.1 聚类 将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类。由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异。聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法。聚类分析计算方法主要有如下几种:划分方法,层次方法,基于密度的方法,基于网格的方
8、法,基于模型的方法。 K-均值聚类算法是著名的划分聚类分割方法。划分方法的基本思想是:给定一个有 N个元组或者纪录的数据集,分裂法将构造 K个分组,每一个分组就代表一个聚类, Kwidth;i+) for (j=0;jheight;j+) CvScalar s; /获取图像各个像素点的三通道值( RGB) s.val0=(float)cvGet2D(m_imagesrc,j,i).val0; s.val1=(float)cvGet2D(m_imagesrc,j,i).val1; s.val2=(float)cvGet2D(m_imagesrc,j,i).val2; cvSet2D(sample
9、s,k+,0,s); 这里用到 cvGet2D函数获取三通道值并利用 cvSet2D函数将三通道的值排入样本。函数如下: CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 ); Arr:输入数组。 idx0:元素下标第一个以 0 为基准的成员。 idx1:元素下标第二个以 0 为基准的成员。 void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value ); arr:输入数组。 idx0:元素下标的第一个成员,以 0 为基点。 idx1:元素下标的第二个成员,以 0 为基点。
10、 ( 2)对样本矩阵的值进行迭代聚类,迭代 100 次,终止误差 1.0。 cvKMeans2(samples,nCuster,clusters,cvTermCriteria(CV_TERMCRIT_ITER,100,1.0); 3、绘制聚类后的图像。 将聚类后的不同类别取不同的像素值,并对聚类后的图像的每个像素点赋值。 float step=255/(nCuster-1); for (i=0;iwidth;i+) for (j=0;jheight;j+) val=(int)clusters-data.ik+; CvScalar s; s.val0=255-val*step;, cvSet2D
11、(bin,j,i,s); 4、绘制灰度直方图。 ( 1)设置直方图尺寸和灰度范围 ,这里将显示范围设置为 -5 到 260,防止灰度值为 0 和 255 的直方图不显示。 int hist_size = 256; int hist_height = 256; float range = -5,260; float* ranges=range; (2)创建直方图,统计图像在 0 255像素的均匀分布 CvHistogram* gray_hist = cvCreateHist(1, cvCalcHist( cvNormalizeHist(gray_hist,1.0); int scale= 2;
12、/横坐标为灰度级,纵坐标为像素个数 *scale IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale,hist_height),8,3); cvZero(hist_image); float max_value = 0; cvGetMinMaxHistValue(gray_hist, 0, 其中 CvHistogram 为多维直方图类型,其定义如下: typedef struct CvHistogram int type; CvArr* bins; float threshCV_MAX_DIM2; float* thresh2
13、; CvMatND mat; CvHistogram; bins : 用于存放直方图每个灰度级数目的数组指针,数组在cvCreateHist 的时候创建其维数 由 cvCreateHist 确定。 而 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直方图的指针。其定义如下: CvHistogram* cvCreateHist( int dims, int* sizes, int type, float* ranges=NULL, int uniform=1 ); dims:直方图维数的数目。 sizes:直方图维数尺寸的数组。 type:直方图的表示格式 : CV_HIST
14、_ARRAY 意味着直方 图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat. Ranges:图中方块范围的数组 . 它的内容取决于参数 uniform 的值。这个范围的用处是确定何时计算直方图或决定反向映射( backprojected ),每个方块对应于输入图像的哪个 /哪组值。 Uniform:归一化标识。 而 CalcHist 用来计算图像 image 的直方图,其定义如下: void cvCalcHist( IplImage* image, CvHistogram* hist, int accumulate
15、=0, const CvArr* mask=NULL ); image:输入图像 (也可以使用 CvMat* )。 Hist:直方图指针。 Accumulate:累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。 Mask:操作 mask,确定输入图像的哪个象素被计数。 ( 3)分别将每个直方块的值绘制到图中 for( i=0;ibins, (idx0) ) hist:直方图。 idx0, idx1, idx2, idx3:直方块的下标索引。 idx:下标数组。 函数 cvRound,用一种舍入方法将输入浮点数转换成整数, 返回和
16、参数最接近的整数值。 cvRectangle 函 数用以绘制简单、指定粗细或者带填充的矩形,其定义如下: void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 ); img:目标图像。 pt1:矩形的一个顶点。 pt2:矩形对角线上的另一个顶点。 Color:线条颜色 (RGB) 或亮度(灰度图像 ) (grayscale image)。 Thickness:组成矩形的线条的粗细 程度。取负值时(如 CV_FILL
17、ED)函数绘制填充了色彩的矩形。 line_type:线条的类型。 Shift:坐标点的小数点位数。 5、实现结果如图 5-1、图 5-2 和图 5-3: 图 4-1 输入聚类类别数 图 4-2 分为 3类聚类后的图像和直方图 图 4-3 分为 5类聚类后的图像和直方图 参考文献: 1林开颜 ,吴军辉 ,徐立鸿 . 彩色图像分割方法综述 J . 中国图象图形学报 , 2005, 10 (1) :1- 10. 2滕升华 . 黑白影像的彩色化研究 D . 北京 :中国科学院电子学研 究所 , 2006. 3章毓晋图像分割 M北京:科学出版社, 200l 4蔡煦,朱波,曾广周一种彩色多级闯值的图像分割方法及在形状特征提取方面的应用 J山东大学学报 (工学版 ), 2002, 32(4): 333 336 5 吴国雄,陈武凡图像的模糊增强与聚类分割 J小型微型计算机系统, 1994, 15(11): 21 26