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的代码的深度优化和分析。



