/*************************************************************************************************************************************/
/* */
/* 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