#include #include #include #include using namespace cv; using namespace std; // https://stackoverflow.com/a/34734939/5008845 void reducecolor_quantization(const mat3b& src, mat3b& dst) { uchar n = 64; dst = src / n; dst *= n; } // https://stackoverflow.com/a/34734939/5008845 void reducecolor_kmeans(const mat3b& src, mat3b& dst) { int k = 8; int n = src.rows * src.cols; mat data = src.reshape(1, n); data.convertto(data, cv_32f); vector labels; mat1f colors; kmeans(data, k, labels, cv::termcriteria(), 1, cv::kmeans_pp_centers, colors); for (int i = 0; i < n; ++i) { data.at(i, 0) = colors(labels[i], 0); data.at(i, 1) = colors(labels[i], 1); data.at(i, 2) = colors(labels[i], 2); } mat reduced = data.reshape(3, src.rows); reduced.convertto(dst, cv_8u); } void reducecolor_stylization(const mat3b& src, mat3b& dst) { stylization(src, dst); } void reducecolor_edgepreserving(const mat3b& src, mat3b& dst) { edgepreservingfilter(src, dst); } struct lessvec3b { bool operator()(const vec3b& lhs, const vec3b& rhs) const { return (lhs[0] != rhs[0]) ? (lhs[0] < rhs[0]) : ((lhs[1] != rhs[1]) ? (lhs[1] < rhs[1]) : (lhs[2] < rhs[2])); } }; map getpalette(const mat3b& src) { map palette; for (int r = 0; r < src.rows; ++r) { for (int c = 0; c < src.cols; ++c) { vec3b color = src(r, c); if (palette.count(color) == 0) { palette[color] = 1; } else { palette[color] = palette[color] + 1; } } } return palette; } int main() { mat3b img = imread("path_to_image"); // reduce color mat3b reduced; //reducecolor_quantization(img, reduced); reducecolor_kmeans(img, reduced); //reducecolor_stylization(img, reduced); //reducecolor_edgepreserving(img, reduced); // get palette map palette = getpalette(reduced); // print palette int area = img.rows * img.cols; for (auto color : palette) { cout << "color: " << color.first << " \t - area: " << 100.f * float(color.second) / float(area) << "%" << endl; } return 0; }