#include "stdafx.h"
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <opencv2\legacy\legacy.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;
}