/*********************************************************************** * Fulguro Four threads for four watersheds ***********************************************************************/ #include <flgrCoreTypes.h> #include <flgrCoreErrors.h> #include <flgrCoreData.h> #include <flgrCoreIO.h> #include <flgrCoreCompare.h> #include <flgrCoreReplace.h> #include <flgrCoreThreads.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,...) \ { \ time_t before_t, after_t; \ clock_t before_c, after_c; \ int i; \ \ before_t = time(NULL); \ before_c = clock(); \ \ for(i=0;i<nbtime;i++) { \ function(__VA_ARGS__); \ } \ \ after_t = time(NULL); \ after_c = clock(); \ \ printf(textinfo " System time : %d us, CPU time : %d us \n", \ (int) (((after_t-before_t)*1000000)/nbtime), \ (int) ((after_c-before_c)/(CLOCKS_PER_SEC/1000000)/nbtime)); \ } int thread_watershed(void *param) { FLGR_ThreadsArg *arg = (FLGR_ThreadsArg *) param; FLGR_Data2D *label = (FLGR_Data2D *) arg->argv[0]; FLGR_Data2D *src = (FLGR_Data2D *) arg->argv[1]; FLGR_Type *type = (FLGR_Type*) arg->argv[2]; flgr2d_watershed(label, src, *type); return 0; } void flgr2d_threaded_4_watershed(FLGR_Data2D *imLabel1, FLGR_Data2D *imin1, FLGR_Connexity *type1, FLGR_Data2D *imLabel2, FLGR_Data2D *imin2, FLGR_Connexity *type2, FLGR_Data2D *imLabel3, FLGR_Data2D *imin3, FLGR_Connexity *type3, FLGR_Data2D *imLabel4, FLGR_Data2D *imin4, FLGR_Connexity *type4) { FLGR_ThreadsArgList *arglist = flgr_threads_create_argument_list(4); flgr_threads_set_argument(arglist, 0, 3, imLabel1, imin1, type1); flgr_threads_set_argument(arglist, 1, 3, imLabel2, imin2, type2); flgr_threads_set_argument(arglist, 2, 3, imLabel2, imin2, type2); flgr_threads_set_argument(arglist, 3, 3, imLabel2, imin2, type2); flgr_threads_start(arglist, 4, 1, thread_watershed); flgr_threads_destroy_argument_list(arglist); } int main(void) { FLGR_Data2D *imin,*imtmp,*imFilter,*imDistance,*imMarker,*imMaxima,*imWatershed; FLGR_Data2D *imLabel,*imLabel2,*imLabel3,*imLabel4; 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); imLabel2 = flgr2d_create_from(imin); imLabel3 = flgr2d_create_from(imin); imLabel4 = 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(100000,"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); flgr2d_label(imLabel2, imMaxima, nhb1->connexity); // Watershed BENCH_FUCTION(1000,"Watershed",flgr2d_watershed,imLabel, imin, nhb1->connexity); BENCH_FUCTION(1000,"4 Threads 4 Watersheds", flgr2d_threaded_4_watershed, imLabel, imin, &(nhb1->connexity), imLabel2, imin, &(nhb1->connexity), imLabel3, imin, &(nhb1->connexity), imLabel4, imin, &(nhb1->connexity)); flgr2d_watershed_build_line(imWatershed, imLabel, nhb1->connexity); flgr2d_replace_I_with_S_S_I(imWatershed,imWatershed,"==","1","255",imin); 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(imLabel2); flgr2d_destroy(imLabel3); flgr2d_destroy(imLabel4); 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; }