#include <flgrCoreTypes.h>
#include <flgrCoreErrors.h>
#include <flgrCoreData.h>
#include <flgrCoreCompare.h>
#include <flgrCoreVector.h>
#include <flgrArith.h>
#include <flgrImageIO.h>
#include <flgrMorphoBase.h>
#include <time.h>
#define BENCH_FUNCTION(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)); \
}
FLGR_Ret geodesic_rec_dilate(FLGR_Data2D *immarker, FLGR_Data2D *immask, FLGR_Data2D *nhbc) {
FLGR_Data2D *nhb,*imtmp1,*imtmp2;
FLGR_Ret ret;
nhb = flgr2d_create_neighborhood_from_connexity(immarker->spp,immarker->type, nhbc->connexity);
imtmp1 = flgr2d_create_pixmap(immarker->size_y,immarker->size_x,immarker->spp,immarker->type);
imtmp2 = flgr2d_create_pixmap(immarker->size_y,immarker->size_x,immarker->spp,immarker->type);
if((ret=flgr2d_copy(imtmp2,immarker))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_dilate(imtmp1,imtmp2,nhb))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_arith_inf(imtmp2,immask,imtmp1))!=FLGR_RET_OK) goto fail;
while(flgr2d_compare(immarker,"==",imtmp2)==0) {
if((ret=flgr2d_copy(immarker,imtmp2))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_dilate(imtmp1,imtmp2,nhb))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_arith_inf(imtmp2,immask,imtmp1))!=FLGR_RET_OK) goto fail;
}
fail:
flgr2d_destroy(nhb);
flgr2d_destroy(imtmp1);
flgr2d_destroy(imtmp2);
return ret;
}
FLGR_Ret geodesic_rec_erode(FLGR_Data2D *immarker, FLGR_Data2D *immask, FLGR_Data2D *nhbc) {
FLGR_Data2D *nhb,*imtmp1,*imtmp2;
FLGR_Ret ret;
nhb = flgr2d_create_neighborhood_from_connexity(immarker->spp,immarker->type, nhbc->connexity);
imtmp1 = flgr2d_create_pixmap(immarker->size_y,immarker->size_x,immarker->spp,immarker->type);
imtmp2 = flgr2d_create_pixmap(immarker->size_y,immarker->size_x,immarker->spp,immarker->type);
if((ret=flgr2d_copy(imtmp2,immarker))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_erode(imtmp1,imtmp2,nhb))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_arith_sup(imtmp2,immask,imtmp1))!=FLGR_RET_OK) goto fail;
while(flgr2d_compare(immarker,"==",imtmp2)==0) {
if((ret=flgr2d_copy(immarker,imtmp2))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_erode(imtmp1,imtmp2,nhb))!=FLGR_RET_OK) goto fail;
if((ret=flgr2d_arith_sup(imtmp2,immask,imtmp1))!=FLGR_RET_OK) goto fail;
}
fail:
flgr2d_destroy(nhb);
flgr2d_destroy(imtmp1);
flgr2d_destroy(imtmp2);
return ret;
}
FLGR_Ret geodesic_rec_open(FLGR_Data2D *imdest,FLGR_Data2D *imin,FLGR_Data2D *nhb) {
FLGR_Ret ret;
if((ret=flgr2d_erode(imdest,imin,nhb))!=FLGR_RET_OK) return ret;
ret=geodesic_rec_dilate(imdest,imin,nhb);
return ret;
}
FLGR_Ret geodesic_rec_close(FLGR_Data2D *imdest,FLGR_Data2D *imin,FLGR_Data2D *nhb) {
FLGR_Ret ret;
if((ret=flgr2d_dilate(imdest,imin,nhb))!=FLGR_RET_OK) return ret;
ret=geodesic_rec_erode(imdest,imin,nhb);
return ret;
}
FLGR_Ret geodesic_rec_open_tophat(FLGR_Data2D *imdest,FLGR_Data2D *imin,FLGR_Data2D *nhb) {
FLGR_Ret ret;
if((ret=geodesic_rec_open(imdest,imin,nhb))!=FLGR_RET_OK) return ret;
ret=flgr2d_arith_sub(imdest,imin,imdest);
return ret;
}
FLGR_Ret geodesic_rec_close_tophat(FLGR_Data2D *imdest,FLGR_Data2D *imin,FLGR_Data2D *nhb) {
FLGR_Ret ret;
if((ret=geodesic_rec_close(imdest,imin,nhb))!=FLGR_RET_OK) return ret;
ret=flgr2d_arith_sub(imdest,imdest,imin);
return ret;
}
int main(void) {
FLGR_Data2D *imin;
FLGR_Data2D *imDest1;
FLGR_Data2D *imDest2;
FLGR_Data2D *imDest3;
FLGR_Data2D *imDest4;
FLGR_Data2D *nhb;
FLGR_Data2D *nhb2;
imin = flgr2d_load_pgm("../../images/gray/lena.pgm");
imDest1 = flgr2d_create_pixmap_from(imin);
imDest2 = flgr2d_create_pixmap_from(imin);
imDest3 = flgr2d_create_pixmap_from(imin);
imDest4 = flgr2d_create_pixmap_from(imin);
nhb = flgr2d_create_neighborhood(9,9,1,FLGR_UINT8,FLGR_HEX,FLGR_6_CONNEX);
nhb2 = flgr2d_create_neighborhood_from_connexity(1,FLGR_UINT8,FLGR_8_CONNEX);
flgr2d_dilate(imDest1, imin, nhb);
flgr2d_copy(imDest2,imDest1);
flgr2d_copy(imDest3,imDest1);
BENCH_FUNCTION(100000,"Erode 3x3 benchmark", flgr2d_erode,imDest4,imin,nhb2);
BENCH_FUNCTION(100,"Fast Dual Geodesic reconstruction",
flgr2d_geodesic_reconstruct_dual,imDest1,imin,nhb->connexity);
BENCH_FUNCTION(100,"Fast Geodesic reconstruction by closing",
flgr2d_geodesic_reconstruct_erode,imDest2,imin,nhb->connexity);
BENCH_FUNCTION(100,"Naive Geodesic reconstruction by closing",
geodesic_rec_erode,imDest3,imin,nhb);
flgr2d_save_pgm(imDest1,"fast_dual.pgm",5);
flgr2d_save_pgm(imDest2,"fast.pgm",5);
flgr2d_save_pgm(imDest3,"dual.pgm",5);
flgr2d_destroy(imin);
flgr2d_destroy(imDest1);
flgr2d_destroy(imDest2);
flgr2d_destroy(imDest3);
flgr2d_destroy(imDest4);
flgr2d_destroy(nhb);
flgr2d_destroy(nhb2);
}