Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

assuming a 3channel, bgr image (CV_8UC3):

Mat ocv = ...

// convert to float & reshape to a [3 x W*H] Mat 
//  (so every pixel is on a row of it's own)
Mat data;
ocv.convertTo(data,CV_32F);
data = data.reshape(1,data.total());

// do kmeans
Mat labels, centers;
kmeans(data, 8, labels, TermCriteria(CV_TERMCRIT_ITER, 10, 1.0), 3, 
       KMEANS_PP_CENTERS, centers);

// reshape both to a single row of Vec3f pixels:
centers = centers.reshape(3,centers.rows);
data = data.reshape(3,data.rows);

// replace pixel values with their center value:
Vec3f *p = data.ptr<Vec3f>();
for (size_t i=0; i<data.rows; i++) {
   int center_id = labels.at<int>(i);
   p[i] = centers.at<Vec3f>(center_id);
}

// back to 2d, and uchar:
ocv = data.reshape(3, ocv.rows);
ocv.convertTo(ocv, CV_8U);