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



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.