#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; }