void DistanceTransformNonEuclid(vector<double>& D, const vector<unsigned char>& L, const vector<int>& leadingNbh, const vector<int>& trailingNbh, const vector<double>& leadingWgt, const vector<double>& trailingWgt, int ndim, const int* dims) { int i,j; int nvoxels=numberOfElements(ndim,dims); //construct a subscript representation of the neighborhood //for efficient boundary check vector<int> vcoordsL; for(i=0; i<leadingNbh.size(); ++i) { vector<int> vsub = Ind2SubCentered(leadingNbh[i],ndim,dims); vcoordsL.insert(vcoordsL.end(),vsub.begin(),vsub.end()); } vector<int> vcoordsT; for(i=0; i<leadingNbh.size(); ++i) { vector<int> vsub = Ind2SubCentered(trailingNbh[i],ndim,dims); vcoordsT.insert(vcoordsT.end(),vsub.begin(),vsub.end()); } //first pass - from upper left to lower right for(i=0; i<nvoxels; ++i) { double v1=GetData(D,i,(double)0); double minV=INFINITY; vector<int> vsub = Ind2Sub(i,ndim,dims); for(j=0; j<leadingNbh.size(); ++j) { if(NeighborCheck(vsub.begin(),vcoordsL.begin()+j*ndim,ndim,dims)) { int k=i+leadingNbh[j]; double v2=D[k]; //trust BoundaryCheck - no array boundary check here minV=Min(minV,v2+leadingWgt[j]); } } if(v1>minV) SetData(D,i,minV); } //second pass - from lower right to upper left for(i=nvoxels-1; i>=0; --i) { double v1=GetData(D,i,(double)0); double minV=INFINITY; vector<int> vsub = Ind2Sub(i,ndim,dims); for(j=0; j<trailingNbh.size(); ++j) { if(NeighborCheck(vsub.begin(),vcoordsT.begin()+j*ndim,ndim,dims)) { int k=i+trailingNbh[j]; double v2=D[k]; //trust BoundaryCheck - no array boundary check here minV=Min(minV,v2+trailingWgt[j]); } } if(v1>minV) SetData(D,i,minV); } }
bool NeighborCheck(int p, int offset, int ndim, const int* dims) { vector<int> vsub = Ind2Sub(p, ndim, dims); vector<int> voff = Ind2SubCentered(offset, ndim, dims); if(voff.size()>ndim) return false; //index overflow for(int i=0; i<ndim; ++i) { if(vsub[i]+voff[i]<0 || vsub[i]+voff[i]>=dims[i]) { return false; } } return true; }
void LocalMinimum(vector<unsigned char>& M, const vector<Item>& V, const vector<unsigned char>& L, const vector<int>& nbh, bool strict, int ndim, const int* dims) { int nvoxels = numberOfElements(ndim,dims); if(M.size()<nvoxels || V.size()<nvoxels || L.size()<nvoxels) { //mexPrintf("An input image does not contain enough data.\n"); return; } int i; //construct a subscript representation of the neighborhood //for efficient boundary check vector<int> vcoords; for(i=0; i<nbh.size(); ++i) { vector<int> vsub = Ind2SubCentered(nbh[i],ndim,dims); vcoords.insert(vcoords.end(),vsub.begin(),vsub.end()); } for(i=0; i<nvoxels; ++i) { unsigned char lb=L[i]; if(!lb) continue; //not inside ROI bool bLM=true; bool b0; Item origV=V[i]; vector<int> vsub = Ind2Sub(i,ndim,dims); for(int j=0; j<nbh.size(); ++j) { if(NeighborCheck(vsub.begin(),vcoords.begin()+j*ndim,ndim,dims)) { int k=i+nbh[j]; if(L[k]) { bool b; Item v2=V[k]; if(strict) {// strictly maximum if(v2<=origV) { bLM=false; break; } } else { if(v2<origV) { bLM=false; break; } } } } } if(bLM) { SetData(M,i,(unsigned char) 1); } else { SetData(M,i,(unsigned char) 0); } } }