• 基于K-MEANS聚类的胡萝卜纯色背景去除方法


    所谓的聚类是指,将一个数据集中的某些方面相似的数据成员进行分类的过程,聚类就是一种发现这种内在结构的技术,聚类技术经常被称为无监督学习。k均值聚类是最著名的划分聚类算法,由于简洁和效率使得他成为所有聚类算法中最广泛使用的。给定一个数据点集合和需要的聚类数目k,k由用户指定,k均值算法根据某个距离函数反复把数据分入k个聚类中。
    1. k均值算法描述
    先随机选取K个对象作为初始的聚类中心。然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是以下任何一个:
    1)没有(或最小数目)对象被重新分配给不同的聚类。
    2)没有(或最小数目)聚类中心再发生变化。
    3)误差平方和局部最小。
     
    而基于K均值的胡萝卜图像的分类,则是利用分类的思想,将目标区与背景区分成两类,所以,在此处将 K 的值,设置为 2;因为,是根据灰度值进行划分,则误差设置为1作为终止条件;
    算法具体实现代码如下所示:
    IplImage* img = cvCloneImage(m_sourceImage);
    		IplImage* grayImage = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    		//IplImage* redImage = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    
    		//cvSplit(img, NULL, NULL, redImage, NULL);
    
    		cvCvtColor(img, grayImage, CV_RGB2GRAY);
    		//IplImage* img = cvCreateImage(cvGetSize(m_sourceImage), IPL_DEPTH_8U, 1);
    		//cvCvtColor(m_sourceImage, img, CV_RGB2GRAY);
    		int total = img->height*img->width;
    		int cluster_num = 2;
    		CvMat *row = cvCreateMat(img->height, img->width, CV_32FC3);
    		//cvConvert(redImage, row);
    		cvConvert(img, row);//转一下类型!
    		CvMat *clusters = cvCreateMat(total, 1, CV_32SC1);
    
    // 		CvArr* cvReshapeMatND(const CvArr* arr,
    // 			int sizeof_header, CvArr* header,
    // 			int new_cn, int new_dims, int* new_sizes);
    // 
    // 		arr :输入数组
    // 		sizeof_header :输出头的大小,对于IplImage, CvMat 和 CvMatND 各种结构输出的头均是不同的.
    // 		header:被添充的输出头.
    // 		new_cn:新的通道数,如果new_cn = 0 则通道数保持原样
    //		new_dims:新的维数.如果new_dims = 0 则维数保持原样。
    // 			new_sizes
    // 			新的维大小.只有当 new_dims = 1值被使用,因为要保持数组的总数一致,因此如果 new_dims = 1, new_sizes 是不被使用的
    
    
    		cvReshape(row, row, 0, total);						//把图像转成数据矩阵,但注意实际数据未变,只是访问顺序变了。
    		cvKMeans2(row, cluster_num, clusters, cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0));
    		cvReshape(clusters, clusters, 0, img->width);		//聚类完的结果再reshape回来比较方便看~
    		int i = 0, j = 0;
    		CvScalar s;
    		IplImage* resImg = cvCreateImage(cvSize(img->width, img->height), 8, 1);//生成用来显示结果的图像
    		s = cvGet2D(img, i, j);
    
    		vector <int> v1, v2;		//存放分类后的灰度值
    
    
    		for (i = 0; i < img->height; i++)
    		{
    			for (j = 0; j < img->width; j++)
    			{
    				double val = cvGetReal2D(grayImage, i, j);
    
    				if (clusters->data.i[i*img->width + j] == 0)
    				{
    					v1.push_back(val);				//处理完成后的图像的白色区域
    					s.val[0] = 255;
     					cvSet2D(resImg, i, j, s);//注意循环顺序
    				}
    				else
    				{
    					v2.push_back(val);				//处理完成后的图像的黑色区域
    					s.val[0] = 0;
    					cvSet2D(resImg, i, j, s);
    				}
    			}
    		}
    
    		double thresh1 = accumulate(v1.begin(), v1.end(), 0) / v1.size();
    		double thresh2 = accumulate(v2.begin(), v2.end(), 0) / v2.size();
    
    		if (thresh2 > thresh1)		//如果黑色区域的灰度值均值大于白色区域
    		{
    			cvNot(resImg, resImg);	//图像取反
    		}
    
    		IplConvKernel *element = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE);
    		cvSmooth(resImg, resImg, CV_MEDIAN);
    		cvErode(resImg, resImg, element, 1);
    		cvDilate(resImg, resImg, element, 1);
    		cvReleaseStructuringElement(&element);
    
    		cvSaveImage("s2.jpg", m_sourceImage);
    		cvSaveImage("b2.jpg", resImg);
    
    		ShowImage(resImg, IDC_PIC2);
    
    		int key = cvWaitKey(0);
    		cvReleaseImage(&img);//记得释放内存
    		cvReleaseImage(&resImg);
    		cvReleaseMat(&row);
    		cvReleaseMat(&clusters);
    

      上述代码,对图像的处理结果进行了校正,因为,K-Mean聚类,只是简单的将目标区与背景区进行分类,而不能明确的标记出目标区还是背景区,所以,根据经验,将灰度值均值较大的部分作为目标区;

    而灰度值较小的部分标记为背景区;

    以下为未校正图像与校正后图像的对比:

    如上图所示:左侧图像为未做校正的处理效果,右侧图像为校正后的图像;

    由于此方法只是简单的根据图像的灰度值对图像进行二值化,所以,很难对复杂背景的图像进行分割;相关的算法,在以后的学习中再进行完善与补充。

  • 相关阅读:
    Struts2 helloWorld
    Python学习笔记基础汇总部分
    从控制台读入,典型的装饰者模式
    随机数产生方法小知识点
    Struts2基础知识
    面向对象原则之GOF是招式,九大原则才是精髓
    静态工厂方法
    单例模式singleton
    J2SE基础夯实系列之JDBC,链接数据库实例代码
    Ubuntu 12.04 下安装ssh 服务遇到的问题以及总结
  • 原文地址:https://www.cnblogs.com/lingtianyulong/p/4230575.html
Copyright © 2020-2023  润新知