版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://www.blogbus.com/kalikaliu-logs/64827428.html
现在做的lazy snapping抠图工具先要根据kmeans来找出前景和背景中被用户标记的像素的均值,所以要用到opencv里面的cvKmeans函数。
cvKmeans的参数列表:
const CvArr* samples, //sample通常是一个m*n的矩阵,被理解为一个由m个vector组成的数组,其中每个vector的维度是n
int cluster_count, //这是自己需要的cluster个数
CvArr* labels,//为每一个vector标记一个lable,确定它属于哪一个cluster
CvTermCriteria termcrit, //termination criteria终止循环的限定值
int attempts CV_DEFAULT(1),//没太明白
CvRNG* rng CV_DEFAULT(0), //同上
int flags CV_DEFAULT(0),
CvArr* _centers CV_DEFAULT(0),//返回各个cluster的中心
//double* compactness CV_DEFAULT(0) )
我需要得到的是像素的聚类中心,聚类的根据是像素的RGB值以及坐标,即求出(R,G,B,x,y)相似的一些cluster。
------------------------------------------------------------------------------------------------------------------------------------
// Load in an image
// Depth: 8, Channels: 3
IplImage* iplImage = cvLoadImage("C:/TestImages/rainbox_box.jpg");
// Create a matrix to the image
cv::Mat mImage = cv::Mat(iplImage);
// Create a single channel image to create our labels needed
IplImage* iplLabels = cvCreateImage(cvGetSize(iplImage), iplImage->depth, 1);
// Convert the image to grayscale
cvCvtColor(iplImage, iplLabels, CV_RGB2GRAY);
// Create the matrix for the labels
cv::Mat mLabels = cv::Mat(iplLabels);
// Create the labels
int rows = mLabels.total();
int cols = 1;
cv::Mat list(rows, cols, mLabels .type());
uchar* src;
uchar* dest = list.ptr(0);
for(int i=0; i<mLabels.size().height; i++)
{
src = mLabels.ptr(i);
memcpy(dest, src, mLabels.step);
dest += mLabels.step;
}
list.convertTo(list, CV_32F);
// Run the algorithm
cv::Mat labellist(list.size(), CV_8UC1);
cv::Mat centers(6, 1, mImage.type());
cv::TermCriteria termcrit(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0);
kmeans(mImage, 6, labellist, termcrit, 3, cv::KMEANS_PP_CENTERS, centers);