00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <flgrCoreMalloc.h>
00024 #include <flgrCoreData.h>
00025 #include <flgrCoreVector.h>
00026 #include <flgrCoreIO.h>
00027 #include <flgrCoreDataIO.h>
00028 #include <flgrCoreSlideWindow.h>
00029 #include <flgrCoreNhbManage.h>
00030 #include <flgrCoreCopy.h>
00031 #include <flgrCoreReplace.h>
00032 #include <flgrCoreDispatch.h>
00033 #include <flgrDataToolsPStack.h>
00034 
00035 #include "flgrMorphoBase.h"
00036 #include "flgrMorphoWatershed.h"
00037 #include "flgrMorphoWatershedSPP1.h"
00038 
00043 #define FLGR_MACRO_COMPARE_PR_LBL(dtype)                \
00044   dtype *p1 = (dtype*) priorityLabel1->array;               \
00045   dtype *p2 = (dtype*) priorityLabel2->array;               \
00046   dtype a1,a2;                              \
00047   int ret;                              \
00048                                     \
00049   a1 = flgr_get_array_##dtype(p1,0);                    \
00050   a2 = flgr_get_array_##dtype(p2,0);                    \
00051                                     \
00052   ret = (a1>a2) ? FLGR_TRUE : FLGR_FALSE;               \
00053   return ret
00054 
00055 
00056 int comparePrLbl_fgUINT8(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00057   FLGR_MACRO_COMPARE_PR_LBL(fgUINT8);
00058 }
00059 int comparePrLbl_fgUINT16(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00060   FLGR_MACRO_COMPARE_PR_LBL(fgUINT16);
00061 }
00062 int comparePrLbl_fgUINT32(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00063   FLGR_MACRO_COMPARE_PR_LBL(fgUINT32);
00064 }
00065 int comparePrLbl_fgINT8(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00066   FLGR_MACRO_COMPARE_PR_LBL(fgINT8);
00067 }
00068 int comparePrLbl_fgINT16(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00069   FLGR_MACRO_COMPARE_PR_LBL(fgINT16);
00070 }
00071 int comparePrLbl_fgINT32(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00072   FLGR_MACRO_COMPARE_PR_LBL(fgINT32);
00073 }
00074 int comparePrLbl_fgFLOAT32(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00075   FLGR_MACRO_COMPARE_PR_LBL(fgINT32);
00076 }
00077 int comparePrLbl_fgFLOAT64(FLGR_Vector *priorityLabel1, FLGR_Vector *priorityLabel2) {
00078   FLGR_MACRO_COMPARE_PR_LBL(fgINT32);
00079 }
00080 
00081 
00082 
00084 
00086 #define WATERSHED_DYNAMIC_STACK(dtype,dtypename,comparefct)     \
00087   FLGR_Vector *vec;                         \
00088   FLGR_Data2D *nhbOdd,*nhbEven;                     \
00089   FLGR_Data2D *nhb;                         \
00090   FLGR_NhbBox2D *cont;                          \
00091   FLGR_PStack *pstack;                          \
00092   FLGR_McStack *stack;                          \
00093   int *cont_list_x;                         \
00094   int *cont_list_y;                         \
00095   dtype *label_ptr;                         \
00096   dtype *src_ptr;                           \
00097   dtype *cont_ptr;                          \
00098   dtype newcolor;                           \
00099   dtype color;                              \
00100   dtype cont_centerval;                         \
00101   int i,j,w2,h2;                            \
00102   int row, col;                             \
00103   int m,n;                              \
00104                                     \
00105                         \
00106                                     \
00107   vec = flgr_vector_create(imsrc->spp,imsrc->type);         \
00108   pstack = flgr_pstack_create(dtypename,comparefct);            \
00109                                     \
00110               \
00111               \
00112               \
00113   for(i=0 ; i<imlabel->size_y ; i++) {                  \
00114     label_ptr = (dtype*) imlabel->array[i];             \
00115     for(j=0 ; j<imlabel->size_x ; j++) {                \
00116       if(label_ptr[j]>0) {                      \
00117     flgr2d_get_data_vector_##dtype(imsrc,i,j,vec);          \
00118     flgr_pstack_push_##dtype(pstack,vec, i, j );            \
00119       }                                 \
00120     }                                   \
00121   }                                 \
00122                                     \
00123                           \
00124                           \
00125                           \
00126   nhb = flgr2d_create_neighborhood_from_connexity(imsrc->spp,       \
00127                           dtypename,connexity); \
00128   nhbOdd = flgr2d_create_neighborhood_from(nhb);            \
00129   nhbEven = flgr2d_create_neighborhood_from(nhb);           \
00130                                     \
00131   flgr2d_fill_nhbs_for_6_connexity(nhbEven,nhbOdd,nhb,FLGR_NHB_NO_SYM); \
00132                                     \
00133   flgr2d_destroy(nhb);                          \
00134                                     \
00135   cont = flgr2d_create_neighbor_box(nhbOdd);                \
00136   w2 = cont->nhb_size_x/2;                      \
00137   h2 = cont->nhb_size_y/2;                      \
00138                                     \
00139   cont_list_x = cont->list_coord_x[0];                  \
00140   cont_list_y = cont->list_coord_y[0];                  \
00141                                     \
00142   stack = flgr_pstack_get_first_no_empty_stack(pstack);         \
00143   i=0;                                  \
00144   while( i < pstack->nbPriority) {                  \
00145                                     \
00146     color = *((dtype *) stack->priorityLabel->array);           \
00147                                     \
00148     while(stack->size>0) {                      \
00149       flgr_pstack_pop_stack(stack, &row, &col);             \
00150                                     \
00151       nhb = (((row%2)==1) ? nhbOdd : nhbEven);              \
00152                                     \
00153       flgr2d_get_neighborhood(cont,imlabel,nhb,row,col);        \
00154                                     \
00155       cont_ptr = (dtype*) cont->list_data_val[0];           \
00156       cont_centerval = *((dtype*) cont->center_data_val->array);    \
00157                                     \
00158       for(j=0 ; j<cont->size[0] ; j++) {                \
00159     m=row+cont_list_y[j]-h2;                    \
00160     n=col+cont_list_x[j]-w2;                    \
00161     if(cont_ptr[j]==0) {                        \
00162       label_ptr = imlabel->array[m];                \
00163       label_ptr[n] = cont_centerval;                \
00164                                     \
00165       src_ptr = imsrc->array[m];                    \
00166       newcolor = src_ptr[n];                    \
00167                                     \
00168       if(newcolor<color) {                      \
00169         if(stack->next==NULL) {                 \
00170           newcolor = color;                     \
00171         } else {                            \
00172           newcolor = *((dtype *) stack->next->priorityLabel->array); \
00173         }                               \
00174       }     \
00175       flgr_vector_populate_from_scalar_##dtype(vec,newcolor);   \
00176       flgr_pstack_push_##dtype(pstack,vec,m,n);         \
00177                                     \
00178     }               \
00179       }                       \
00180                                     \
00181     }               \
00182     stack = stack->next;                        \
00183     i=i+1;                              \
00184   }                \
00185                                     \
00186   flgr_pstack_destroy(pstack);                      \
00187   flgr_vector_destroy(vec);                     \
00188   return
00189 
00190 void flgr2d_watershed_fgBIT(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00191   flgr_no_define_type_function(FLGR_BIT);
00192 }
00193 
00194 void flgr2d_watershed_fgUINT8(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00195   if(imsrc->spp==1) {
00196     flgr2d_watershed_spp1_fgUINT8(imlabel, imsrc, connexity);
00197   }else {
00198     WATERSHED_DYNAMIC_STACK(fgUINT8, FLGR_UINT8, comparePrLbl_fgUINT8);
00199   }
00200 }
00201 
00202 void flgr2d_watershed_fgUINT16(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00203   if(imsrc->spp==1) {
00204     flgr2d_watershed_spp1_fgUINT16(imlabel, imsrc, connexity);
00205   }else {
00206     WATERSHED_DYNAMIC_STACK(fgUINT16, FLGR_UINT16, comparePrLbl_fgUINT16);
00207   }
00208 }
00209 
00210 void flgr2d_watershed_fgUINT32(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00211   WATERSHED_DYNAMIC_STACK(fgUINT32,FLGR_UINT32, comparePrLbl_fgUINT32);
00212 }
00213 
00214 void flgr2d_watershed_fgINT8(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00215   WATERSHED_DYNAMIC_STACK(fgINT8,FLGR_INT8, comparePrLbl_fgINT8);
00216 }
00217 
00218 void flgr2d_watershed_fgINT16(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00219   WATERSHED_DYNAMIC_STACK(fgINT16,FLGR_INT16, comparePrLbl_fgINT16);
00220 }
00221 
00222 void flgr2d_watershed_fgINT32(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00223   WATERSHED_DYNAMIC_STACK(fgINT32,FLGR_INT32, comparePrLbl_fgINT32);
00224 }
00225 
00226 void flgr2d_watershed_fgFLOAT32(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00227   WATERSHED_DYNAMIC_STACK(fgFLOAT32,FLGR_FLOAT32, comparePrLbl_fgFLOAT32);
00228 }
00229 
00230 void flgr2d_watershed_fgFLOAT64(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00231   WATERSHED_DYNAMIC_STACK(fgFLOAT64,FLGR_FLOAT64, comparePrLbl_fgFLOAT64);
00232 }
00233 
00235 
00241 
00242 FLGR_Ret flgr2d_watershed(FLGR_Data2D *imlabel, FLGR_Data2D *imsrc, FLGR_Connexity connexity) {
00243   FLGR_Ret ret;
00244 
00245   
00246 
00247   if((imlabel==NULL) || (imsrc==NULL)){
00248     POST_ERROR("Null objects!\n");
00249     return FLGR_RET_NULL_OBJECT;
00250   }
00251 
00252   if(imlabel->spp!=1)  {
00253     POST_ERROR("Multi Sample Per Pixel not supported\n");
00254     return FLGR_RET_UNDEFINED_ERROR;
00255   }
00256 
00257   if((ret=flgr2d_is_data_same_attributes(imlabel,imsrc,__FUNCTION__))!=FLGR_RET_OK) return ret;
00258 
00259   FLGR_DISPATCH_PROCEDURE(imlabel->type,flgr2d_watershed,imlabel,imsrc,connexity);
00260 
00261 }
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 #define FLGR_MACRO_WSHED_BUILD_LINE(dtype)          \
00272   FLGR_Data2D *nhb;                     \
00273                     \
00274   nhb = flgr2d_create_neighborhood_from_connexity(imdest->spp,  \
00275                           imdest->type, \
00276                           connexity);   \
00277   flgr2d_gradient_outer(imdest,imlabel,nhb);            \
00278   flgr2d_replace_I_with_S_S_S(imdest,imdest,"!=","0","1","0");  \
00279   flgr2d_destroy(nhb)
00280 
00281 
00282 
00283 
00284 void flgr2d_watershed_build_line_fgBIT(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00285   flgr_no_define_type_function(FLGR_BIT);
00286 }
00287 void flgr2d_watershed_build_line_fgUINT8(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00288   FLGR_MACRO_WSHED_BUILD_LINE(fgUINT8);
00289 }
00290 void flgr2d_watershed_build_line_fgUINT16(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00291   FLGR_MACRO_WSHED_BUILD_LINE(fgUINT16);
00292 }
00293 void flgr2d_watershed_build_line_fgUINT32(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00294   FLGR_MACRO_WSHED_BUILD_LINE(fgUINT32);
00295 }
00296 void flgr2d_watershed_build_line_fgINT8(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00297   FLGR_MACRO_WSHED_BUILD_LINE(fgINT8);
00298 }
00299 void flgr2d_watershed_build_line_fgINT16(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00300   FLGR_MACRO_WSHED_BUILD_LINE(fgINT16);
00301 }
00302 void flgr2d_watershed_build_line_fgINT32(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00303   FLGR_MACRO_WSHED_BUILD_LINE(fgINT32);
00304 }
00305 void flgr2d_watershed_build_line_fgFLOAT32(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00306   FLGR_MACRO_WSHED_BUILD_LINE(fgFLOAT32);
00307 }
00308 void flgr2d_watershed_build_line_fgFLOAT64(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00309   FLGR_MACRO_WSHED_BUILD_LINE(fgFLOAT64);
00310 }
00311 
00313 
00319 
00320 FLGR_Ret flgr2d_watershed_build_line(FLGR_Data2D *imdest, FLGR_Data2D *imlabel, FLGR_Connexity connexity) {
00321   FLGR_Ret ret;
00322 
00323   
00324 
00325   if((imdest==NULL) || (imlabel==NULL)) {
00326     POST_ERROR("Null object\n");
00327     return FLGR_RET_NULL_OBJECT;
00328   }
00329 
00330   if((ret=flgr2d_is_data_same_attributes(imlabel,imdest,__FUNCTION__))!=FLGR_RET_OK) return ret;
00331 
00332   FLGR_DISPATCH_PROCEDURE(imlabel->type,flgr2d_watershed_build_line,imdest,imlabel,connexity);
00333 
00334 
00335 
00336 }
00337 
00338