OpenCV实现超像素算法Slic

OpenCV实现超像素算法Slic,第1张

OpenCV实现超像素算法Slic
void run(cv::Mat & Image, int Iterations, int superpixels, int m)
{
	if(Image.type()!=CV_8UC3){
		return;
	}
	int s_step = sqrt(Image.cols*Image.rows / superpixels);

	int nc = m;
	int ns = s_step;
	int step = s_step;

	Mat LabImage;
	cvtColor(Image, LabImage, COLOR_BGR2Lab);
	//准备数据
	int cols = Image.cols;
	int rows = Image.rows;
	int *cluster = new int[cols*rows];
	int *distance = new int[cols*rows];
	
	std::vector mats;
	split(LabImage,mats);

	cv::Mat L=mats[0];
	cv::Mat A=mats[1];
	cv::Mat B=mats[2];

	//置为-1
	memset(cluster, 255, sizeof(int)*cols*rows);

	int *centers = new int[superpixels * 5];
	int *centersCvx = new int[superpixels * 5];

#ifdef _DEBUG
	cv::Mat LookCluster(rows, cols, CV_32S, cluster);
	cv::Mat LookDistance(rows, cols, CV_32S, distance);
	cv::Mat LookCenters(1, superpixels * 5, CV_32S, centers);
#endif // _DEBUG
	int CenterSize = 0;
	for (int i = step; i < rows - step / 2; i += step) {
		
		for (int j = step; j < cols - step / 2; j += step) {

			int MAXGrad = INT_MAX;
			int MinR =i;
			int MinC =j;
			for (int r = i - 1; r <= i + 1; r++) {
				for (int c = j - 1; c <=j + 1; c++) {
					int v1 = L.ptr(r - 1)[c - 1];
					int v2 = L.ptr(r - 1)[c];
					int v3 = L.ptr(r - 1)[c + 1];
					int v4 = L.ptr(r )[c - 1];
					int v6 = L.ptr(r)[c + 1];
					int v7 = L.ptr(r +1)[c - 1];
					int v8 = L.ptr(r + 1)[c];
					int v9 = L.ptr(r + 1)[c+1];

					int dy = v1 + v3 - v7 - v9 + 2 * (v2 - v8);
					int dx = v1 + v7 - v3 - v9 + 2 * (v4 - v6);
					int totalGrad = dx * dx + dy * dy;
					if (totalGrad < MAXGrad) {
						MinR = r;
						MinC = c;
					}
				}
			}
	
			centers[5 * CenterSize] = L.ptr(MinR)[MinC];
			centers[5 * CenterSize+1] = A.ptr(MinR)[MinC];
			centers[5 * CenterSize+2] = B.ptr(MinR)[MinC];
			centers[5 * CenterSize+3] = MinC;
			centers[5 * CenterSize+4] = MinR;
			CenterSize++;
		}
	}

	int NcPow=nc*nc;
	int NsPow = ns*ns;

	for (int it = 0; it < Iterations; it++) {

		memset(distance, 127, sizeof(int)*cols*rows);

		for (int i = 0; i < CenterSize; i++) {
			int l_base = centers[5 * i];
			int a_base = centers[5 * i + 1];
			int b_base = centers[5 * i + 2];
			int x = centers[5 * i + 3];
			int y = centers[5 * i + 4];

			int rMin = max(y - step, 0);
			int rMax = min(y + step, rows-1);

			int cMin = max(x - step, 0);
			int cMax = min(x + step, cols-1);
			
			for (int r = rMin; r < rMax; r++) {
				int *distancePtr = distance + r * cols;
				int *clusterPtr = cluster + r * cols;
				uchar *lPtr = L.ptr(r);
				uchar *aPtr = A.ptr(r);
				uchar *bPtr = B.ptr(r);
				for (int c = cMin; c < cMax; c++) {
					int MaxDistance = distancePtr[c];
					int l_run = lPtr[c];
					int a_run = aPtr[c];
					int b_run = bPtr[c];
					
					int ld = l_run - l_base;
					int ad = a_run - a_base;
					int bd = b_run - b_base;
					
					int xd = c - x;
					int yd = r - y;

					int D1 = (ld*ld + ad * ad + bd * bd)*NsPow;
					int D2 = (xd*xd+yd*yd)*NcPow;
					
					int D = D1 + D2;

					if (D < MaxDistance) {
						distancePtr[c] = D;
						clusterPtr[c] = i;
					}

				}

			}
		}
		memset(centers, 0, sizeof(int)*superpixels * 5);
		memset(centersCvx, 0, sizeof(int)*superpixels * 5);
		for (int r = 0; r < rows; r++) {
			int *clusterPtr = cluster + r * cols;
			uchar *lPtr = L.ptr(r);
			uchar *aPtr = A.ptr(r);
			uchar *bPtr = B.ptr(r);
			for (int c = 0; c < cols; c++) {
				int c_id = clusterPtr[c];
				if (c_id != -1) {

					centers[c_id * 5 + 0] += lPtr[c];
					centers[c_id * 5 + 1] += aPtr[c];
					centers[c_id * 5 + 2] += bPtr[c];
					centers[c_id * 5 + 3] += c;
					centers[c_id * 5 + 4] += r;
					
					centersCvx[c_id] += 1;
				}

			}
		}

		for (int j = 0; j < CenterSize; j++) {
			int cvx = centersCvx[j];
			if (cvx == 0) {
				continue;
			}
			centers[j * 5 + 0] /= cvx;
			centers[j * 5 + 1] /= cvx;
			centers[j * 5 + 2] /= cvx;
			centers[j * 5 + 3] /= cvx;
			centers[j * 5 + 4] /= cvx;
		}
	}

	delete[]centers;
	delete[]cluster;
	delete[]distance;
	delete[]centersCvx;
}

超像素经典算法SLIC的代码的深度优化和分析。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5711527.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存