int CmSaliencyRC::Quantize(CMat& img3f, Mat &idx1i, Mat &_color3f, Mat &_colorNum, double ratio, const int clrNums[3]) { float clrTmp[3] = {clrNums[0] - 0.0001f, clrNums[1] - 0.0001f, clrNums[2] - 0.0001f}; int w[3] = {clrNums[1] * clrNums[2], clrNums[2], 1}; CV_Assert(img3f.data != NULL); idx1i = Mat::zeros(img3f.size(), CV_32S); int rows = img3f.rows, cols = img3f.cols; if (img3f.isContinuous() && idx1i.isContinuous()){ cols *= rows; rows = 1; } // Build color pallet map<int, int> pallet; for (int y = 0; y < rows; y++) { const float* imgData = img3f.ptr<float>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++, imgData += 3) { idx[x] = (int)(imgData[0]*clrTmp[0])*w[0] + (int)(imgData[1]*clrTmp[1])*w[1] + (int)(imgData[2]*clrTmp[2]); pallet[idx[x]] ++; } } // Find significant colors int maxNum = 0; { int count = 0; vector<pair<int, int>> num; // (num, color) pairs in num num.reserve(pallet.size()); for (map<int, int>::iterator it = pallet.begin(); it != pallet.end(); it++) num.push_back(pair<int, int>(it->second, it->first)); // (color, num) pairs in pallet sort(num.begin(), num.end(), std::greater<pair<int, int>>()); maxNum = (int)num.size(); int maxDropNum = cvRound(rows * cols * (1-ratio)); for (int crnt = num[maxNum-1].first; crnt < maxDropNum && maxNum > 1; maxNum--) crnt += num[maxNum - 2].first; maxNum = min(maxNum, 256); // To avoid very rarely case if (maxNum <= 10) maxNum = min(10, (int)num.size()); pallet.clear(); for (int i = 0; i < maxNum; i++) pallet[num[i].second] = i; vector<Vec3i> color3i(num.size()); for (unsigned int i = 0; i < num.size(); i++) { color3i[i][0] = num[i].second / w[0]; color3i[i][1] = num[i].second % w[0] / w[1]; color3i[i][2] = num[i].second % w[1]; } for (unsigned int i = maxNum; i < num.size(); i++) { int simIdx = 0, simVal = INT_MAX; for (int j = 0; j < maxNum; j++) { int d_ij = vecSqrDist<int, 3>(color3i[i], color3i[j]); if (d_ij < simVal) simVal = d_ij, simIdx = j; } pallet[num[i].second] = pallet[num[simIdx].second]; } } _color3f = Mat::zeros(1, maxNum, CV_32FC3); _colorNum = Mat::zeros(_color3f.size(), CV_32S); Vec3f* color = (Vec3f*)(_color3f.data); int* colorNum = (int*)(_colorNum.data); for (int y = 0; y < rows; y++) { const Vec3f* imgData = img3f.ptr<Vec3f>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++) { idx[x] = pallet[idx[x]]; color[idx[x]] += imgData[x]; colorNum[idx[x]] ++; } } for (int i = 0; i < _color3f.cols; i++) color[i] /= (float)colorNum[i]; return _color3f.cols; }
#include "ColorTable.h" color3i const ch20m151010[255] = { color3i(0,0,0), color3i(0,1,0), color3i(0,2,0), color3i(1,4,1), color3i(1,5,1), color3i(1,7,1), color3i(2,8,2), color3i(3,9,2), color3i(3,11,2), color3i(4,12,2), color3i(5,13,2), color3i(6,15,2), color3i(6,16,2), color3i(7,17,2), color3i(8,18,2), color3i(9,19,2), color3i(11,20,2), color3i(12,22,2), color3i(13,23,2), color3i(14,24,2), color3i(16,25,2), color3i(17,26,2), color3i(19,26,2), color3i(20,27,2), color3i(22,28,2),