/*************************************************************************************************************************************/ /* */ /* P O U R L A T R A N S F O R M E E E N O N D E L E T T E S D E M O R L E T */ /* D ' U N E I M A G E C O M P L E X E : */ /* */ /* */ /* Author of '$xci/morlet.12$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20030430155117). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N T E R F A C E ' listG ' : */ /* */ /* */ /* :Debut_listG: */ /* :Fin_listG: */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F I C H I E R S D ' I N C L U D E S : */ /* */ /*************************************************************************************************************************************/ #include INCLUDES_BASE #include image_image_IMAGESF_EXT #include image_image_IMAGESJ_EXT /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A R A M E T R E S : */ /* */ /*************************************************************************************************************************************/ #include xci/genere_ch.01.I" #define DILATATION \ FU \ /* Dilatation des coordonnees 'a'. */ #define ROTATION PI_SUR_2 \ /* Facteur de rotation 't'. */ #define MODULE FLOT(SIX) \ /* Module |k|. */ #define LINEAIRE FU \ /* Importance de la partie lineaire de l'exonentielle complexe. */ #define RADIALE FZERO \ /* Importance de la partie radiale de l'exonentielle complexe. */ #define MORLET \ FU \ /* Efficacite de Morlet. */ #define MORLET_X2 \ FDU \ /* Ponderation de XxX, */ #define MORLET_Y2 \ FDU \ /* Ponderation de YxY, */ #define MORLET_XY \ FZERO \ /* Ponderation de XxY. */ #define CALCULER_LA_TRANSFORMEE_DIRECTE \ VRAI \ /* Faut-il calculer la transformee directe ('VRAI') ou inverse ('FAUX') ? */ #define GENERER_LA_PARTIE_REELLE \ VRAI #define GENERER_LA_PARTIE_IMAGINAIRE \ VRAI /* Faut-il calculer les parties Reelle et Imaginaire ? */ #define SEUIL_INFERIEUR_DE_LA_DILATATION \ GRO5(INVE(FLOT(MIN2(dimX,dimY)))) \ /* Seuil inferieur de la dilatation. Pour des dilatations inferieur a ce seuil, l'ondelette */ \ /* sera trop petite (par rapport au point) et l'on risque de tomber sur des problemes */ \ /* d'aliasing... */ #define SEUIL_SUPERIEUR_DE_LA_DILATATION \ GRO10(FRA10(FU)) \ /* Seuil superieur de la dilatation. Pour des dilatations superieur a ce seuil, l'ondelette */ \ /* sera trop grande (par rapport a l'image) et l'on risque de tomber sur des problemes */ \ /* d'anisotropie. Jusqu'au 20030514091146, la valeur de ce seuil etait 'GRO4(FRA10(FU))', */ \ /* mais en fait, il peut etre augmente (le risque encouru etant donc celui de l'anisotropie */ \ /* puisque, en effet, le support de l'ondelette est rectangulaire ce qui peut privilegier */ \ /* les diagonales de ce rectangle lorsque le seuil est trop grand... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ #define TEST_DE_LA_VALEUR_MOYENNE(composante) \ Bblock \ DEFV(Logical,INIT(tester_la_valeur_moyenne,VRAI)); \ /* Afin d'iterer au moins une fois... */ \ \ Tant(IL_FAUT(tester_la_valeur_moyenne)) \ Bblock \ DEFV(genere_Float,INIT(niveau_minimum,FLOT__NIVEAU_UNDEF)); \ DEFV(genere_Float,INIT(niveau_maximum,FLOT__NIVEAU_UNDEF)); \ CALS(IFnivo_extrema(composante,ADRESSE(niveau_minimum),ADRESSE(niveau_maximum))); \ /* Extrema de la composante courante... */ \ \ Test(IZNE(IFnivo_extrema_____niveau_moyen)) \ Bblock \ CALS(IFscale(composante \ ,FU \ ,composante \ ,NEGA(IFnivo_extrema_____niveau_moyen) \ ) \ ); \ /* Retablissement d'une moyenne nulle... */ \ \ EGAL(tester_la_valeur_moyenne,FAUX); \ /* ATTENTION : dans ce cas, on pourrait tester de nouveau la valeur moyenne ; mais les */ \ /* experiences effectuees montrent que la premiere iteration ameliore tres nettement la */ \ /* situation, la seconde tres peu et les suivantes stagnent. Ainsi, par exemple avec le */ \ /* parametre "dilatation=0.08", on trouve les valeurs suivantes pour la valeur moyenne */ \ /* de 'IFmage_PR' au cours des iterations successives (en isolant visuellement la */ \ /* premiere et la seconde afin de bien noter le non interet de l'iteration) : */ \ /* */ \ /* +6.00909e-10 (valeur moyenne apres 'IJgenere_champ(...)'), */ \ /* */ \ /* -4.22899e-17 (valeur moyenne apres le premier 'IFscale(...)'), */ \ /* */ \ /* -3.80239e-18 */ \ /* -6.80707e-19 */ \ /* -4.25158e-19 */ \ /* -2.96997e-19 */ \ /* +6.53087e-19 */ \ /* -4.09426e-19 */ \ /* -2.88639e-19 */ \ /* +6.67143e-19 */ \ /* (...) */ \ /* */ \ /* ce n'est donc pas la peine d'iterer, d'ou l'arret immediat (via le 'FAUX'). Malgre */ \ /* tout, je laisse le 'Tant(...)' car, en effet, on ne sait jamais... */ \ Eblock \ ATes \ Bblock \ EGAL(tester_la_valeur_moyenne,FAUX); \ /* Evidemment, dans ce cas, il faut arreter d'iterer la correction... */ \ Eblock \ ETes \ Eblock \ ETan \ Eblock \ /* Test de la moyenne de la composante courante et retablissement d'une moyenne nulle si */ \ /* necessaire (procedure introduite le 20030509090919). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P O U R L A T R A N S F O R M E E E N O N D E L E T T E S D E M O R L E T */ /* D ' U N E I M A G E C O M P L E X E : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(CHAR,INIC(POINTERc(nom_imageR),NOM_PIPE)); #include xci/genere_ch.02.I" DEFV(complexe,valeur_initiale); /* Valeur initiale du champ de Morlet. */ DEFV(Logical,INIT(calculer_la_transformee_directe,CALCULER_LA_TRANSFORMEE_DIRECTE)); /* Faut-il calculer la transformee directe ('VRAI') ou inverse ('FAUX') ? */ DEFV(Logical,INIT(generer_la_partie_reelle,GENERER_LA_PARTIE_REELLE)); DEFV(Logical,INIT(generer_la_partie_imaginaire,GENERER_LA_PARTIE_IMAGINAIRE)); /* Faut-il calculer les parties Reelle et Imaginaire ? */ DEFV(Float,INIT(seuil_inferieur_de_la_dilatation,SEUIL_INFERIEUR_DE_LA_DILATATION)); /* Seuil inferieur de la dilatation. Pour des dilatations inferieur a ce seuil, l'ondelette */ /* sera trop petite (par rapport au point) et l'on risque de tomber sur des problemes */ /* d'aliasing... */ DEFV(Float,INIT(seuil_superieur_de_la_dilatation,SEUIL_SUPERIEUR_DE_LA_DILATATION)); /* Seuil superieur de la dilatation. Pour des dilatations superieur a ce seuil, l'ondelette */ /* sera trop grande (par rapport a l'image) et l'on risque de tomber sur des problemes */ /* d'anisotropie. Jusqu'au 20030514091146, la valeur de ce seuil etait 'GRO4(FRA10(FU))', */ /* mais en fait, il peut etre augmente (le risque encouru etant donc celui de l'anisotropie */ /* puisque, en effet, le support de l'ondelette est rectangulaire ce qui peut privilegier */ /* les diagonales de ce rectangle lorsque le seuil est trop grand... */ /*..............................................................................................................................*/ Cinitialisation(valeur_initiale,R0_Complexe,I0_Complexe); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____translation,FZERO); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____homothetie,FU); /* Definition des parametres specifiques aux images complexes... */ EGAL(Fmorlet_reel__Fmorlet_imaginaire_____dilatation,DILATATION); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____angle_rotation,ROTATION); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____nombre_de_periodes,MODULE); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____coefficient_rotation,LINEAIRE); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____coefficient_rayon,RADIALE); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____coefficient,MORLET); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____coefficient_X2,MORLET_X2); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____coefficient_Y2,MORLET_Y2); EGAL(Fmorlet_reel__Fmorlet_imaginaire_____coefficient_XY,MORLET_XY); /* Definition du champ de Morlet... */ #include xci/genere_ch.03.I" GET_ARGUMENTSi(nombre_d_arguments ,BLOC(GET_ARGUMENT_C("imageR=""R=",nom_imageR); GET_ARGUMENT_F("amplificateur=""a=",amplificateur_de_la_fonction); GET_ARGUMENT_F("translateur=""tr=""T=",translateur_de_la_fonction); /* Le 20050623151902, "t=" a ete remplace par "tr=" (double definition...). */ GET_ARGUMENT_F("dilatation=""d=",Fmorlet_reel__Fmorlet_imaginaire_____dilatation); GET_ARGUMENT_F("theta=""rotation=""p=""angle=",Fmorlet_reel__Fmorlet_imaginaire_____angle_rotation); /* Le 20050623151902, "t=" a ete remplace par "angle=" et "theta=" (double definition...). */ GET_ARGUMENT_F("nombre_periodes=""module=""m=""k=",Fmorlet_reel__Fmorlet_imaginaire_____nombre_de_periodes); /* Le 20121114112732 "nombre_periodes=" a ete introduit... */ GET_ARGUMENT_F("lineaire=""l=",Fmorlet_reel__Fmorlet_imaginaire_____coefficient_rotation); GET_ARGUMENT_F("radiale=""r=",Fmorlet_reel__Fmorlet_imaginaire_____coefficient_rayon); GET_ARGUMENT_F("c=",Fmorlet_reel__Fmorlet_imaginaire_____coefficient); GET_ARGUMENT_F("cx2=",Fmorlet_reel__Fmorlet_imaginaire_____coefficient_X2); GET_ARGUMENT_F("cy2=",Fmorlet_reel__Fmorlet_imaginaire_____coefficient_Y2); GET_ARGUMENT_F("cxy=",Fmorlet_reel__Fmorlet_imaginaire_____coefficient_XY); GET_ARGUMENT_L("translater=",IJscale_____translater_aussi_la_partie_Imaginaire); GET_ARGUMENT_L("directe=",calculer_la_transformee_directe); GET_ARGUMENT_N("inverser=""inverse=",calculer_la_transformee_directe); GET_ARGUMENT_L("reelle=""PR=",generer_la_partie_reelle); GET_ARGUMENT_L("imaginaire=""PI=",generer_la_partie_imaginaire); GET_ARGUMENT_F("valeur=""PRPI=",Funiforme_____valeur); /* On notera qu'une seule valeur 'Funiforme_____valeur' est disponible pour deux */ /* initialisations possibles, l'une de la partie Reelle et l'autre de la partie */ /* Imaginaire. Cela n'est en fait pas tres grave car il semble assez probable que */ /* l'on ne demande jamais de ne generer ni la partie Reelle ni la partie Imaginaire ! */ GET_ARGUMENT_F("si=""seuil_inferieur=""inferieur=",seuil_inferieur_de_la_dilatation); GET_ARGUMENT_F("superieur=""ss=""seuil_superieur=",seuil_superieur_de_la_dilatation); /* Ceci a ete introduit le 20030509210713... */ GET_ARGUMENT_L("rn=""renormaliser=",IJgenere_champ_____renormaliser_le_champ_automatiquement); /* Arguments introduits le 20121114132502... */ ) ); Test(IFEXff(Fmorlet_reel__Fmorlet_imaginaire_____dilatation,seuil_inferieur_de_la_dilatation,seuil_superieur_de_la_dilatation)) /* Ce test a ete introduit le 20030505145359 pour eviter des problemes d'aliasing... */ Bblock PRINT_ATTENTION("la dilation demandee est hors 'norme'"); CAL1(Prer3("(la dilatation demandee vaut %f alors que les seuils inferieur et superieur valent respectivement {%f,%f})\n" ,Fmorlet_reel__Fmorlet_imaginaire_____dilatation ,seuil_inferieur_de_la_dilatation ,seuil_superieur_de_la_dilatation ) ); Eblock ATes Bblock Eblock ETes CALi(IJinitialisation(IJmageR,ADRESSE(valeur_initiale))); /* Initialisation de l'image Resultat. */ CALS(IJgenere_champ(IJmageR ,amplificateur_de_la_fonction ,COND(IL_FAUT(generer_la_partie_reelle) ,COND(IL_FAUT(calculer_la_transformee_directe) ,aFONCTION(Ftransformee_directe_de_Morlet_reel) ,aFONCTION(Ftransformee_inverse_de_Morlet_reel) ) ,aFONCTION(Funiforme) ) ,COND(IL_FAUT(generer_la_partie_imaginaire) ,COND(IL_FAUT(calculer_la_transformee_directe) ,aFONCTION(Ftransformee_directe_de_Morlet_imaginaire) ,aFONCTION(Ftransformee_inverse_de_Morlet_imaginaire) ) ,aFONCTION(Funiforme) ) ,translateur_de_la_fonction ,ADRESSE(translation) ,ADRESSE(echelle) ,Zf_ARGUMENT_INUTILE ,Tf_ARGUMENT_INUTILE ) ); /* Generation du champ de Morlet... */ /* */ /* L'argument 'Tf_ARGUMENT_INUTILE' a ete introduit le 20100209120931... */ CALS(Icomplexe_reelle(IFmage_PR,IJmageR)); CALS(Icomplexe_imaginaire(IFmage_PI,IJmageR)); /* Recuperation des parties reelles et imaginaires. */ TEST_DE_LA_VALEUR_MOYENNE(IFmage_PR); TEST_DE_LA_VALEUR_MOYENNE(IFmage_PI); /* Verification que la moyenne est bien nulle et retablissement si necessaire... */ CALS(Ireelle_complexe(IJmageR,IFmage_PR)); CALS(Iimaginaire_complexe(IJmageR,IFmage_PI)); /* Reconstitution de l'image Resultat complexe. */ CALi(IupdateJ_image(nom_imageR,IJmageR)); /* Et rangement du champ complexe... */ RETU_Commande; Eblock ECommande