Пример #1
0
    /**
     * @brief pass
     * @param img
     * @param S
     * @return
     */
    bool pass(Image *img, int S)
    {
        float Sf = float(S);
        float Sf2 = Sf * Sf;

        for(int i = 0; i < nSuperPixels; i++) {
            prevX[i] = centers[i].x;
            prevY[i] = centers[i].y;
        }

        //for each cluster
        for(int i = 0; i < nSuperPixels; i++) {
            float i_f = float(i);

            //Search in Sx2 radius
            for(int j = -S; j < S; j++) {
                int vY = centers[i].y + j;

                for(int k = -S; k < S; k++) {
                    int vX = centers[i].x + k;

                    float *pixel = (*img)(vX, vY);
                    float *l_d   = (*labels_distance)(vX, vY);

                    float dS = float(distanceS(vX, vY, centers[i].x, centers[i].y)) / Sf2;
                    float dC = distanceC(pixel, centers[i].value, img->channels) / mPixel[i];
                    float D = dC + dS;

                    if(D < l_d[1]) {
                        l_d[0] = i_f;
                        l_d[1] = D;
                        l_d[2] = dC;
                    }
                }
            }
        }

        //update mPixel
        for(int i = 0; i < labels_distance->size(); i += labels_distance->channels) {
            int label = int(labels_distance->data[i]);

            if(label < 0) {
                continue;
            }

            if(mPixel[label] < labels_distance->data[i + 2]) {
                mPixel[label] = labels_distance->data[i + 2];
            }
        }

        //update clusters
        for(int i = 0; i < nSuperPixels; i++) {
            centers[i].x = 0;
            centers[i].y = 0;
            counter[i]   = 0;

            int ind = i * img->channels;

            for(int j = 0; j < img->channels; j++) {
                col_values[ind + j] = 0.0f;
            }
        }

        for(int j = 0; j < img->height; j++) {
            for(int k = 0; k < img->width; k++) {
                float *l_d = (*labels_distance)(k, j);
                int label = int(l_d[0]);

                if(label > -1) {
                    centers[label].x += k;
                    centers[label].y += j;
                    counter[label]++;

                    int ind = label * img->channels;
                    float *col = (*img)(k, j);

                    for(int p = 0; p < img->channels; p++) {
                        col_values[ind + p] += col[p];
                    }
                }
            }
        }

        float E = 0.0f;

        for(int i = 0; i < nSuperPixels; i++) {
            if(counter[i] <= 0) {
                continue;
            }

            centers[i].x /= counter[i];
            centers[i].y /= counter[i];
            int ind = i * img->channels;

            for(int j = 0; j < img->channels; j++) {
                centers[i].value[j] = col_values[ind + j] / float(counter[i]);
            }

            //Error
            int tx = prevX[i] - centers[i].x;
            int ty = prevY[i] - centers[i].y;
            float tmpErr = sqrtf(float(tx * tx + ty * ty));
            E += tmpErr;
        }

        return (E > (0.0001f * float(nSuperPixels)));
    }
Пример #2
0
void smoothingLineCGM(surface_mesh *pm, int *vert, double *pT, double *pU, double *pV, int iSurf, int iV_U, int n, CGMedge edge) {
    int i, j=0, jj;
    double t, tp, tn, tu, tv, sp, sn;
    double x, y, z, x0, y0, z0, x1, y1, z1, x2, y2, z2;
    double du, k=0.0, k0, k1, fi0_, fi1_, f1, p;
    int v, vp, vn;
    double xyz[3];

    while (j < 5) {
	for (i=n-2; i>0; i--) {
	    v  = vert[i];
	    vp = vert[i-1];  tp = pT[i-1];
	    vn = vert[i+1];  tn = pT[i+1];
	    if (tp > tn) {
		t  = tp;
		tp = tn;
		tn = t;
	    }
	    x1 = pm->vert[vp].x;
	    y1 = pm->vert[vp].y;
	    z1 = pm->vert[vp].z;
	    x2 = pm->vert[vn].x;
	    y2 = pm->vert[vn].y;
	    z2 = pm->vert[vn].z;

	    sp = sizeFace(pm, 0.5*(pm->vert[v].x+x1), 0.5*(pm->vert[v].y+y1), 0.5*(pm->vert[v].z+z1));
	    sn = sizeFace(pm, 0.5*(pm->vert[v].x+x2), 0.5*(pm->vert[v].y+y2), 0.5*(pm->vert[v].z+z2));

	    /* find  point  on  surface */
	    t = pT[i];
	    if (iSurf>=0) {
		bounLine(pm, iV_U, t, &tu, &tv);
		bounSurf(pm, iSurf, tu, tv, &x, &y, &z);
	    } else {
		CGM_GetEdgeCoordsFromU(edge, t, xyz);
		x = xyz[0]; y = xyz[1]; z = xyz[2];
	    }
	    f1 = (sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z))*
		(sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z));
	    for (jj=0; jj<222; jj++) { /* NEW METH */
		if (f1 < 0.01) break;
		du = 0.2; /*???*/
		do {
		    du /= 2.0;
		    if (iSurf>=0) {
			bounLine(pm, iV_U, t+du, &tu, &tv);
			bounSurf(pm, iSurf, tu, tv, &x0, &y0, &z0);
		    } else {
			CGM_GetEdgeCoordsFromU(edge, t+du, xyz);
			x0 = xyz[0]; y0 = xyz[1]; z0 = xyz[2];
		    }
		    p = distanceS(x, y, z, x0, y0, z0);
		} while (p > 0.1*sp*sn);

		k0 = -0.9;
		k1 = 1.0;
		if (du == 0.0)
		    errorExit3(3, "du == 0.0 ");
		if (t + k0*du < tp)
		    k0 = (tp-t)/du;
		if (t + k1*du > tn)
		    k1 = (tn-t)/du;
		while (k1 - k0 > 0.00001) {/*min of funk*/

		    k = 0.5*(k0+k1);
		    if (iSurf>=0) {
			bounLine(pm, iV_U, t+k*du, &tu, &tv);
			bounSurf(pm, iSurf, tu, tv, &x, &y, &z);
		    } else {
			CGM_GetEdgeCoordsFromU(edge, t+k*du, xyz);
			x = xyz[0]; y = xyz[1]; z = xyz[2];
		    }
		    fi0_ = (sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z))*
			(sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z));
		    if (iSurf>=0) {
			bounLine(pm, iV_U, t+(k+fabs(k)*0.01)*du, &tu, &tv);
			bounSurf(pm, iSurf, tu, tv, &x, &y, &z);
		    } else {
			CGM_GetEdgeCoordsFromU(edge, t+(k+fabs(k)*0.01)*du, xyz);
			x = xyz[0]; y = xyz[1]; z = xyz[2];
		    }
		    fi1_ = (sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z))*
			(sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z));
		    if (fi1_ - fi0_ > 0.)
			k1 = k;
		    else
			k0 = k;
		}
		t += k*du;
		if (iSurf>=0) {
		    bounLine(pm, iV_U, t, &tu, &tv);
		    bounSurf(pm, iSurf, tu, tv, &x, &y, &z);
		} else {
		    CGM_GetEdgeCoordsFromU(edge, t, xyz);
		    x = xyz[0]; y = xyz[1]; z = xyz[2];
		}
		f1 = (sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z))*
		    (sp/sn - distance(x1, y1, z1, x, y, z)/distance(x2, y2, z2, x, y, z));
	    } /*NEW METH*/
	    if (iSurf>=0) {
		bounLine(pm, iV_U, t, &tu, &tv);
		bounSurf(pm, iSurf, tu, tv, &x, &y, &z);
		pU[i] = tu,  pV[i] = tv;
	    } else {
		CGM_GetEdgeCoordsFromU(edge, t, xyz);
		x = xyz[0]; y = xyz[1]; z = xyz[2];
	    }
	    pT[i] = t;
	    pm->vert[v].x = x;
	    pm->vert[v].y = y;
	    pm->vert[v].z = z;
	}
	j++;
    }
    return;
}