/* Recursive reconquest: tries to reconquest all adjacents. If it does, calls reconquest on them */ void reconquest_recursive(Subgraph *sg, int predecessor, int node, int* oldNodes){ // Tags the current node as 'old', i.e., already tried to reconquer it oldNodes[node] = 1; // Clones the list of adjacents Set* p = CloneSet(sg->node[node].incAdj); // Tries to reconquer the node (check if new pathval would be smaller than current pathval) float reconquerorPathval = opf_ArcWeight(sg->node[predecessor].feat, sg->node[node].feat, sg->nfeats) + sg->node[predecessor].pathval; if (sg->node[node].pathval >= reconquerorPathval){ // Destroy adjacents, will be refilled as reconquest advances DestroySet(&(sg->node[node].incAdj)); sg->node[node].incAdj = NULL; // Reconquer the node sg->node[node].pred = predecessor; sg->node[node].pathval = reconquerorPathval; InsertSet(&(sg->node[predecessor].incAdj),node); InsertSet(&(sg->node[node].incAdj),predecessor); // Tries to reconquer its neighbours while(p != NULL){ if (!oldNodes[p->elem]){ reconquest_recursive(sg, node, p->elem, oldNodes); } p = p->next; } DestroySet(&p); } }
/* Reconquest function begin reconquest with 'root' node as the new root */ void reconquest(Subgraph* sg, int root){ // Flag vector int* oldNodes = (int*)calloc(sg->nnodes, sizeof(int)); // Recursively calls the reconquest function for each adjacent node // Clones the list of adjacents Set* p = CloneSet(sg->node[root].incAdj); // Destroy adjacents, will be refilled as reconquest advances DestroySet(&(sg->node[root].incAdj)); sg->node[root].incAdj = NULL; // Goes through all former adjacent nodes while(p != NULL){ reconquest_recursive(sg, root, p->elem, oldNodes); p = p->next; } // Destroy the cloned set DestroySet(&p); // Frees the flag vector free(oldNodes); }
// Destroy Arcs void opf_DestroyArcs(Subgraph *sg){ int i; for (i=0; i < sg->nnodes; i++) { sg->node[i].nplatadj = 0; DestroySet(&(sg->node[i].adj)); } }
// Deallocate memory for subgraph void DestroySubgraph(Subgraph **sg){ int i; if ((*sg)!=NULL) { for (i=0; i < (*sg)->nnodes; i++) { if ((*sg)->node[i].feat != NULL) free((*sg)->node[i].feat); if ((*sg)->node[i].adj != NULL) DestroySet(&(*sg)->node[i].adj); } free((*sg)->node); free((*sg)->ordered_list_of_nodes); free((*sg)); *sg = NULL; } }
static void check_and_destroy(char *str, hash *h, set *S) { static char buf[4096]; char *k; int i = 0; buf[i] = 0; k = StartKeyLoopHash(h); while(k) { if (!InSetElement(S, k)) { strcat(&buf[i], k); i += strlen(k); strcat(&buf[i], ","); i++; } k = GetNextKeyHash(h); } if (strlen(buf)) { fprintf(stderr, "[W] %s: not empty hash (%s)\n", str, buf); } DestroyHash(&h); DestroySet(&S); }
Region *MakeRegions(Graph *g, Image *mask) { Region *r=NULL; int L, a, b, h, v, s; bool stop; Set *set; int p, q; int i, n; set = CreateSet(g->nnodes); n = g->nnodes; for (i=0;i<g->nnodes;i++) if (mask->val[i]) MakeSet(set, i); else n--; QuickSort(g->edges, g->nedges, sizeof(Edge), CompareEdge); stop = false; for (i=0;i<g->nedges && !stop;i++) { if (mask->val[g->edges[i].p] && mask->val[g->edges[i].q]) { p = FindSet(set,g->edges[i].p); q = FindSet(set,g->edges[i].q); if (p != q) { L = g->nodes[p].L / g->nodes[p].s - g->nodes[q].L / g->nodes[q].s; a = g->nodes[p].a / g->nodes[p].s - g->nodes[q].a / g->nodes[q].s; b = g->nodes[p].b / g->nodes[p].s - g->nodes[q].b / g->nodes[q].s; if (100 * (L * L + a * a + b * b) < MIN_DISTANCE * 195075) { L = g->nodes[p].L + g->nodes[q].L; a = g->nodes[p].a + g->nodes[q].a; b = g->nodes[p].b + g->nodes[q].b; h = g->nodes[p].h + g->nodes[q].h; v = g->nodes[p].v + g->nodes[q].v; s = g->nodes[p].s + g->nodes[q].s; Union(set,p,q); p = FindSet(set,q); g->nodes[p].L = L; g->nodes[p].a = a; g->nodes[p].b = b; g->nodes[p].h = h; g->nodes[p].v = v; g->nodes[p].s = s; n--; } else stop = true; } } } for (; i<g->nedges; i++) { if (mask->val[g->edges[i].p] && mask->val[g->edges[i].q]) { p = FindSet(set,g->edges[i].p); q = FindSet(set,g->edges[i].q); if (p != q) { if (100 * g->nodes[p].s < MIN_AREA * g->nnodes || 100 * g->nodes[q].s < MIN_AREA * g->nnodes) { L = g->nodes[p].L + g->nodes[q].L; a = g->nodes[p].a + g->nodes[q].a; b = g->nodes[p].b + g->nodes[q].b; h = g->nodes[p].h + g->nodes[q].h; v = g->nodes[p].v + g->nodes[q].v; s = g->nodes[p].s + g->nodes[q].s; Union(set,p,q); p = FindSet(set,q); g->nodes[p].L = L; g->nodes[p].a = a; g->nodes[p].b = b; g->nodes[p].h = h; g->nodes[p].v = v; g->nodes[p].s = s; n--; } } } } r = CreateRegion(n); i = 0; for (p=0; p<set->n; p++) if (mask->val[p] && p == FindSet(set,p)) r->nodes[i++] = g->nodes[p]; DestroySet(&set); return(r); }
int main(int argc, char **argv) { timer *t1=NULL,*t2=NULL; Image *img=NULL,*grad=NULL; ImageForest *fst=NULL; CImage *cimg=NULL; Set *Obj=NULL,*Bkg=NULL; char outfile[100]; char *file_noext; /*--------------------------------------------------------*/ void *trash = malloc(1); struct mallinfo info; int MemDinInicial, MemDinFinal; free(trash); info = mallinfo(); MemDinInicial = info.uordblks; /*--------------------------------------------------------*/ if (argc!=4){ fprintf(stderr,"Usage: diffwatershed <image.pgm> <gradient.pgm> <seeds.txt>\n"); fprintf(stderr,"image.pgm: image to overlay the watershed lines on it\n"); fprintf(stderr,"gradient.pgm: gradient image to compute the watershed segmentation\n"); fprintf(stderr,"seeds.txt: seed pixels\n"); exit(-1); } img = ReadImage(argv[1]); grad = ReadImage(argv[2]); ReadSeeds(argv[3],&Obj,&Bkg); fst = CreateImageForest(img); file_noext = strtok(argv[1],"."); // Add object and background seeds t1 = Tic(); DiffWatershed(grad,fst,Obj,Bkg,NULL); t2 = Toc(); fprintf(stdout,"Adding object and background seeds in %f ms\n",CTime(t1,t2)); cimg = DrawLabeledRegions(img,fst->label); sprintf(outfile,"%s_result-a.ppm",file_noext); WriteCImage(cimg,outfile); DestroyCImage(&cimg); // Remove background trees t1 = Tic(); DiffWatershed(grad,fst,NULL,NULL,Bkg); t2 = Toc(); fprintf(stdout,"Removing background trees in %f ms\n",CTime(t1,t2)); cimg = DrawLabeledRegions(img,fst->label); sprintf(outfile,"%s_result-b.ppm",file_noext); WriteCImage(cimg,outfile); DestroyCImage(&cimg); // Adding background trees back to the forest t1 = Tic(); DiffWatershed(grad,fst,NULL,Bkg,NULL); t2 = Toc(); fprintf(stdout,"Adding the removed background trees in %f ms\n",CTime(t1,t2)); cimg = DrawLabeledRegions(img,fst->label); sprintf(outfile,"%s_result-c.ppm",file_noext); WriteCImage(cimg,outfile); DestroyCImage(&cimg); DestroyImageForest(&fst); DestroyImage(&img); DestroyImage(&grad); DestroySet(&Obj); DestroySet(&Bkg); /* ---------------------------------------------------------- */ info = mallinfo(); MemDinFinal = info.uordblks; if (MemDinInicial!=MemDinFinal) printf("\n\nDinamic memory was not completely deallocated (%d, %d)\n", MemDinInicial,MemDinFinal); return(0); }