Image *WaterGray(Image *img, Image *marker, AdjRel *A) { Image *cost=NULL,*label=NULL, *pred=NULL; GQueue *Q=NULL; int i,p,q,tmp,n,lambda=1; Pixel u,v; n = img->ncols*img->nrows; cost = CreateImage(img->ncols,img->nrows); label = CreateImage(img->ncols,img->nrows); pred = CreateImage(img->ncols,img->nrows); Q = CreateGQueue(MaximumValue(marker)+2,n,cost->val); // Trivial path initialization for (p=0; p < n; p++) { cost->val[p]=marker->val[p]+1; pred->val[p]=NIL; InsertGQueue(&Q,p); } // Path propagation while(!EmptyGQueue(Q)) { p=RemoveGQueue(Q); if (pred->val[p]==NIL) { // on-the-fly root detection cost->val[p] =img->val[p]; label->val[p]=lambda; lambda++; } u.x = p%img->ncols; u.y = p/img->ncols; for (i=1; i < A->n; i++){ v.x = u.x + A->dx[i]; v.y = u.y + A->dy[i]; if (ValidPixel(img,v.x,v.y)){ q = v.x + img->tbrow[v.y]; if (cost->val[q] > cost->val[p]){ tmp = MAX(cost->val[p],img->val[q]); if (tmp < cost->val[q]){ RemoveGQueueElem(Q,q); pred->val[q] = p; label->val[q] = label->val[p]; cost->val[q] = tmp; InsertGQueue(&Q,q); } } } } } DestroyGQueue(&Q); DestroyImage(&cost); DestroyImage(&pred); return(label); }
CImage *ColorizeImage(Image *img, float R, float G, float B) { CImage *cimg=CreateCImage(img->ncols,img->nrows); float Cb,Cr,Y; int Imax,p,n=img->ncols*img->nrows; Imax = MAX(MaximumValue(img),1); Cb = -0.148*R-0.291*G+0.439*B+128.0/255.; Cr = 0.439*R-0.368*G-0.071*B+128.0/255.; for (p=0; p < n; p++) { Y = ((float)img->val[p]/Imax); R=296.82*(Y-0.062745098039)+ 406.98*(Cr-0.50196078431); G=296.82*(Y-0.062745098039)- 207.315*(Cr-0.50196078431)- 99.96*(Cb-0.50196078431); B=296.82*(Y-0.062745098039)+ 514.335*(Cb-0.50196078431); if (R<0.0) R=0.0; if (G<0.0) G=0.0; if (B<0.0) B=0.0; if (R>255.0) R=255.0; if (G>255.0) G=255.0; if (B>255.0) B=255.0; cimg->C[0]->val[p]=(int)(R); cimg->C[1]->val[p]=(int)(G); cimg->C[2]->val[p]=(int)(B); } return(cimg); }
void DiffWatershed(Image *grad, ImageForest *fst, Set *Obj, Set *Bkg, Set *Rm) { AdjRel *A=NULL; GQueue *Q=NULL; Pixel u,v; int i,p,q,n,tmp,Cmax=MaximumValue(grad); Set *aux, *Frontier=NULL; Image *cost=fst->cost,*pred=fst->pred,*label=fst->label,*root=fst->root; n = grad->ncols*grad->nrows; Q = CreateGQueue(Cmax+1,n,cost->val); A = Circular(1.5); if (Rm != NULL) { // Treat removed trees Frontier = ForestRemoval(fst,Rm,A); while (Frontier != NULL) { p = RemoveSet(&Frontier); InsertGQueue(&Q,p); } } /* Trivial path initialization for new seeds */ aux = Obj; while(aux != NULL){ p=aux->elem; if (Q->L.elem[p].color == GRAY) { /* p is also a frontier pixel, but the priority is it as a seed. */ RemoveGQueueElem(Q,p); } label->val[p]=1; cost->val[p]=0; root->val[p]=p; pred->val[p]=NIL; InsertGQueue(&Q,p); aux = aux->next; } aux = Bkg; while(aux != NULL){ p=aux->elem; if (Q->L.elem[p].color == GRAY) { /* p is also a frontier pixel, but the priority is it as a seed. */ RemoveGQueueElem(Q,p); } label->val[p]=0; cost->val[p]=0; root->val[p]=p; pred->val[p]=NIL; InsertGQueue(&Q,p); aux = aux->next; } /* Path propagation */ while (!EmptyGQueue(Q)){ p = RemoveGQueue(Q); u.x = p%grad->ncols; u.y = p/grad->ncols; for (i=1; i < A->n; i++) { v.x = u.x + A->dx[i]; v.y = u.y + A->dy[i]; if (ValidPixel(grad,v.x,v.y)){ q = v.x + grad->tbrow[v.y]; if (Q->L.elem[q].color != BLACK) { tmp = MAX(cost->val[p] , grad->val[q]); if ((tmp < cost->val[q])||(pred->val[q]==p)){ if (Q->L.elem[q].color == GRAY) { RemoveGQueueElem(Q,q); } cost->val[q] = tmp; label->val[q] = label->val[p]; root->val[q] = root->val[p]; pred->val[q] = p; InsertGQueue(&Q,q); } } } } } DestroyGQueue(&Q); DestroyAdjRel(&A); }