Original Beans Image
Alternate Filter Size 3x3
Distance Function
Marker for watershed segmentation
Labelized image thanks to watershed alogirthm
Watershed line
/*********************************************************************** * Fulguro Example 4 : Beans count ***********************************************************************/ #include <flgrCoreTypes.h> #include <flgrCoreErrors.h> #include <flgrCoreData.h> #include <flgrCoreIO.h> #include <flgrCoreCompare.h> #include <flgrCoreReplace.h> #include <flgrImageIO.h> #include <flgrMeasureBase.h> #include <flgrMorphoBase.h> #include <flgrMorphoWatershed.h> #include <flgrMorphoGeodesy.h> #include <flgrMorphoLabel.h> #include <flgrMorphoDistance.h> #include <time.h> #define BENCH_FUCTION(nbtime,textinfo,function,...) \ { \ clock_t before, after; \ int i; \ before=clock(); \ for(i=0;i<nbtime;i++) { \ function(__VA_ARGS__); \ } \ after=clock(); \ printf(textinfo " time : %d us \n", \ (int) ((after - before)/(CLOCKS_PER_SEC/1000000)/nbtime)); \ } int main(void) { FLGR_Data2D *imin,*imtmp,*imFilter,*imDistance,*imMarker,*imMaxima,*imLabel,*imWatershed; FLGR_Data2D *nhb1,*nhb2,*nhb3,*nhb4,*nhb5; FLGR_Vector *vec_min, *vec_max; FLGR_Vector *vec_hmin; imin = flgr2d_load_pgm("../../images/gray/beans.pgm"); imtmp = flgr2d_create_from(imin); imFilter = flgr2d_create_from(imin); imDistance = flgr2d_create_from(imin); imMarker = flgr2d_create_from(imin); imMaxima = flgr2d_create_from(imin); imLabel = flgr2d_create_from(imin); imWatershed = flgr2d_create_from(imin); vec_min = flgr_vector_create(imin->spp,imin->type); vec_max = flgr_vector_create(imin->spp,imin->type); vec_hmin = flgr_vector_create(imin->spp,imin->type); flgr_vector_populate_from_string(vec_hmin,"1"); nhb1 = flgr2d_create_neighborhood(3,3,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX); nhb2 = flgr2d_create_neighborhood(5,5,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX); nhb3 = flgr2d_create_neighborhood(7,7,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX); nhb4 = flgr2d_create_neighborhood(9,9,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX); nhb5 = flgr2d_create_neighborhood(11,11,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX); flgr2d_replace_I_with_S_S_I(imin,imin,"==","255","254",imin); //Filter BENCH_FUCTION(1000,"Open Filter",flgr2d_open,imtmp,imin,nhb1); flgr2d_close(imFilter,imtmp,nhb1); // Distance flgr2d_replace_I_with_S_S_S(imtmp,imFilter,"<","128","255","0"); flgr2d_distance(imDistance,imtmp,nhb1->connexity); // Distance Maxima flgr2d_regional_hmaxima(imMaxima,imDistance,vec_hmin,nhb1->connexity); flgr2d_replace_I_with_S_S_S(imtmp,imMaxima,">","0","255","0"); flgr2d_dilate(imMaxima,imtmp,nhb5); // Labelize Maxima flgr2d_label(imLabel, imMaxima, nhb1->connexity); // Watershed BENCH_FUCTION(1,"Watershed",flgr2d_watershed,imLabel, imin, nhb1->connexity); flgr2d_watershed_build_line(imWatershed, imLabel, nhb1->connexity); flgr2d_replace_I_with_S_S_I(imWatershed,imWatershed,"==","1","255",imin); flgr2d_measure_min_max(imLabel,vec_min,vec_max); printf("Coffee Beans number : %d\n", flgr_get_array_fgUINT8(vec_max->array,0)); flgr2d_save_pgm(imFilter,"filter.pgm",5); flgr2d_save_pgm(imDistance,"distance.pgm",5); flgr2d_save_pgm(imMaxima,"maxima.pgm",5); flgr2d_save_pgm(imLabel,"label.pgm",5); flgr2d_save_pgm(imWatershed,"watershed.pgm",5); flgr2d_destroy(imin); flgr2d_destroy(imtmp); flgr2d_destroy(imFilter); flgr2d_destroy(imDistance); flgr2d_destroy(imMarker); flgr2d_destroy(imMaxima); flgr2d_destroy(imLabel); flgr2d_destroy(imWatershed); flgr2d_destroy(nhb1); flgr2d_destroy(nhb2); flgr2d_destroy(nhb3); flgr2d_destroy(nhb4); flgr2d_destroy(nhb5); flgr_vector_destroy(vec_max); flgr_vector_destroy(vec_min); flgr_vector_destroy(vec_hmin); return 0; }