#include "stdafx.h" #include <opencvcv.h> #include <opencvhighgui.h> #include <opencv2legacylegacy.hpp> int _tmain(int argc, _TCHAR* argv[]) { CvEM em_model; //CvEM em_model2; CvEMParams params; int N=3; //设置模型参数 params.covs = NULL; params.means = NULL; params.weights = NULL; params.probs = NULL; params.nclusters = N; params.cov_mat_type = CvEM::COV_MAT_SPHERICAL; //params.cov_mat_type = CvEM::COV_MAT_DIAGONAL; params.start_step = CvEM::START_AUTO_STEP; params.term_crit.max_iter = 10; params.term_crit.epsilon = 0.1; params.term_crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS; IplImage* img=cvLoadImage("frame18843.jpg");//加载图像,图像放在Debug文件夹里,这里是相对路径 cvNamedWindow( "原始图像", 1 ); //创建窗口 cvShowImage( "原始图像", img ); //显示图像 //cvWaitKey(0); //等待按键 int i,j; CvMat *samples=cvCreateMat((img->width)*(img->height),3,CV_32FC1);//创建样本矩阵,CV_32FC3代表32位浮点3通道(彩色图像) CvMat *clusters=cvCreateMat((img->width)*(img->height),1,CV_32SC1);//创建类别标记矩阵,CV_32SF1代表32位整型1通道 cvReshape( samples, samples, 3, 0 ); int k=0; for (i=0;i<img->width;i++) { for (j=0;j<img->height;j++) { CvScalar s; //获取图像各个像素点的三通道值(RGB) s.val[0]=(float)cvGet2D(img,j,i).val[0]; s.val[1]=(float)cvGet2D(img,j,i).val[1]; s.val[2]=(float)cvGet2D(img,j,i).val[2]; cvSet2D(samples,k++,0,s);//将像素点三通道的值按顺序排入样本矩阵 } } int nCuster=3;//聚类类别数,自己修改。 //cvKMeans2(samples,nCuster,clusters,cvTermCriteria(CV_TERMCRIT_ITER,100,1.0));//开始聚类,迭代100次,终止误差1.0 cvReshape( samples, samples, 1, 0 ); em_model.train( samples, 0, params, clusters ); IplImage *bin=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);//创建用于显示的图像,二值图像 k=0; int val=0; float step=255/(nCuster-1); for (i=0;i<img->width;i++) { for (j=0;j<img->height;j++) { val=(int)clusters->data.i[k++]; CvScalar s; s.val[0]=255-val*step;//这个是将不同类别取不同的像素值, cvSet2D(bin,j,i,s); //将每个像素点赋值 } } cvNamedWindow( "聚类图像", 1 ); //创建窗口 cvShowImage( "聚类图像", bin ); //显示图像 cvWaitKey(0); //等待按键 cvDestroyWindow( "原始图像" );//销毁窗口 cvReleaseImage( &img ); //释放图像 cvDestroyWindow( "聚类图像" );//销毁窗口 cvReleaseImage( &bin ); //释放图像 return 0; }