/*-------------------------------------------------------------------*/ bool DPMatchingCircular(int *C, double &T, // output double *A, double thre, // input int M, int N, // A is MxN matrix int n_search) { double *A2 = new double[M*2*N]; bool bSucc = false; memcpy(A2,A,M*N*sizeof(double)); memcpy(A2+M*N,A,M*N*sizeof(double)); int *CC = new int[M]; double TT = 1000000; int id_best = 0; T = 100000; // try different start points bSucc = DPMatchingFixStartPoint(C, T, A2, thre, M, N); id_best = 0; int iS1, iS2; //n_search=0; for(iS1=1;iS1<n_search;++iS1) { bSucc = DPMatchingFixStartPoint(CC, TT, A2+iS1*M, thre, M, N); if(TT<T) { T = TT; id_best = iS1; memcpy(C,CC,M*sizeof(int)); } // another direction iS2 = N-iS1; bSucc = DPMatchingFixStartPoint(CC, TT, A2+iS2*M, thre, M, N); if(TT<T) { T = TT; id_best = iS2; memcpy(C,CC,M*sizeof(int)); }//*/ } // adjust indices for(int ii=0;ii<M;++ii) { if(C[ii]<N) { // not occluded C[ii] += id_best; if(C[ii]>=N) C[ii] -= N; } } delete []A2; delete []CC; return true; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Input data */ double *A = mxGetPr(prhs[0]); double thre = *(mxGetPr(prhs[1])); int M = mxGetM(prhs[0]); int N = mxGetN(prhs[0]); int n_start = 1; if(nrhs>2) n_start = ROUND(*(mxGetPr(prhs[2]))); int n_search = 1; if(nrhs>3) n_search = ROUND(*(mxGetPr(prhs[3]))); /* call algorithm */ D = new double[M*N]; // DP matrix, D[y,x] is the cost of contour 1 at x links = new int[M*N]; // matching to contour 2 at y int *C = new int[M]; double T = 100000000; bool bSucc = false; if(n_start==1 && n_search==1) bSucc = DPMatchingFixStartPoint(C, T, A, thre, M, N); else bSucc = DPMatchingMultiStart(C,T, A,thre,M,N,n_start,n_search); //bSucc = DPMatchingCircular(C, T, A, thre, M, N, n_search); /* Output data */ mxArray *pMxC = mxCreateDoubleMatrix(1,M,mxREAL); double *pC = mxGetPr(pMxC); for(int ii=0;ii<M;++ii) pC[ii] = (double)C[ii]+1; mxArray *pMxT = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(pMxT))= T; /* Return */ plhs[0] = pMxC; plhs[1] = pMxT; delete []C; delete []D; delete []links; }
void DPMatching( double *cvec, double *match_cost, double *A, double thre, int M, int N, int n_start, int n_search) { /* Input data */ /* call algorithm */ D = new double[M*N]; // DP matrix, D[y,x] is the cost of contour 1 at x links = new int[M*N]; // matching to contour 2 at y int *C = new int[M]; double T = 100000000; bool bSucc = false; if(n_start==1 && n_search==1) bSucc = DPMatchingFixStartPoint(C, T, A, thre, M, N); else bSucc = DPMatchingMultiStart(C,T, A,thre,M,N,n_start,n_search); //bSucc = DPMatchingCircular(C, T, A, thre, M, N, n_search); /* Output data */ for(int ii=0;ii<M;++ii) cvec[ii] = (double)C[ii]+1; *match_cost=T; /* Return */ delete []C; delete []D; delete []links; }
/*-------------------------------------------------------------------*/ bool DPMatchingMultiStart ( int *C, double &T_best, // output double *A, double thre, // input int M, int N, // A is MxN matrix int n_start, int n_search) { double *A2 = new double[M*2*N]; bool bSucc = false; memcpy(A2,A,M*N*sizeof(double)); memcpy(A2+M*N,A,M*N*sizeof(double)); int *CC = new int[M*N]; double TT; int id_best; id_best = -1; T_best = 4000*N; n_start = MIN(N,n_start); // try different start points int id_start, iS, iS1, iS2, dS; for(iS=0;iS<n_start;++iS) { id_start = ROUND(N*iS/(double)n_start); bSucc = DPMatchingFixStartPoint(CC+id_start*M, TT, A2+id_start*M, thre, M, N); if(TT<T_best) { T_best = TT; id_best = id_start; } for(dS=1;dS<n_search;++dS) { // forward iS1 = id_start+dS; if(iS1>N) iS1-=N; bSucc = DPMatchingFixStartPoint(CC+iS1*M, TT, A2+iS1*M, thre, M, N); if(TT<T_best) { T_best = TT; id_best = iS1; } // backward iS2 = id_start-dS; if(iS2<0) iS2+=N; bSucc = DPMatchingFixStartPoint(CC+iS2*M, TT, A2+iS2*M, thre, M, N); if(TT<T_best) { T_best = TT; id_best = iS2; } } } // adjust indices if(id_best<0) printf("\n\tId_best=%d !!!!!!!\n",id_best); memcpy(C,CC+id_best*M,M*sizeof(int)); for(int ii=0;ii<M;++ii) { if(C[ii]<N) { // not occluded C[ii] += id_best; if(C[ii]>=N) C[ii] -= N; } } delete []A2; delete []CC; return true; }