IplImage* COPENCV::ExtractPatch( IplImage* pImage, const std::vector<std::pair<T,T> > vBox, IplImage* pPatchIn ) { return ExtractPatch( pImage, static_cast<int>( vBox[0].first ), static_cast<int>( vBox[0].second ), static_cast<int>( vBox[2].first - vBox[0].first + 1 ), static_cast<int>( vBox[2].second - vBox[0].second + 1 ), pPatchIn ); }
// selectMiddlePoint: if true, select the middle point in the patch, // otherwise build the mean // neverLosePoints: if true, and if we cannot do the refinement, still use // the control point. void RefineKeypoints (ArrayList* msList, bool selectMiddlePoint, bool neverLosePoints) { DisplayImage* pic1 = NULL; DisplayImage* pic2 = NULL; char* pic1Name = NULL; char* pic2Name = NULL; /* Keep stats for the refineHandler delegate */ int totalRefines = 0; int doneRefines = 0; int i; for(i=0; i<ArrayList_Count(msList); i++) { MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); int j; for(j=0; j<ArrayList_Count(ms->matches); j++) { ArrayList_GetItem(ms->matches, j); totalRefines += 1; } } for(i=0; i<ArrayList_Count(msList); i++) { MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); WriteLine (" between \"%s\" and \"%s\"", ms->file1, ms->file2); if (pic1Name != ms->file1) { pic1Name = ms->file1; pic1 = DisplayImage_new (ms->file1); } if (pic2Name != ms->file2) { pic2Name = ms->file2; pic2 = DisplayImage_new (ms->file2); } /*WriteLine ("pair: %s, %s, %d keypoint matches", ms->file1, ms->file2, ArrayList_Count(ms->Matches));*/ ArrayList* refinedMatches = ArrayList_new0 (NULL); int j; for(j=0; j<ArrayList_Count(ms->matches); j++) { Match* m = (Match*) ArrayList_GetItem(ms->matches, j); int p1x = (int) (m->kp1->x + 0.5); int p1y = (int) (m->kp1->y + 0.5); int p1radius; DisplayImage* patch1 = ExtractPatch (pic1, p1x, p1y, m->kp1->scale, &p1radius); int p2x = (int) (m->kp2->x + 0.5); int p2y = (int) (m->kp2->y + 0.5); int p2radius; DisplayImage* patch2 = ExtractPatch (pic2, p2x, p2y, m->kp2->scale, &p2radius); /* Call the refine handler delegate in case there is one to * inform the callee of a single refining step (for progress * bar displays and such). */ doneRefines += 1; if (refineHandler != NULL) refineHandler (doneRefines, totalRefines); // Skip over keypoint matches we cannot refine as part of the // image lies outside. if (patch1 == NULL || patch2 == NULL) { if (neverLosePoints) ArrayList_AddItem(refinedMatches, m); DisplayImage_delete(patch1); DisplayImage_delete(patch2); continue; } // Otherwise, run the SIFT algorithm on both small patches. ArrayList* p1kp = ExtractKeypoints (patch1); ArrayList* p2kp = ExtractKeypoints (patch2); /*WriteLine ("p1kp = %d, p2kp = %d", ArrayList_Count(p1kp), ArrayList_Count(p2kp));*/ // Apply the matching, RANSAC enabled. MultiMatch* mm = MultiMatch_new0 (); mm->verbose = false; ArrayList* matches = NULL; matches = MultiMatch_TwoPatchMatch (mm, p1kp, patch1->width, patch1->height, p2kp, patch2->width, patch2->height, true); DisplayImage_delete(patch1); DisplayImage_delete(patch2); /* In case there are less than three keypoints in the * two patches, we ignore them all. */ if (0 /*was exception ???*/ ) { matches = NULL; } if (matches == NULL || ArrayList_Count(matches) != 1) { if (neverLosePoints) ArrayList_AddItem(refinedMatches, m); continue; } MatchSet* pSet = (MatchSet*) ArrayList_GetItem(matches, 0); // Now get the real new control point coordinates from the // patches. We have two options and assume all points are // equal quality-wise: // a) Select the one that is most in the middle // (selectMiddlePoint == true) // b) Build the mean of all the control point matches in the // patches (selectMiddlePoint == false). double kp1X = 0.0; double kp1Y = 0.0; double kp2X = 0.0; double kp2Y = 0.0; double kpMidDist = Double_PositiveInfinity; int k; for(k=0; k<ArrayList_Count(pSet->matches); k++) { Match* pM = (Match*) ArrayList_GetItem(pSet->matches, k); if (selectMiddlePoint) { double dist = sqrt ( pow (pM->kp1->x - p1radius, 2.0) + pow (pM->kp1->y - p1radius, 2.0)); if (dist < kpMidDist) { kpMidDist = dist; kp1X = pM->kp1->x; kp1Y = pM->kp1->y; kp2X = pM->kp2->x; kp2Y = pM->kp2->y; } } else { kp1X += pM->kp1->x; kp1Y += pM->kp1->y; kp2X += pM->kp2->x; kp2Y += pM->kp2->y; } /*WriteLine ("(%g, %g) matches (%g, %g)", pM->kp1->x, pM->kp1->y, pM->kp2->x, pM->kp2->y);*/ } if (selectMiddlePoint == false) { kp1X /= (double) ArrayList_Count(pSet->matches); kp1Y /= (double) ArrayList_Count(pSet->matches); kp2X /= (double) ArrayList_Count(pSet->matches); kp2Y /= (double) ArrayList_Count(pSet->matches); } kp1X += p1x - p1radius; kp1Y += p1y - p1radius; kp2X += p2x - p2radius; kp2Y += p2y - p2radius; Match* mn = Match_clone (m); // Adjust the original keypoints location to be the mean of // all the highly precise superresolution points. mn->kp1->x = kp1X; mn->kp1->y = kp1Y; mn->kp2->x = kp2X; mn->kp2->y = kp2Y; /*WriteLine ("MASTER POINT MATCH: (%g,%g) to (%g,%g)", kp1X, kp1Y, kp2X, kp2Y);*/ ArrayList_AddItem(refinedMatches, mn); /* DisplayImage_Save (patch1, "patch-1.jpg"); DisplayImage_Save (patch2, "patch-2.jpg"); exit (0); */ } ms->matches = refinedMatches; } }
float nlmsegFuzzy4D(float *subject, float *imagedata, float *maskdata, float *meandata, float *vardata, float *mask, int sizepatch, int searcharea, float beta, float threshold, int dims[3], int librarysize, float *SegSubject, float *PatchCount) { float *MeansSubj, *VarsSubj, *PatchImg, *PatchTemp, *localmask; float w,average,totalweight, d, Mean, TMean, Var, TVar,th,proba, min, max; int i,j,k,ii,jj,kk,ni,nj,nk,v,f,ndim; data_t storage, *tab; int sadims,volumesize,index; int count; int realcount; int p; //int lim; /*Number of the closest patches taken into account*/ int t,mincount=MINCOUNT; int notfinished=1; double minidist; double epsi = 0.0001; time_t time1,time2; fprintf(stderr,"Patch size: %d\nSearch area: %d\nBeta: %f\nThreshold: %f\nSelection: %d\n",sizepatch,searcharea,beta,threshold,librarysize); ndim = 3; volumesize=dims[0]*dims[1]*dims[2]; /*Patch radius*/ f = sizepatch; /*Search Area radius*/ v = searcharea; sadims = pow(2*v+1,ndim); sadims = sadims * librarysize; tab=(data_t*)malloc(sadims*sizeof(*tab)); PatchImg=(float*) malloc((2*f+1)*(2*f+1)*(2*f+1)*sizeof(float)); PatchTemp=(float*) malloc((2*f+1)*(2*f+1)*(2*f+1)*sizeof(float)); /* allocate memory */ MeansSubj = (float *)calloc(volumesize,sizeof(*MeansSubj)); VarsSubj = (float *)calloc(volumesize,sizeof(*VarsSubj)); localmask = (float *)calloc(volumesize,sizeof(*localmask)); bcopy(mask,localmask,volumesize*sizeof(*localmask)); fprintf(stderr,"Dimensions: %d %d %d\n",dims[0],dims[1],dims[2]); fprintf(stderr,"Computing first moment image..."); time1=time(NULL); ComputeFirstMoment(subject, MeansSubj, dims, f, &min, &max); time2=time(NULL); fprintf(stderr,"done (%d sec)\nComputing second moment image...",(int)(time2-time1)); ComputeSecondMoment(subject, MeansSubj, VarsSubj, dims, f, &min, &max); fprintf(stderr,"done"); time1=time(NULL); if (1){ do { fprintf(stderr," (%d sec)\nSegmenting ",(int)(time1-time2)); time2=time(NULL); notfinished=0; for(i=0;i<dims[0];i++) { fprintf(stderr,"\b\b\b\b\b\b\b\b\b%3d / %3d",i+1,dims[0]); for(j=0;j<dims[1];j++) { for(k=0;k<dims[2];k++) { index=i*(dims[2]*dims[1])+(j*dims[2])+k; /* mask check */ if ( localmask[index] > 0 ) { proba=0.; average=0; totalweight=0; count = 0; realcount=0; minidist = 1000000000.0; ExtractPatch(subject, PatchTemp, i, j, k, f, dims[0], dims[1], dims[2]); TMean = MeansSubj[index]; TVar = VarsSubj[index]; /* go through the search space */ for(ii=-v;ii<=v;ii++) { for(jj=-v;jj<=v;jj++) { for(kk=-v;kk<=v;kk++) { ni=i+ii; nj=j+jj; nk=k+kk; if((ni>=0) && (nj>=0) && (nk>=0) && (ni<dims[0]) && (nj<dims[1]) && (nk<dims[2])) { for(t=0;t<librarysize;t++) { Mean = meandata[t*volumesize+ni*(dims[2]*dims[1])+(nj*dims[2])+nk]; Var = vardata[t*volumesize+ni*(dims[2]*dims[1])+(nj*dims[2])+nk]; /*Similar Luminance and contrast -> Cf Wang TIP 2004*/ th = ((2 * Mean * TMean + epsi) / ( Mean*Mean + TMean*TMean + epsi)) * ((2 * sqrt(Var) * sqrt(TVar) + epsi) / (Var + TVar + epsi)); if(th > threshold) { ExtractPatch4D(imagedata, PatchImg,ni,nj,nk,t,f,dims[0],dims[1],dims[2]); d = SSDPatch(PatchImg,PatchTemp,f); if (d < minidist) minidist = d; storage.dist = d; storage.z = ni; storage.y = nj; storage.x = nk; storage.t = t; tab[count] = storage; count ++; } } } } } } /* require a minimum number of selected patches */ if (count >= mincount) { /* Sort the distance*/ /*This can be removed according to the chosen strategy*/ /*qsort (tab, count, sizeof *tab, cmp);*/ p = 0; /*You can use the closest Patches (i.e. the 'lim' closest ones) or all the preselected patches (count)*/ //lim = count; /*in this case, you take all the preselected patches into account*/ if (minidist<=0) minidist = epsi; /*to avoid division by zero*/ while (p < count) { storage = tab[p]; w = exp(- ((storage.dist)/(beta*(minidist)) ) ); /*The smoothing parameter is the minimal distance*/ if (w>0) { average = average + maskdata[(storage.t*volumesize)+(storage.z*(dims[2]*dims[1]))+(storage.y*dims[2])+storage.x]*w; totalweight = totalweight + w; realcount++; } p++; } // while /* We compute the probability */ proba = average / totalweight; SegSubject[index] = proba; PatchCount[index] = realcount; } else { /* Not enough similar patches */ notfinished=1; SegSubject[index] = -1; } }// mask check } // for k } // for j } // for i time1=time(NULL); if (notfinished){ threshold=threshold*0.95; mincount=mincount*0.95; v=v+1; count=0; for(i=0;i<dims[0];i++) { for(j=0;j<dims[1];j++) { for(k=0;k<dims[2];k++) { index=i*(dims[2]*dims[1])+(j*dims[2])+k; if (SegSubject[index]<0){ localmask[index] = 1; count++; }else{ localmask[index] = 0; } } } } fprintf(stderr," (redoing %d voxels) t=%f, min=%d ",count,threshold,mincount); free(tab); sadims = pow(2*v+1,ndim); sadims = sadims * librarysize; tab=(data_t*)malloc(sadims*sizeof(*tab)); } }while (notfinished); } fprintf(stderr," done (%d sec, t=%f, min=%d)\n",(int)(time1-time2),threshold,mincount); free(tab); free(PatchImg); free(PatchTemp); free(MeansSubj); free(VarsSubj); free(localmask); return max; }