Ask Your Question
1

Colour Quantization

asked 2012-12-18 09:36:11 -0600

imran gravatar image

updated 2016-04-13 10:20:39 -0600

LBerger gravatar image

Does anyone know if there are any Colour Quantization (Colour Reduction) methods in OpenCV?

If so, could you please guide me to where it is? Or anyone else that has implemented it using OpenCV?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
3

answered 2012-12-19 00:17:44 -0600

updated 2012-12-19 02:14:06 -0600

for color quantization without number of color you can use cvPyrMeanShift else quantization with number of color you can use cvKmean.In the KMean method the number of clusters is equal to number of the output colors and convert the input image rows/columns as a set of 1D vectors with 3 component(RGB).You have to use KMean in 3D instead of 2D. For quantization by KMean use the below code.

void bhQuantizeImage(IplImage* srcImage,IplImage* dstImage,int colorCount)
{
     int i, size;

  CvMat *clusters;
  CvMat *points;
  CvMat *color = cvCreateMat (colorCount, 1, CV_32FC3);
  CvMat *count = cvCreateMat (colorCount, 1, CV_32SC1);


  size = srcImage->width * srcImage->height;
  dstImage = cvCloneImage (srcImage);
  clusters = cvCreateMat (size, 1, CV_32SC1);
  points = cvCreateMat (size, 1, CV_32FC3);

  for (i = 0; i < size; i++) {
    points->data.fl[i * 3 + 0] = (uchar) srcImage->imageData[i * 3 + 0];
    points->data.fl[i * 3 + 1] = (uchar) srcImage->imageData[i * 3 + 1];
    points->data.fl[i * 3 + 2] = (uchar) srcImage->imageData[i * 3 + 2];
  }

  cvKMeans2 (points, colorCount, clusters, cvTermCriteria (CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0));

  cvSetZero (color);
  cvSetZero (count);
  for (i = 0; i < size; i++) {
    int idx = clusters->data.i[i];
    int j = ++count->data.i[idx];;
    color->data.fl[idx * 3 + 0] = color->data.fl[idx * 3 + 0] * (j - 1) / j + points->data.fl[i * 3 + 0] / j;
    color->data.fl[idx * 3 + 1] = color->data.fl[idx * 3 + 1] * (j - 1) / j + points->data.fl[i * 3 + 1] / j;
    color->data.fl[idx * 3 + 2] = color->data.fl[idx * 3 + 2] * (j - 1) / j + points->data.fl[i * 3 + 2] / j;
  }

  for (i = 0; i < size; i++) {
    int idx = clusters->data.i[i];
    dstImage->imageData[i * 3 + 0] = (char) color->data.fl[idx * 3 + 0];
    dstImage->imageData[i * 3 + 1] = (char) color->data.fl[idx * 3 + 1];
    dstImage->imageData[i * 3 + 2] = (char) color->data.fl[idx * 3 + 2];
  }


  cvReleaseMat (&clusters);
  cvReleaseMat (&points);
  cvReleaseMat (&color);
  cvReleaseMat (&count);
}
edit flag offensive delete link more

Comments

Thanks for the guidance.

imran gravatar imageimran ( 2012-12-20 10:02:06 -0600 )edit

Thanks for the detailed answer. If possible though; can some documentation be added to the code to highlight the key tasks for further elaboration?

user1446598 gravatar imageuser1446598 ( 2013-03-31 10:46:45 -0600 )edit
1

answered 2012-12-18 10:28:38 -0600

SR gravatar image

Choose k-colors by using k-means clustering

edit flag offensive delete link more

Comments

Thanks for the guidance

imran gravatar imageimran ( 2012-12-20 10:01:23 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2012-12-18 09:36:11 -0600

Seen: 6,660 times

Last updated: Dec 19 '12