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