Пример #1
0
template<class T, int D> inline T vecDist( const cv::Vec<T, D> &v1, const cv::Vec<T, D> &v2 )
{
    return sqrt( vecSqrDist( v1, v2 ) );
}  // out of range risk for T = byte, ...
Пример #2
0
int CmColorQua::D_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
	for (int y = 0; y < rows; y++)	{
		const float* imgDataP = img3f.ptr<float>(y);
		int* idx = idx1i.ptr<int>(y);
#pragma omp parallel for
		for (int x = 0; x < cols; x++){
			const float* imgData = imgDataP + 3*x;
			idx[x] = (int)(imgData[0]*clrTmp[0])*w[0] + (int)(imgData[1]*clrTmp[1])*w[1] + (int)(imgData[2]*clrTmp[2]);
		}
	}
	map<int, int> pallet;
	for (int y = 0; y < rows; y++)	{
		int* idx = idx1i.ptr<int>(y);
		for (int x = 0; x < cols; x++)
			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; 

		int numSZ = num.size();
		vector<Vec3i> color3i(numSZ);
#pragma omp parallel for
		for (int i = 0; i < numSZ; 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;
#pragma omp parallel for
			for (int j = 0; j < maxNum; j++) {
				int d_ij = vecSqrDist(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);
#pragma omp parallel for
		for (int x = 0; x < cols; x++)	
			idx[x] = pallet[idx[x]];
		for (int x = 0; x < cols; x++)	{
			color[idx[x]] += imgData[x];
			colorNum[idx[x]] ++;
		}
	}
	for (int i = 0; i < _color3f.cols; i++)
		color[i] /= colorNum[i];

	return _color3f.cols;
}