_______________________________________________________________________________________________________________________________________ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N S D E B A S E A Q U A T R E I M A G E S : */ /* */ /* */ /* Definition : */ /* */ /* Ce fichier contient toutes les fonctions */ /* de base de gestion et de manipulation de */ /* quatre images raster, quelle que soit la definition. */ /* Ainsi, on pourra avec elles passer des */ /* fausses aux vraies couleurs... */ /* */ /* */ /* Author of '$xiii/quad_image$FON' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 19870000000000). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E P L A C E M E N T L O C A L E T Q U E L C O N Q U E D E S P O I N T S D ' U N E I M A G E : */ /* */ /*************************************************************************************************************************************/ #define NIVEAU_XY(image,normalisation) \ normalisation(______NORMALISE_NIVEAU(load_point(image,X,Y))) \ /* Procedure permettant de passer d'un niveau a un deplacement selon un axe... */ \ /* */ \ /* ATTENTION, comme on a en general : */ \ /* */ \ /* dimX # COULEURS */ \ /* */ \ /* et : */ \ /* */ \ /* dimY # COULEURS */ \ /* */ \ /* la procedure 'NIVEAU_XY(...)' implique un "regroupement par paquets" des coordonnees */ \ /* deplacees lorsque la relation '#' est '>', et une suppression de points pour '<'. */ #define CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UN_DEPLACEMENT_LOCAL_QUELCONQUE \ DEFV(Int,INIT(X_deplace,NIVEAU_XY(deplacement_horizontal,_cDENORMALISE_OX))); \ DEFV(Int,INIT(Y_deplace,NIVEAU_XY(deplacement_vertical,_cDENORMALISE_OY))); \ /* Definition des coordonnees deplacees, et ce afin d'alleger le code qui suit... */ \ /* */ \ /* ATTENTION, jusqu'au 20051203130754, les fonctions : */ \ /* */ \ /* _lDENORMALISE_OX(...) */ \ /* _lDENORMALISE_OY(...) */ \ /* */ \ /* etaient utilisees ci-dessus par erreur... */ \ \ EGAL(X_deplace,COND(IL_NE_FAUT_PAS(tore_horizontal),X_deplace,MODX(X_deplace))); \ EGAL(Y_deplace,COND(IL_NE_FAUT_PAS(tore_vertical),Y_deplace,MODY(Y_deplace))); \ /* Gestion d'un eventuel tore... */ \ \ /* Procedure permettant de convertir deux niveaux en deux coordonnees {x,y}. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E P L A C E M E N T L O C A L E T Q U E L C O N Q U E D E S P O I N T S */ /* D ' U N E I M A G E " S T A N D A R D " : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ideplacement_local_quelconque(imageR ,imageA ,deplacement_horizontal,tore_horizontal ,deplacement_vertical,tore_vertical ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=imageA deplacee localement. */ DEFV(Argument,DEFV(image,imageA)); /* Image Argument a deplacer, */ DEFV(Argument,DEFV(image,deplacement_horizontal)); /* Seconde image Argument definissant le deplacement horizontal, */ DEFV(Argument,DEFV(Logical,tore_horizontal)); /* La direction horizontale ('X') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ DEFV(Argument,DEFV(image,deplacement_vertical)); /* Troisieme image Argument definissant le deplacement vertical. */ DEFV(Argument,DEFV(Logical,tore_vertical)); /* La direction verticale ('Y') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UN_DEPLACEMENT_LOCAL_QUELCONQUE; store_point(load_point_valide(imageA,X_deplace,Y_deplace) ,imageR ,X,Y ,FVARIABLE ); /* Et deplacement... */ Eblock end_image RETI(imageR); Eblock EFonctionP /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E P L A C E M E N T L O C A L E T Q U E L C O N Q U E D E S P O I N T S */ /* D ' U N E I M A G E " F L O T T A N T E " : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFdeplacement_local_quelconque(imageR ,imageA ,deplacement_horizontal,tore_horizontal ,deplacement_vertical,tore_vertical ) ) ) ) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=imageA deplacee localement. */ DEFV(Argument,DEFV(imageF,imageA)); /* Image Argument a deplacer, */ DEFV(Argument,DEFV(image,deplacement_horizontal)); /* Seconde image Argument definissant le deplacement horizontal, */ DEFV(Argument,DEFV(Logical,tore_horizontal)); /* La direction horizontale ('X') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ DEFV(Argument,DEFV(image,deplacement_vertical)); /* Troisieme image Argument definissant le deplacement vertical. */ DEFV(Argument,DEFV(Logical,tore_vertical)); /* La direction verticale ('Y') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UN_DEPLACEMENT_LOCAL_QUELCONQUE; storeF_point(loadF_point_valide(imageA,X_deplace,Y_deplace) ,imageR ,X,Y ); /* Et deplacement... */ Eblock end_image RETIF(imageR); Eblock EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E P L A C E M E N T L O C A L E T Q U E L C O N Q U E D E S P O I N T S */ /* D ' U N E I M A G E " C O M P L E X E " : */ /* */ /*************************************************************************************************************************************/ BFonctionJ DEFV(Common,DEFV(FonctionJ,POINTERJ(IJdeplacement_local_quelconque(imageR ,imageA ,deplacement_horizontal ,deplacement_vertical ) ) ) ) DEFV(Argument,DEFV(imageJ,imageR)); /* Image Resultat, telle que : imageR=imageA deplacee localement. */ DEFV(Argument,DEFV(imageJ,imageA)); /* Image Argument a deplacer, */ DEFV(Argument,DEFV(image,deplacement_horizontal)); /* Seconde image Argument definissant le deplacement horizontal, */ DEFV(Argument,DEFV(image,deplacement_vertical)); /* Troisieme image Argument definissant le deplacement vertical. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Logical,INIT(tore_horizontal,VRAI)); DEFV(Logical,INIT(tore_vertical,VRAI)); /* Les directions horizontale ('X') et verticales ('Y') sont repliees sur elles-memes */ /* systematiquement car, en effet, la fonction 'loadJ_point_valide(...)' n'est pas */ /* disponible... */ /*..............................................................................................................................*/ begin_image Bblock CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UN_DEPLACEMENT_LOCAL_QUELCONQUE; storeJ_point(loadJ_point(imageA,X_deplace,Y_deplace) ,imageR ,X,Y ); /* Et deplacement... */ Eblock end_image RETIJ(imageR); Eblock EFonctionJ #undef CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UN_DEPLACEMENT_LOCAL_QUELCONQUE #undef NIVEAU_XY _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A N S L A T I O N L O C A L E E T Q U E L C O N Q U E D E S P O I N T S D ' U N E I M A G E : */ /* */ /*************************************************************************************************************************************/ #define NIVEAU_XY(coordonnee,image,normalisation) \ ADD2(coordonnee,normalisation(______NORMALISE_NIVEAU(load_point(image,X,Y)))) \ /* Procedure permettant de passer d'un niveau a une translation selon un axe... */ #define CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UNE_TRANSLATION_LOCALE_QUELCONQUE \ DEFV(Int,INIT(X_translate,NIVEAU_XY(X,translation_horizontale,_lDENORMALISE_OX))); \ DEFV(Int,INIT(Y_translate,NIVEAU_XY(Y,translation_verticale,_lDENORMALISE_OY))); \ /* Definition des coordonnees translatees, et ce afin d'alleger le code qui suit... */ \ \ EGAL(X_translate,COND(IL_NE_FAUT_PAS(tore_horizontal),X_translate,MODX(X_translate))); \ EGAL(Y_translate,COND(IL_NE_FAUT_PAS(tore_vertical),Y_translate,MODY(Y_translate))); \ /* Gestion d'un eventuel tore... */ \ \ /* Procedure permettant de convertir deux niveaux en deux coordonnees {x,y}. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A N S L A T I O N L O C A L E E T Q U E L C O N Q U E D E S P O I N T S */ /* D ' U N E I M A G E " S T A N D A R D " : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(Logical,SINT(Itranslation_locale_quelconque_____deplacer_tous_les_niveaux_de_imageA,VRAI))); DEFV(Common,DEFV(genere_p,SINT(Itranslation_locale_quelconque_____niveau_unique_a_deplacer_de_imageA,BLANC))); /* Ce parametre introduit le 20051203131159, si 'IL_NE_FAUT_PAS(translations_directes)', */ /* permet de ne deplacder tous les niveaux de 'imageA' ('VRAI', ce qui assure, par defaut, */ /* la compatibilite anterieure) ou bien un seul ('FAUX') definit ci-dessus... */ DEFV(Common,DEFV(FonctionP,POINTERp(Itranslation_locale_quelconque(imageR ,imageA ,translation_horizontale,tore_horizontal ,translation_verticale,tore_vertical ,translations_directes ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=imageA translatee localement. */ DEFV(Argument,DEFV(image,imageA)); /* Image Argument a translater, */ DEFV(Argument,DEFV(image,translation_horizontale)); /* Seconde image Argument definissant la translation horizontale, */ DEFV(Argument,DEFV(Logical,tore_horizontal)); /* La direction horizontale ('X') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ DEFV(Argument,DEFV(image,translation_verticale)); /* Troisieme image Argument definissant la translation verticale. */ DEFV(Argument,DEFV(Logical,tore_vertical)); /* La direction verticale ('Y') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ DEFV(Argument,DEFV(Logical,translations_directes)); /* Indique si l'on doit passer de {X_translate,Y_translate} a {X,Y} ('VRAI') ou l'inverse, */ /* c'est-a-dire passer de {X,Y} a {X_translate,Y_translate} ('FAUX'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UNE_TRANSLATION_LOCALE_QUELCONQUE; Test(IL_FAUT(translations_directes)) Bblock store_point(load_point_valide(imageA,X_translate,Y_translate) ,imageR ,X,Y ,FVARIABLE ); Eblock ATes Bblock DEFV(genere_p,INIT(niveau_courant_de_imageA,load_point(imageA,X,Y))); /* Niveau courant en {X,Y} de 'imageA'... */ Test(IFOU(IL_FAUT(Itranslation_locale_quelconque_____deplacer_tous_les_niveaux_de_imageA) ,IFET(IL_NE_FAUT_PAS(Itranslation_locale_quelconque_____deplacer_tous_les_niveaux_de_imageA) ,IFEQ(niveau_courant_de_imageA,Itranslation_locale_quelconque_____niveau_unique_a_deplacer_de_imageA) ) ) ) Bblock store_point_valide(load_point(imageA,X,Y) ,imageR ,X_translate,Y_translate ,FVARIABLE ); Eblock ATes Bblock Eblock ETes Eblock ETes /* Et translation... On notera l'usage des fonctions 'MOD?(...)' qui permettent, bien que */ /* les translations defines par 'translation_horizontale' et 'translation_verticale' soient */ /* positives ou nulles, d'obtenir des translation "negatives"... */ Eblock end_image RETI(imageR); Eblock EFonctionP /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A N S L A T I O N L O C A L E E T Q U E L C O N Q U E D E S P O I N T S */ /* D ' U N E I M A G E " F L O T T A N T E " : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFtranslation_locale_quelconque(imageR ,imageA ,translation_horizontale,tore_horizontal ,translation_verticale,tore_vertical ,translations_directes ) ) ) ) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=imageA translatee localement. */ DEFV(Argument,DEFV(imageF,imageA)); /* Image Argument a translater, */ DEFV(Argument,DEFV(image,translation_horizontale)); /* Seconde image Argument definissant la translation horizontale, */ DEFV(Argument,DEFV(Logical,tore_horizontal)); /* La direction horizontale ('X') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ DEFV(Argument,DEFV(image,translation_verticale)); /* Troisieme image Argument definissant la translation verticale. */ DEFV(Argument,DEFV(Logical,tore_vertical)); /* La direction verticale ('Y') est-elle repliee sur elle-meme ('VRAI') ou non ('FAUX'). */ DEFV(Argument,DEFV(Logical,translations_directes)); /* Indique si l'on doit passer de {X_translate,Y_translate} a {X,Y} ('VRAI') ou l'inverse, */ /* c'est-a-dire passer de {X,Y} a {X_translate,Y_translate} ('FAUX'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UNE_TRANSLATION_LOCALE_QUELCONQUE; Test(IL_FAUT(translations_directes)) Bblock storeF_point(loadF_point_valide(imageA,X_translate,Y_translate) ,imageR ,X,Y ); Eblock ATes Bblock storeF_point_valide(loadF_point(imageA,X,Y) ,imageR ,X_translate,Y_translate ); Eblock ETes /* Et translation... On notera l'usage des fonctions 'MOD?(...)' qui permettent, bien que */ /* les translations defines par 'translation_horizontale' et 'translation_verticale' soient */ /* positives ou nulles, d'obtenir des translation "negatives"... */ Eblock end_image RETIF(imageR); Eblock EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A N S L A T I O N L O C A L E E T Q U E L C O N Q U E D E S P O I N T S */ /* D ' U N E I M A G E " C O M P L E X E " : */ /* */ /*************************************************************************************************************************************/ BFonctionJ DEFV(Common,DEFV(FonctionJ,POINTERJ(IJtranslation_locale_quelconque(imageR ,imageA ,translation_horizontale ,translation_verticale ,translations_directes ) ) ) ) DEFV(Argument,DEFV(imageJ,imageR)); /* Image Resultat, telle que : imageR=imageA translatee localement. */ DEFV(Argument,DEFV(imageJ,imageA)); /* Image Argument a translater, */ DEFV(Argument,DEFV(image,translation_horizontale)); /* Seconde image Argument definissant la translation horizontale, */ DEFV(Argument,DEFV(image,translation_verticale)); /* Troisieme image Argument definissant la translation verticale. */ DEFV(Argument,DEFV(Logical,translations_directes)); /* Indique si l'on doit passer de {X_translate,Y_translate} a {X,Y} ('VRAI') ou l'inverse, */ /* c'est-a-dire passer de {X,Y} a {X_translate,Y_translate} ('FAUX'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Logical,INIT(tore_horizontal,VRAI)); DEFV(Logical,INIT(tore_vertical,VRAI)); /* Les directions horizontale ('X') et verticale ('Y') sont repliees sur elles-memes */ /* systematiquement car, en effet, la fonction 'loadJ_point_valide(...)' n'est pas */ /* disponible... */ /*..............................................................................................................................*/ begin_image Bblock CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UNE_TRANSLATION_LOCALE_QUELCONQUE; Test(IL_FAUT(translations_directes)) Bblock storeJ_point(loadJ_point(imageA,X_translate,Y_translate) ,imageR ,X,Y ); Eblock ATes Bblock storeJ_point(loadJ_point(imageA,X,Y) ,imageR ,X_translate,Y_translate ); Eblock ETes /* Et translation... On notera l'usage des fonctions 'MOD?(...)' qui permettent, bien que */ /* les translations defines par 'translation_horizontale' et 'translation_verticale' soient */ /* positives ou nulles, d'obtenir des translation "negatives"... */ Eblock end_image RETIJ(imageR); Eblock EFonctionJ #undef CONVERSION_DES_NIVEAUX_EN_COORDONNEES_POUR_UNE_TRANSLATION_LOCALE_QUELCONQUE #undef NIVEAU_XY _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E L A D E F O R M A T I O N D E P A S S A G E */ /* D ' U N E I M A G E A U N E A U T R E : */ /* */ /*************************************************************************************************************************************/ BFonctionI /* ATTENTION : c'est bien 'FonctionI' (et non pas 'FonctionF') a cause du 'RETU_ERROR'... */ #define DEPLACEMENT_NUL_EN_X_ET_EN_Y \ FZERO #define DEPLACEMENT_NON_DEFINI_EN_X_ET_EN_Y \ F_INFINI /* Definition des deplacements nuls et non definis... */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____seuil_strict,VRAI))); #define IFGT_IFGE(x,a) \ IFGc(x,a,IFdeformation_de_passage_d_une_image_a_une_autre_____seuil_strict) \ /* Afin de pouvoir selectionner entre des 'IFGT(...)'s et des 'IFGE(...)'. */ #define arrondir_centre_de_gravite________G12 \ IFdeformation_de_passage_d_une_image_a_une_autre_____arrondir_centre_de_gravite________G12 #define arrondir_point_courant_interieur___P1 \ IFdeformation_de_passage_d_une_image_a_une_autre_____arrondir_point_courant_interieur___P1 #define arrondir_point_courant_du_contour_C12 \ IFdeformation_de_passage_d_une_image_a_une_autre_____arrondir_point_courant_du_contour_C12 /* Definitions destinees a raccourcir quelques lignes a venir... */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____arrondir_centre_de_gravite________G12,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____arrondir_point_courant_interieur___P1,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____arrondir_point_courant_du_contour_C12,VRAI))); #define ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir,coordonnee) \ COND(IL_FAUT(arrondir) \ ,AINT(coordonnee) \ ,NEUT(coordonnee) \ ) \ /* Afin de pouvoir facilement essayer 'AINT(...)', 'ARRO(...)' ou encore 'ENTO(...)' */ \ /* (introduit le 20120615155805 et complete par le 'COND(...)' le 20120619102601...), en */ /* notant malgre tout que c'est 'AINT(...)' qui donne les meilleurs resultats... */ #define point_X \ FLOT(X) #define point_Y \ FLOT(Y) /* Point courant des images. */ #define CALCUL_DU_CENTRE_DE_GRAVITE(image,seuil,centre_de_gravite_X,centre_de_gravite_Y) \ Bblock \ DEFV(Positive,INIT(nombre_de_points,ZERO)); \ DEFV(Float,INIT(cumul_des_niveaux,FZERO)); \ DEFV(Float,INIT(cumul_coordonnees_X_ponderees,FZERO)); \ DEFV(Float,INIT(cumul_coordonnees_Y_ponderees,FZERO)); \ \ begin_image \ Bblock \ DEFV(genere_Float,INIT(niveau_courant,loadF_point(image,X,Y))); \ \ Test(IFGT_IFGE(niveau_courant,seuil)) \ Bblock \ INCR(nombre_de_points,I); \ /* Ne sert a rien, mais on ne sait jamais... */ \ INCR(cumul_des_niveaux,niveau_courant); \ \ INCR(cumul_coordonnees_X_ponderees,MUL2(niveau_courant,point_X)); \ INCR(cumul_coordonnees_Y_ponderees,MUL2(niveau_courant,point_Y)); \ /* Seuls les points de niveau superieur [ou egal] au seuil sont pris en compte... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ end_image \ \ Test(IZNE(cumul_des_niveaux)) \ /* Test manquant introduit le 20220205080727... */ \ Bblock \ EGAL(centre_de_gravite_X,DIVI(cumul_coordonnees_X_ponderees,cumul_des_niveaux)); \ EGAL(centre_de_gravite_Y,DIVI(cumul_coordonnees_Y_ponderees,cumul_des_niveaux)); \ Eblock \ ATes \ Bblock \ PRINT_ATTENTION("lors du calcul du centre de gravite, le cumul des niveaux est nul."); \ \ EGAL(centre_de_gravite_X,FLOT(Xcentre)); \ EGAL(centre_de_gravite_Y,FLOT(Ycentre)); \ /* Dans ces conditions, arbitrairement, on place le centre de gravite au centre... */ \ Eblock \ ETes \ \ EGAL(centre_de_gravite_X \ ,ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir_centre_de_gravite________G12 \ ,centre_de_gravite_X \ ) \ ); \ EGAL(centre_de_gravite_Y \ ,ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir_centre_de_gravite________G12 \ ,centre_de_gravite_Y \ ) \ ); \ /* Au cas ou il serait mieux de prendre la partie entiere... */ \ Eblock \ /* Calcul du centre de gravite d'une image... */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____acces_simplifie,VRAI))); /* Afin d'assurer le parametrage de 'ACCES_POINT(...)'. */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____periodiser_X,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____periodiser_Y,FAUX))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax] est periodique ou pas. */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____symetriser_X,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____symetriser_Y,FAUX))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax] est symetrique ou pas. */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____prolonger_X,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____prolonger_Y,FAUX))); /* Indique si l'espace [Xmin,Xmax]x[Ymin,Ymax] doit etre prolonge a l'exterieur comme il */ /* est au bord... */ DEFV(Common,DEFV(genere_Float,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____niveau_hors_image ,DEPLACEMENT_NUL_EN_X_ET_EN_Y ) ) ); /* Niveau a forcer au cas ou les coordonnees transformees seraient "hors-image". */ #define ACCES_POINT(image,Xf,Yf) \ COND(IL_FAUT(IFdeformation_de_passage_d_une_image_a_une_autre_____acces_simplifie) \ ,loadF_point(image,Xf,Yf) \ ,FFload_point_coordonnees_01(image \ ,_____cNORMALISE_OX(Xf),_____cNORMALISE_OY(Yf) \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____periodiser_X \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____periodiser_Y \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____symetriser_X \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____symetriser_Y \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____prolonger_X \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____prolonger_Y \ ,IFdeformation_de_passage_d_une_image_a_une_autre_____niveau_hors_image \ ) \ ) \ /* Acces a un point avec mise des coordonnees flottantes {Xf,Yf} dans [0,1]... */ #define RECHERCHE_D_UN_POINT_DU_CONTOUR(contour) \ Bblock \ Tant(IL_FAUT(rechercher_un_point_du_contour`contour)) \ Bblock \ Test(TEST_DANS_L_IMAGE(INTE(X`contour`point_courant_du_contour) \ ,INTE(Y`contour`point_courant_du_contour) \ ) \ ) \ Bblock \ Test(IFGT_IFGE(ACCES_POINT(imageA_contour`contour \ ,X`contour`point_courant_du_contour \ ,Y`contour`point_courant_du_contour \ ) \ ,seuil_de_definition_du_contour`contour \ ) \ ); \ Bblock \ INCR(X`contour`point_courant_du_contour,pas_X__contour`contour); \ INCR(Y`contour`point_courant_du_contour,pas_Y__contour`contour); \ /* Tant qu'on est a l'interieur du 'contour' on progresse sur la droite joignant le */ \ /* le point courant {X,Y} au centre de gravite du 'contour_C2'... */ \ Eblock \ ATes \ Bblock \ EGAL(rechercher_un_point_du_contour`contour,FAUX); \ /* Dans le cas contraire, on arrete... */ \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ EGAL(rechercher_un_point_du_contour`contour,FAUX); \ Eblock \ ETes \ Eblock \ ETan \ \ EGAL(X`contour`point_courant_du_contour \ ,ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir_point_courant_du_contour_C12 \ ,X`contour`point_courant_du_contour \ ) \ ); \ EGAL(Y`contour`point_courant_du_contour \ ,ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir_point_courant_du_contour_C12 \ ,Y`contour`point_courant_du_contour \ ) \ ); \ /* Au cas ou il serait mieux de prendre la partie entiere... */ \ /* */ \ /* Les experiences faites aux environs du 'v $xiii/quad_image$FON 20120615074526' montrent */ \ /* qu'en fait le probleme n'est pas la... */ \ Eblock \ /* Recherche d'un point du contour... */ DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__G1,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__G2,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__XY,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__C1,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__C2,FAUX))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__pas,VRAI))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__similitude,VRAI))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__P1,VRAI))); DEFV(Common,DEFV(Logical,SINT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles__P2,VRAI))); /* Introduit le 20120618154406 afin d'aider la mise au point et completes par des */ /* indicateurs selectifs le 20120618165110... */ #define EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(editer,format,coordonnee1,coordonnee2,separateur) \ Bblock \ Test(IL_FAUT(NomDeLaFonctionCourante QD@@__ _____lister_les_coordonnees_utiles_`editer)) \ Bblock \ CAL3(Prme2(format,coordonnee1,coordonnee2)); \ CAL3(Prme0(separateur)); \ \ EGAL(au_moins_un_couple_de_coordonees_a_ete_editee,VRAI); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Edition d'un couple de coordonnees (introduite le 20120618165110). */ DEFV(Common,DEFV(FonctionI,IFdeformation_de_passage_d_une_image_a_une_autre(imageR_deformation_X,imageR_deformation_Y ,imageA_contour_C1,seuil_de_definition_du_contour_C1 ,imageA_contour_C2,seuil_de_definition_du_contour_C2 ) ) ) /* Fonction introduite le 20120613175703... */ DEFV(Argument,DEFV(imageF,imageR_deformation_X)); DEFV(Argument,DEFV(imageF,imageR_deformation_Y)); /* Images Resultat {deformation_X,deformation_Y}. */ DEFV(Argument,DEFV(imageF,imageA_contour_C1)); DEFV(Argument,DEFV(genere_Float,seuil_de_definition_du_contour_C1)); /* Image Argument definissant 'contour_C1'... */ DEFV(Argument,DEFV(imageF,imageA_contour_C2)); DEFV(Argument,DEFV(genere_Float,seuil_de_definition_du_contour_C2)); /* Image Argument definissant 'contour_C2', sachant que l'on veut passer de 'contour_C1' */ /* a 'contour_C2'... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ DEFV(genere_Float,INIT(minimum_deformation_X_courante,F_INFINI)); DEFV(genere_Float,INIT(maximum_deformation_X_courante,F_MOINS_L_INFINI)); DEFV(genere_Float,INIT(minimum_deformation_Y_courante,F_INFINI)); DEFV(genere_Float,INIT(maximum_deformation_Y_courante,F_MOINS_L_INFINI)); /* Donnees introduites le 20120620104755... */ DEFV(Float,INIT(X_G1_centre_de_gravite_______,FLOT__UNDEF)); DEFV(Float,INIT(Y_G1_centre_de_gravite_______,FLOT__UNDEF)); DEFV(Float,INIT(X_G2_centre_de_gravite_______,FLOT__UNDEF)); DEFV(Float,INIT(Y_G2_centre_de_gravite_______,FLOT__UNDEF)); /* Definition des centres de gravite des images {contour_C1,contour_C2}. */ /*..............................................................................................................................*/ CALS(IFinitialisation(imageR_deformation_X,DEPLACEMENT_NON_DEFINI_EN_X_ET_EN_Y)); CALS(IFinitialisation(imageR_deformation_Y,DEPLACEMENT_NON_DEFINI_EN_X_ET_EN_Y)); /* A priori... */ CALCUL_DU_CENTRE_DE_GRAVITE(imageA_contour_C1 ,seuil_de_definition_du_contour_C1 ,X_G1_centre_de_gravite_______ ,Y_G1_centre_de_gravite_______ ); CALCUL_DU_CENTRE_DE_GRAVITE(imageA_contour_C2 ,seuil_de_definition_du_contour_C2 ,X_G2_centre_de_gravite_______ ,Y_G2_centre_de_gravite_______ ); /* Calcul des centres de gravite des images {contour_C1,contour_C2}. */ begin_image Bblock Test(IFGT_IFGE(loadF_point(imageA_contour_C2,X,Y),seuil_de_definition_du_contour_C2)) Bblock DEFV(Float,INIT(pas_X__contour_C2,FLOT__UNDEF)); DEFV(Float,INIT(pas_Y__contour_C2,FLOT__UNDEF)); Test(IFET(IFEQ(point_X,X_G2_centre_de_gravite_______),IFEQ(point_Y,Y_G2_centre_de_gravite_______))) Bblock storeF_point(DEPLACEMENT_NUL_EN_X_ET_EN_Y,imageR_deformation_X,X,Y); storeF_point(DEPLACEMENT_NUL_EN_X_ET_EN_Y,imageR_deformation_Y,X,Y); Eblock ATes Bblock Test(IFEQ(X_G2_centre_de_gravite_______,point_X)) Bblock EGAL(pas_X__contour_C2,FZERO); EGAL(pas_Y__contour_C2,FU); /* Cas ou la doite passant par le point courant {X,Y} et le centre de gravite du */ /* 'contour_C2' est verticale... */ Eblock ATes Bblock DEFV(Float,INIT(pente ,DIVI(SOUS(point_Y,Y_G2_centre_de_gravite_______) ,SOUS(point_X,X_G2_centre_de_gravite_______) ) ) ); EGAL(pente,ABSO(pente)); EGAL(pas_X__contour_C2,INVE(RACX(ADD2(EXP2(pente),FU)))); EGAL(pas_Y__contour_C2,MUL2(pente,pas_X__contour_C2)); /* Cas ou la doite passant par le point courant {X,Y} et le centre de gravite du */ /* 'contour_C2' n'est pas verticale... */ /* */ /* {pX,pY} designant {pas_X__contour_C2,pas_Y__contour_C2}, on a : */ /* */ /* pY */ /* ---- = pente */ /* pX */ /* */ /* 2 2 2 */ /* pX + pY = 1 */ /* */ /* en utilisant donc un deplacement unitaire... */ Eblock ETes EGAL(pas_X__contour_C2 ,MEME_SIGNE_QUE(SOUS(point_X,X_G2_centre_de_gravite_______) ,pas_X__contour_C2 ) ); EGAL(pas_Y__contour_C2 ,MEME_SIGNE_QUE(SOUS(point_Y,Y_G2_centre_de_gravite_______) ,pas_Y__contour_C2 ) ); /* Prise en compte du signe de la pente de cette droite... */ Eblock ETes begin_nouveau_block Bblock DEFV(Logical,INIT(rechercher_un_point_du_contour_C2,VRAI)); DEFV(Float,INIT(X_P2_point_courant_interieur_,point_X)); DEFV(Float,INIT(Y_P2_point_courant_interieur_,point_Y)); DEFV(Float,INIT(X_C2_point_courant_du_contour,FLOT__UNDEF)); DEFV(Float,INIT(Y_C2_point_courant_du_contour,FLOT__UNDEF)); EGAL(X_C2_point_courant_du_contour,X_P2_point_courant_interieur_); EGAL(Y_C2_point_courant_du_contour,Y_P2_point_courant_interieur_); RECHERCHE_D_UN_POINT_DU_CONTOUR(C2); /* Tant qu'on est a l'interieur du 'contour_C2' on progresse sur la droite joignant le */ /* le point courant {X,Y} au centre de gravite du 'contour_C2'... */ begin_nouveau_block Bblock DEFV(Logical,INIT(rechercher_un_point_du_contour_C1,VRAI)); DEFV(Float,INIT(X_P1_point_courant_interieur_,FLOT__UNDEF)); DEFV(Float,INIT(Y_P1_point_courant_interieur_,FLOT__UNDEF)); DEFV(Float,INIT(X_C1_point_courant_du_contour,X_G1_centre_de_gravite_______)); DEFV(Float,INIT(Y_C1_point_courant_du_contour,Y_G1_centre_de_gravite_______)); DEFV(Float,INIT(pas_X__contour_C1,pas_X__contour_C2)); DEFV(Float,INIT(pas_Y__contour_C1,pas_Y__contour_C2)); /* Effectivement, les pas de parcours dans 'contour_C1' et 'contour_C2' sont egaux... */ DEFV(Float,INIT(distance_du_centre_de_gravite_au_contour__imageA_contour_C2,FLOT__UNDEF)); RECHERCHE_D_UN_POINT_DU_CONTOUR(C1); /* Tant qu'on est a l'interieur du 'contour_C1' on progresse sur la droite joignant le */ /* le point courant {X,Y} au centre de gravite du 'contour_C1' parallelement a ce qui a */ /* ete fait dans le 'contour_C2'... */ EGAL(distance_du_centre_de_gravite_au_contour__imageA_contour_C2 ,RdisF2D(X_G2_centre_de_gravite_______ ,Y_G2_centre_de_gravite_______ ,X_C2_point_courant_du_contour ,Y_C2_point_courant_du_contour ) ); Test(IZNE(distance_du_centre_de_gravite_au_contour__imageA_contour_C2)) Bblock DEFV(Float,INIT(module_du_deplacement ,SCAL(RdisF2D(X_G1_centre_de_gravite_______ ,Y_G1_centre_de_gravite_______ ,X_C1_point_courant_du_contour ,Y_C1_point_courant_du_contour ) ,distance_du_centre_de_gravite_au_contour__imageA_contour_C2 ,RdisF2D(X_G2_centre_de_gravite_______ ,Y_G2_centre_de_gravite_______ ,X_P2_point_courant_interieur_ ,Y_P2_point_courant_interieur_ ) ) ) ); DEFV(Float,INIT(angle_du_deplacement,ATAN(pas_Y__contour_C1,pas_X__contour_C1))); /* Caracteristiques du deplacement en module et en angle. */ EGAL(X_P1_point_courant_interieur_ ,ADD2(X_G1_centre_de_gravite_______ ,Xcartesienne_2D(module_du_deplacement,angle_du_deplacement) ) ); EGAL(Y_P1_point_courant_interieur_ ,ADD2(Y_G1_centre_de_gravite_______ ,Ycartesienne_2D(module_du_deplacement,angle_du_deplacement) ) ); /* Avec les notations suivantes : */ /* */ /* G2 : {X_G2_centre_de_gravite_______,Y_G2_centre_de_gravite_______} */ /* P2 : {X_P2_point_courant_interieur_,Y_P2_point_courant_interieur_} */ /* C2 : {X_C2_point_courant_du_contour,Y_C2_point_courant_du_contour} */ /* G1 : {X_G1_centre_de_gravite_______,Y_G1_centre_de_gravite_______} */ /* P1 : {X_P1_point_courant_interieur_,Y_P1_point_courant_interieur_} */ /* C1 : {X_C1_point_courant_du_contour,Y_C1_point_courant_du_contour} */ /* */ /* */ /* contour 1 contour 2 */ /* */ /* ------------------ ------------------ */ /* | | | | */ /* | | | | */ /* | + G1 | | + G2 | */ /* | / | | / | */ /* | |/ | | / | */ /* | +- P1 | | |/ | */ /* | / | | +- P2 | */ /* |/ | | / | */ /* C1 + | | / | */ /* | | | / | */ /* ------------------ ---+-------------- */ /* */ /* C2 */ /* */ /* */ /* On pose la relation de proportionnalite (concernant les modules des vecteurs) : */ /* */ /* G P G P */ /* 1 1 2 2 */ /* ------ = ------ */ /* G C G C */ /* 1 1 2 2 */ /* */ /* d'apres l'hypothese sur laquelle repose la methode utilisee : */ /* */ /* G C // G C */ /* 1 1 2 2 */ /* */ /* d'ou le calcul ci-dessus d'une translation amenant de P1 a P2... */ /* */ /* */ /* On notera le probleme numerique rencontre, par exemple, avec les valeurs suivantes : */ /* */ /* */ /* deplacement pasY Y(P1) */ /* */ /* (459.097442) x (-0.594682) = -273.01698500344 */ /* (458.095254) x (-0.596668) = -273.33077901367 */ /* (456.097219) x (-0.598664) = -273.04898551542 */ /* (455.095040) x (-0.600670) = -273.36193767680 */ /* (453.097041) x (-0.602685) = -273.07479015508 */ /* (452.094871) x (-0.604709) = -273.38583734754 */ /* (450.096910) x (-0.606744) = -273.09359956104 */ /* (449.094750) x (-0.608788) = -273.40349466300 */ /* (447.096827) x (-0.610842) = -273.10551999833 */ /* (446.094678) x (-0.612905) = -273.41365861959 */ /* (444.096795) x (-0.614979) = -273.11020289231 */ /* (443.094657) x (-0.617062) = -273.41687523773 */ /* (441.096815) x (-0.619155) = -273.10729849133 */ /* (440.094690) x (-0.621257) = -273.41190682533 */ /* (438.096890) x (-0.623370) = -273.09645831930 */ /* (437.094778) x (-0.625492) = -273.39928688078 */ /* (435.097021) x (-0.627624) = -273.07733270810 */ /* (434.094925) x (-0.629766) = -273.37822453755 */ /* (432.097213) x (-0.631918) = -273.05000664453 */ /* (431.095132) x (-0.634080) = -273.34880129856 */ /* (429.097465) x (-0.636251) = -273.01369120371 */ /* (428.095401) x (-0.638432) = -273.30980305123 */ /* (426.097782) x (-0.640623) = -272.96803939819 */ /* (425.095736) x (-0.642824) = -273.26174139846 */ /* (423.098166) x (-0.645035) = -272.91312550581 */ /* (422.096139) x (-0.647256) = -273.20425854458 */ /* (420.098619) x (-0.649486) = -272.84817165983 */ /* (419.096612) x (-0.651726) = -273.13615855231 */ /* (418.094608) x (-0.653976) = -273.42383936141 */ /* (416.097159) x (-0.656235) = -273.05751913636 */ /* */ /* */ /* soit (le 20120615074526) : */ /* */ /* */ /* deplacement > 0 pasY < 0 Y(P1) */ /* |pasY| > 0 */ /* */ /* |------------------------* |------------------------* |----------------* */ /* |-----------------------* |-----------------------* |---* */ /* |-----------------------* |----------------------* |---------------* */ /* |-----------------------* |---------------------* |-* */ /* |-----------------------* |--------------------* |--------------* */ /* |-----------------------* |-------------------* |* */ /* |-----------------------* |-------------------* |-------------* */ /* |-----------------------* |------------------* * */ /* |-----------------------* |-----------------* |------------* */ /* |-----------------------* |----------------* * */ /* |-----------------------* |---------------* |------------* */ /* |-----------------------* |--------------* * */ /* |-----------------------* |--------------* |------------* */ /* |----------------------* |-------------* * */ /* |----------------------* |------------* |-------------* */ /* |----------------------* |-----------* |* */ /* |----------------------* |----------* |--------------* */ /* |----------------------* |---------* |* */ /* |----------------------* |--------* |---------------* */ /* |----------------------* |-------* |--* */ /* |----------------------* |-------* |----------------* */ /* |----------------------* |------* |---* */ /* |----------------------* |-----* |------------------* */ /* |----------------------* |----* |------* */ /* |----------------------* |---* |---------------------* */ /* |---------------------* |--* |--------* */ /* |---------------------* |-* |------------------------* */ /* |---------------------* |* |-----------* */ /* |---------------------* * * */ /* |---------------------* * |--------------* */ /* */ /* */ /* ou l'on observe que, bien que les suites 'deplacement' et 'pasY' soient monotones (la */ /* premiere decroissante positive et la seconde decroissante negative, mais donc croissante */ /* en valeur absolue), la suite 'Y(P1)' est chaotique ! */ /* */ /* Ceci fut obtenu avec (evidemment en ajoutant ici des ordres d'impression des valeurs */ /* utiles) : */ /* */ /* */ /* :Debut_listG_Probleme_1__IFdeformation_de_passage_d_une_image_a_une_autre: */ /* */ /* $Z Std */ /* */ /* $Z $xci/format.01$X \ */ /* $Z A=$xiio/SPIRALE \ */ /* $Z $formatI \ */ /* $Z mode=1 \ */ /* $Z R=$xTV/SPIRALE \ */ /* $Z $formatR_Pal */ /* */ /* $Z Pal */ /* */ /* $Z $xci/complement$X \ */ /* $Z A=$xTV/SPIRALE \ */ /* $Z $formatI | \ */ /* $Z $xci/seuil$X \ */ /* $Z seuil=12 \ */ /* $Z $formatI | \ */ /* $Z $xci/acces$X \ */ /* $Z convertir=VRAI \ */ /* $Z $formatI | \ */ /* $Z $xci/normalise.01$X \ */ /* $Z R=$xTV/GRAND_RECTANGLE \ */ /* $Z $formatI */ /* */ /* $Z $xci/complement$X \ */ /* $Z A=$xTV/SPIRALE \ */ /* $Z $formatI | \ */ /* $Z $xci/seuil$X \ */ /* $Z seuil=128 \ */ /* $Z $formatI | \ */ /* $Z $xci/acces$X \ */ /* $Z convertir=VRAI \ */ /* $Z $formatI | \ */ /* $Z $xci/normalise.01$X \ */ /* $Z R=$xTV/PETIT_RECTANGLE \ */ /* $Z $formatI */ /* */ /* $Z $xci/GenDeform.01$X \ */ /* $Z C1=$xTV/GRAND_RECTANGLE \ */ /* $Z C2=$xTV/PETIT_RECTANGLE \ */ /* $Z dX=$xTV/DEFORMATION$COORD_X \ */ /* $Z dY=$xTV/DEFORMATION$COORD_Y \ */ /* $Z $formatI */ /* */ /* :Fin_listG_Probleme_1__IFdeformation_de_passage_d_une_image_a_une_autre: */ /* */ /* */ /* en notant que le code precedent etait alors en fait (et par erreur) : */ /* */ /* EGAL(X_P1_point_courant_interieur_ */ /* ,ADD2(X_G1_centre_de_gravite_______ */ /* ,MUL2(module_du_deplacement,pas_X__contour_C1) */ /* ) */ /* ); */ /* EGAL(Y_P1_point_courant_interieur_ */ /* ,ADD2(Y_G1_centre_de_gravite_______ */ /* ,MUL2(module_du_deplacement,pas_Y__contour_C1) */ /* ) */ /* ); */ /* */ /* */ /* On notera qu'un probleme similaire avait ete mis en evidence il y a plusieurs annees */ /* dans 'v $xiii/pent_image$FON Petit.probleme'... */ /* */ /* */ /* Le 20120618103427, avec le "bon" code pour 'X_P1_point_courant_interieur_' et */ /* 'Y_P1_point_courant_interieur_', on trouve toujours le meme phenomene : */ /* */ /* */ /* deplacement angle X(P1) Y(P1) */ /* */ /* {459.097442,3.778463} = {21.449285,15.028486} */ /* {458.095254,3.780936} = {22.929738,14.714641} */ /* {456.097219,3.783425} = {25.211686,14.996560} */ /* {455.095040,3.785931} = {26.698312,14.683899} */ /* {453.097041,3.788454} = {28.983454,14.971037} */ /* {452.094871,3.790993} = {30.476326,14.659675} */ /* {450.096910,3.793550} = {32.764676,14.952187} */ /* {449.094750,3.796124} = {34.263868,14.642244} */ /* {447.096827,3.798716} = {36.555436,14.940290} */ /* {446.094678,3.801325} = {38.061021,14.631890} */ /* {444.096795,3.803951} = {40.355816,14.935637} */ /* {443.094657,3.806596} = {41.867865,14.628911} */ /* {441.096815,3.809258} = {44.165893,14.938528} */ /* {440.094690,3.811939} = {45.684478,14.633610} */ /* {438.096890,3.814638} = {47.985743,14.949274} */ /* {437.094778,3.817355} = {49.510933,14.646304} */ /* {435.097021,3.820090} = {51.815436,14.968197} */ /* {434.094925,3.822845} = {53.347299,14.667320} */ /* {432.097213,3.825618} = {55.655038,14.995628} */ /* {431.095132,3.828410} = {57.193641,14.696998} */ /* {429.097465,3.831222} = {59.504610,15.031914} */ /* {428.095401,3.834052} = {61.050019,14.735685} */ /* {426.097782,3.836903} = {63.364210,15.077409} */ /* {425.095736,3.839772} = {64.916488,14.783746} */ /* {423.098166,3.842662} = {67.233888,15.132482} */ /* {422.096139,3.845571} = {68.793095,14.841553} */ /* {420.098619,3.848501} = {71.113689,15.197512} */ /* {419.096612,3.851450} = {72.679884,14.909494} */ /* {418.094608,3.854421} = {74.250567,14.621884} */ /* {416.097159,3.857411} = {76.576890,14.987967} */ /* */ /* */ /* avec : */ /* */ /* G1=(390.545621,288.045621) */ /* */ /* soit : */ /* */ /* */ /* deplacement angle X(P1) Y(P1) */ /* */ /* |----------------* * * |-----------* */ /* |---------------* * * |-* */ /* |--------------* |* |* |----------* */ /* |--------------* |* |* |* */ /* |-------------* |-* |-* |---------* */ /* |-------------* |-* |-* |* */ /* |------------* |--* |--* |--------* */ /* |------------* |--* |--* * */ /* |-----------* |---* |---* |--------* */ /* |----------* |---* |----* * */ /* |----------* |----* |----* |--------* */ /* |---------* |-----* |-----* * */ /* |--------* |-----* |------* |--------* */ /* |--------* |------* |------* * */ /* |-------* |------* |-------* |--------* */ /* |-------* |-------* |-------* * */ /* |------* |-------* |--------* |---------* */ /* |------* |--------* |--------* |* */ /* |-----* |---------* |---------* |----------* */ /* |----* |---------* |----------* |-* */ /* |----* |----------* |----------* |-----------* */ /* |---* |----------* |-----------* |--* */ /* |--* |-----------* |-----------* |------------* */ /* |--* |------------* |------------* |---* */ /* |-* |------------* |-------------* |--------------* */ /* |-* |-------------* |-------------* |-----* */ /* |* |--------------* |--------------* |----------------* */ /* |* |--------------* |--------------* |-------* */ /* * |---------------* |---------------* * */ /* * |----------------* |----------------* |---------* */ /* */ /* */ /* ou l'on observe que la coordonnee 'X(P1)' est monotone, alors que la coordonnee 'Y(P1)' */ /* a un comportement chaotique. Le programme 'v $xtc/GenDeform.01$c' montre qu'evidemment */ /* si l'on interpole lineairement dans [459.097442,416.097159] et [3.778463,3.857411] */ /* pour le deplacement et l'angle respectivement le chaos disparait. Ce sont donc bien */ /* les petites variations aleatoires par rapport a la "regularite" qui provoquent cela... */ /* Alors pourquoi 'Y(P1)' est chaotique et 'X(P1)' monotone ? En fait, cela peut etre */ /* l'inverse ainsi que le montre 'v $xtc/GenDeform.01$c PHASE' ; en effet, lorsque cette */ /* 'PHASE' est egale a -pi/2 c'est effectivement l'inverse. Ainsi l'exemple ci-dessus */ /* n'est qu'un cas particulier et a d'autres endroits de l'image on doit donc rencontrer */ /* d'autres situations... */ /* */ /* Aux environs du 20120619112211, il semblerait que 'arrondir_point_courant_du_contour_C12' */ /* ameliore grandement les choses... */ EGAL(X_P1_point_courant_interieur_ ,ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir_point_courant_interieur___P1 ,X_P1_point_courant_interieur_ ) ); EGAL(Y_P1_point_courant_interieur_ ,ARRONDI_EVENTUEL_DES_COORDONNEES(arrondir_point_courant_interieur___P1 ,Y_P1_point_courant_interieur_ ) ); /* Introduit le 20120619085812, pour voir... */ Test(IL_FAUT(IFdeformation_de_passage_d_une_image_a_une_autre_____lister_les_coordonnees_utiles)) /* Test introduit le 20120618154406... */ Bblock DEFV(Logical,INIT(au_moins_un_couple_de_coordonees_a_ete_editee,FAUX)); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(G1 ,"G1={%.^^^,%.^^^}" ,X_G1_centre_de_gravite_______ ,Y_G1_centre_de_gravite_______ ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(G2 ,"G2={%.^^^,%.^^^}" ,X_G2_centre_de_gravite_______ ,Y_G2_centre_de_gravite_______ ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(XY ,"{X,Y}={%d,%d}" ,X ,Y ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(C1 ,"C1={%.^^^,%.^^^}" ,X_C1_point_courant_du_contour ,Y_C1_point_courant_du_contour ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(C2 ,"C2={%.^^^,%.^^^}" ,X_C2_point_courant_du_contour ,Y_C2_point_courant_du_contour ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(pas ,"pas={%.^^^,%.^^^}" ,pas_X__contour_C1 ,pas_Y__contour_C1 ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(similitude ,"similitude={%.^^^,%.^^^}" ,module_du_deplacement ,angle_du_deplacement ," " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(P2 ,"P2={%.^^^,%.^^^}" ,X_P2_point_courant_interieur_ ,Y_P2_point_courant_interieur_ ," --> " ); EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES(P1 ,"P1={%.^^^,%.^^^}" ,X_P1_point_courant_interieur_ ,Y_P1_point_courant_interieur_ ,C_VIDE ); Test(EST_VRAI(au_moins_un_couple_de_coordonees_a_ete_editee)) /* Test introduit le 20120618180915... */ Bblock CALS(Fsauts_de_lignes(UN)); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes begin_nouveau_block Bblock DEFV(genere_Float,INIT(deformation_X_courante ,SOUS(_____cNORMALISE_OX(X_P1_point_courant_interieur_) ,_____cNORMALISE_OX(X_P2_point_courant_interieur_) ) ) ); DEFV(genere_Float,INIT(deformation_Y_courante ,SOUS(_____cNORMALISE_OY(Y_P1_point_courant_interieur_) ,_____cNORMALISE_OY(Y_P2_point_courant_interieur_) ) ) ); /* Cette operation 'P1-P2' permet de garantir la conservation de l'orientation d'une image */ /* si le resultat {imageR_deformation_X,imageR_deformation_Y} est utilise, pour celle-ci, */ /* dans 'v $xci/deformi.01$K', par exemple, pour faire un zoom... */ storeF_point(deformation_X_courante ,imageR_deformation_X ,X,Y ); storeF_point(deformation_Y_courante ,imageR_deformation_Y ,X,Y ); EGAL(minimum_deformation_X_courante,MIN2(minimum_deformation_X_courante,deformation_X_courante)); EGAL(maximum_deformation_X_courante,MAX2(maximum_deformation_X_courante,deformation_X_courante)); EGAL(minimum_deformation_Y_courante,MIN2(minimum_deformation_Y_courante,deformation_Y_courante)); EGAL(maximum_deformation_Y_courante,MAX2(maximum_deformation_Y_courante,deformation_Y_courante)); /* Le calcul des extrema de la deformation a ete introduit le 20120620104755. */ Eblock end_nouveau_block Eblock ATes Bblock Eblock ETes Eblock end_nouveau_block Eblock end_nouveau_block Eblock ATes Bblock Eblock ETes Eblock end_image begin_nouveau_block Bblock #define EPSILON_DU_DEPLACEMENT_NON_DEFINI_EN_X \ DIVI(SOUS(maximum_deformation_X_courante,minimum_deformation_X_courante),F_PETIT_INFINI) #define EPSILON_DU_DEPLACEMENT_NON_DEFINI_EN_Y \ DIVI(SOUS(maximum_deformation_Y_courante,minimum_deformation_Y_courante),F_PETIT_INFINI) DEFV(genere_Float,INIT(deplacement_non_defini_en_X ,SOUS(minimum_deformation_X_courante,EPSILON_DU_DEPLACEMENT_NON_DEFINI_EN_X) ) ); DEFV(genere_Float,INIT(deplacement_non_defini_en_Y ,SOUS(minimum_deformation_Y_courante,EPSILON_DU_DEPLACEMENT_NON_DEFINI_EN_Y) ) ); /* Ainsi, les deplacements non definis vont etre faciles a reperer puisqu'ils vont */ /* correspondre aux nouveaux minima eux-memes egaux aux minima courants auxquels est */ /* retranche un "epsilon"... */ #undef EPSILON_DU_DEPLACEMENT_NON_DEFINI_EN_Y #undef EPSILON_DU_DEPLACEMENT_NON_DEFINI_EN_X begin_image Bblock Test(IFOU(IFEQ(loadF_point(imageR_deformation_X,X,Y),DEPLACEMENT_NON_DEFINI_EN_X_ET_EN_Y) ,IFEQ(loadF_point(imageR_deformation_Y,X,Y),DEPLACEMENT_NON_DEFINI_EN_X_ET_EN_Y) ) ) Bblock storeF_point(deplacement_non_defini_en_X ,imageR_deformation_X ,X,Y ); storeF_point(deplacement_non_defini_en_Y ,imageR_deformation_Y ,X,Y ); /* Ainsi, les deplacements non definis vont etre faciles a reperer puisqu'ils vont */ /* correspondre aux nouveaux minima respectifs (introduit le 20120620104755). On notera */ /* au passage que si ensuite les deux champs {imageR_deformation_X,imageR_deformation_Y} */ /* sont renormalises, alors les deplacements non definis seront representes par des */ /* valeurs nulles ('v $xiirv/$Fnota ignorer_diX_diY.VRAI')... */ Eblock ATes Bblock Eblock ETes Eblock end_image Eblock end_nouveau_block RETU_ERROR; Eblock #undef EDITION_EVENTUELLE_D_UN_COUPLE_DE_COORDONNEES #undef RECHERCHE_D_UN_POINT_DU_CONTOUR #undef ACCES_POINT #undef CALCUL_DU_CENTRE_DE_GRAVITE #undef point_Y #undef point_X #undef ARRONDI_EVENTUEL_DES_COORDONNEES #undef arrondir_point_courant_du_contour_C12 #undef arrondir_point_courant_interieur___P1 #undef arrondir_centre_de_gravite________G12 #undef DEPLACEMENT_NON_DEFINI_EN_X_ET_EN_Y #undef DEPLACEMENT_NUL_EN_X_ET_EN_Y #undef IFGT_IFGE EFonctionI /* ATTENTION : c'est bien 'FonctionI' (et non pas 'FonctionF') a cause du 'RETU_ERROR'... */ _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L I C A T I O N E T C U M U L D E T R O I S I M A G E S " S T A N D A R D S " : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Imultiplication_et_cumul_avec_renormalisation(imageR,imageAA,imageAX,imageAB)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=imageAA*imageAX+imageAB. */ DEFV(Argument,DEFV(image,imageAA)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageAX)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageAB)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock BDEFV(imageF,produit_cumul_flottant); /* Image intermediaire flottante avant renormalisation... */ /*..............................................................................................................................*/ begin_image Bblock storeF_point(AXPB(______NORMALISE_NIVEAU(load_point(imageAA,X,Y)) ,______NORMALISE_NIVEAU(load_point(imageAX,X,Y)) ,______NORMALISE_NIVEAU(load_point(imageAB,X,Y)) ) ,produit_cumul_flottant ,X,Y ); Eblock end_image CALS(Ifloat_std_avec_renormalisation(imageR,produit_cumul_flottant)); /* Et renormalisation du produit-cumul... */ EDEFV(imageF,produit_cumul_flottant); /* Image intermediaire flottante avant renormalisation... */ RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L I C A T I O N E T C U M U L D E T R O I S I M A G E S " F L O T T A N T E S " : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFmultiplication_et_cumul_avec_renormalisation(imageR,imageAA,imageAX,imageAB)))) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=imageAA*imageAX+imageAB. */ DEFV(Argument,DEFV(imageF,imageAA)); /* Premiere image Argument, */ DEFV(Argument,DEFV(imageF,imageAX)); /* Seconde image Argument, */ DEFV(Argument,DEFV(imageF,imageAB)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock storeF_point(AXPB(loadF_point(imageAA,X,Y) ,loadF_point(imageAX,X,Y) ,loadF_point(imageAB,X,Y) ) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* ' O R ' L O G I Q U E D E T R O I S I M A G E S : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ior3(imageR,imageA1,imageA2,imageA3)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=imageA1+imageA2+imageA3. */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock store_point(OUI03(load_point(imageA1,X,Y) ,load_point(imageA2,X,Y) ,load_point(imageA3,X,Y) ) ,imageR ,X,Y ,FVARIABLE ); Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M I N I M U M D E T R O I S I M A G E S : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Iminimum3(imageR,imageA1,imageA2,imageA3)))) /* Fonction introduite le 20060710150428... */ DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=MIN3(imageA1,imageA2,imageA3). */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock store_point(MIN3(load_point(imageA1,X,Y) ,load_point(imageA2,X,Y) ,load_point(imageA3,X,Y) ) ,imageR ,X,Y ,FVARIABLE ); Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M I N I M U M D E T R O I S I M A G E S F L O T T A N T E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFminimum3(imageR,imageA1,imageA2,imageA3)))) /* Fonction introduite le 20060710150428... */ DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=MIN3(imageA1,imageA2,imageA3). */ DEFV(Argument,DEFV(imageF,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(imageF,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(imageF,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock storeF_point(MIN3(loadF_point(imageA1,X,Y) ,loadF_point(imageA2,X,Y) ,loadF_point(imageA3,X,Y) ) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A X I M U M D E T R O I S I M A G E S : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Imaximum3(imageR,imageA1,imageA2,imageA3)))) /* Fonction introduite le 20060710150428... */ DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=MAX3(imageA1,imageA2,imageA3). */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock store_point(MAX3(load_point(imageA1,X,Y) ,load_point(imageA2,X,Y) ,load_point(imageA3,X,Y) ) ,imageR ,X,Y ,FVARIABLE ); Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A X I M U M D E T R O I S I M A G E S F L O T T A N T E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFmaximum3(imageR,imageA1,imageA2,imageA3)))) /* Fonction introduite le 20060710150428... */ DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=MAX3(imageA1,imageA2,imageA3). */ DEFV(Argument,DEFV(imageF,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(imageF,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(imageF,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock storeF_point(MAX3(loadF_point(imageA1,X,Y) ,loadF_point(imageA2,X,Y) ,loadF_point(imageA3,X,Y) ) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A D D I T I O N D E T R O I S I M A G E S A V E C R E N O R M A L I S A T I O N : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Iaddition3_avec_renormalisation(imageR,imageA1,imageA2,imageA3)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=imageA1+imageA2+imageA3. */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock BDEFV(imageF,somme_flottante); /* Image intermediaire flottante avant renormalisation... */ /*..............................................................................................................................*/ begin_image Bblock storeF_point(ADD3(FLOT(NIVR(load_point(imageA1,X,Y))) ,FLOT(NIVR(load_point(imageA2,X,Y))) ,FLOT(NIVR(load_point(imageA3,X,Y))) ) ,somme_flottante ,X,Y ); Eblock end_image CALS(Ifloat_std_avec_renormalisation(imageR,somme_flottante)); /* Et renormalisation de la somme... */ EDEFV(imageF,somme_flottante); /* Image intermediaire flottante avant renormalisation... */ RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A D D I T I O N F L O T T A N T E D E T R O I S I M A G E S F L O T T A N T E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFaddition3(imageR,imageA1,imageA2,imageA3)))) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=imageA1+imageA2+imageA3. */ DEFV(Argument,DEFV(imageF,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(imageF,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(imageF,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock storeF_point(ADD3(loadF_point(imageA1,X,Y) ,loadF_point(imageA2,X,Y) ,loadF_point(imageA3,X,Y) ) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A D D I T I O N P O N D E R E E D E T R O I S I M A G E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFaddition3_ponderee(imageR,alpha,imageA1,beta_,imageA2,gamma,imageA3)))) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=(alpha*imageA1)+(beta*imageA2)+(gamma*imageA3). */ DEFV(Argument,DEFV(Float,alpha)); /* Premier coefficient de ponderation, */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(Float,beta_)); /* Second coefficient de ponderation, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(Float,gamma)); /* Troisieme coefficient de ponderation, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock storeF_point(LIZ3(alpha,FLOT(NIVR(load_point(imageA1,X,Y))) ,beta_,FLOT(NIVR(load_point(imageA2,X,Y))) ,gamma,FLOT(NIVR(load_point(imageA3,X,Y))) ) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* A D D I T I O N P O N D E R E E " F L O U E " D E T R O I S I M A G E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFaddition3_ponderee_floue(imageR,alpha,imageA1,beta_,imageA2,gamma,imageA3)))) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=MAX3(alpha*imageA1,beta*imageA2,gamma*imageA3). */ DEFV(Argument,DEFV(Float,alpha)); /* Premier coefficient de ponderation, */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(Float,beta_)); /* Second coefficient de ponderation, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(Float,gamma)); /* Troisieme coefficient de ponderation, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock DEFV(Float,INIT(niveau1,MUL2(alpha,FLOT(NIVR(load_point(imageA1,X,Y)))))); DEFV(Float,INIT(niveau2,MUL2(beta_,FLOT(NIVR(load_point(imageA2,X,Y)))))); DEFV(Float,INIT(niveau3,MUL2(gamma,FLOT(NIVR(load_point(imageA3,X,Y)))))); /* Pour ne pas "fatiguer" les compilateurs... */ storeF_point(MAX3(niveau1,niveau2,niveau3) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L I C A T I O N D E T R O I S I M A G E S A V E C R E N O R M A L I S A T I O N : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Imultiplication3_avec_renormalisation(imageR,imageA1,imageA2,imageA3)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=imageA1*imageA2*imageA3. */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock BDEFV(imageF,produit_flottant); /* Image intermediaire flottante avant renormalisation... */ /*..............................................................................................................................*/ begin_image Bblock storeF_point(MUL3(FLOT(NIVR(load_point(imageA1,X,Y))) ,FLOT(NIVR(load_point(imageA2,X,Y))) ,FLOT(NIVR(load_point(imageA3,X,Y))) ) ,produit_flottant ,X,Y ); Eblock end_image CALS(Ifloat_std_avec_renormalisation(imageR,produit_flottant)); /* Et renormalisation du produit... */ EDEFV(imageF,produit_flottant); /* Image intermediaire flottante avant renormalisation... */ RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L I C A T I O N F L O T T A N T E D E T R O I S I M A G E S F L O T T A N T E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFmultiplication3(imageR,imageA1,imageA2,imageA3)))) DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=imageA1*imageA2*imageA3. */ DEFV(Argument,DEFV(imageF,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(imageF,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(imageF,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock storeF_point(MUL3(loadF_point(imageA1,X,Y) ,loadF_point(imageA2,X,Y) ,loadF_point(imageA3,X,Y) ) ,imageR ,X,Y ); Eblock end_image RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E D E D E U X I M A G E S S U I V A N T U N M A S Q U E : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Imultiplexage(imageR,imageA1,masque,imageA2)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : */ /* */ /* imageR[X][Y]=imageA1[X][Y] si masque[X][Y]=BLANC, et */ /* =imageA2[X][Y] si masque[X][Y]=NOIR. */ /* */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument. */ DEFV(Argument,DEFV(image,masque)); /* Image binaire (NOIR/BLANC) donnant les points a prelever dans */ /* 'imageA1' ('BLANC') et dans 'imageA2' ('NOIR'). */ DEFV(Argument,DEFV(image,imageA2)); /* Deuxieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock DEFV(genere_p,INIT(aiguillage,NIVEAU_UNDEF)); /* Valeur courante du masque binaire. */ EGAL(aiguillage,load_point(masque,X,Y)); Test(IFEQ(aiguillage,BLANC)) Bblock store_point(load_point(imageA1,X,Y),imageR,X,Y,FVARIABLE); Eblock ATes Bblock Eblock ETes Test(IFEQ(aiguillage,NOIR)) Bblock store_point(load_point(imageA2,X,Y),imageR,X,Y,FVARIABLE); Eblock ATes Bblock Eblock ETes Test(IFET(IFNE(aiguillage,BLANC),IFNE(aiguillage,NOIR))) Bblock PRINT_ERREUR("le masque binaire contient des valeurs autres que 'NOIR' et 'BLANC'") store_point(NIVEAU_UNDEF,imageR,X,Y,FVARIABLE); Eblock ATes Bblock Eblock ETes Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N T E R P O L A T I O N E N T R E T R O I S I M A G E S : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(Logical,SINT(Iinterpolation_barycentrique_____verifier_la_somme_des_ponderations,VRAI))); /* Introduit le 20090630101549 par symetrie avec 'IFinterpolation_barycentrique(...)'. */ DEFV(Common,DEFV(Logical,SINT(Iinterpolation_barycentrique_____eviter_l_apparition_du_NOIR,FAUX))); /* Introduit le 20090529132030 pour eviter que du 'NOIR' apparaisse, par exemple, avec */ /* des ponderations trop faibles... */ DEFV(Common,DEFV(FonctionP,POINTERp(Iinterpolation_barycentrique(imageR,alpha,imageA1,beta_,imageA2,gamma,imageA3)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=alpha*imageA1 + beta*imageA2 + gamma*imageA3. */ DEFV(Argument,DEFV(Float,alpha)); /* Premier coefficient d'interpolation, */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument. */ DEFV(Argument,DEFV(Float,beta_)); /* Second coefficient d'interpolation, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument. */ DEFV(Argument,DEFV(Float,gamma)); /* Troisieme coefficient d'interpolation, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ Test(IL_FAUT(Iinterpolation_barycentrique_____verifier_la_somme_des_ponderations)) /* Test introduit le 20090630101549... */ Bblock Test(IFOU(IFLE(ADD3(alpha,beta_,gamma),FZERO),IFGT(ADD3(alpha,beta_,gamma),FU))) Bblock PRINT_ATTENTION("interpolation_barycentrique : alpha + beta + gamma n'est pas dans ]0,1]") CAL1(Prer4("(%g + %g + %g = %g)\n",alpha,beta_,gamma,ADD3(alpha,beta_,gamma))); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes begin_image Bblock DEFV(Float,INIT(combinaison_lineaire_precise ,NIVA(INTERPOLATION_BARYCENTRIQUE(alpha,FLOT(NIVR(load_point(imageA1,X,Y))) ,beta_,FLOT(NIVR(load_point(imageA2,X,Y))) ,gamma,FLOT(NIVR(load_point(imageA3,X,Y))) ) ) ) ); DEFV(genere_p,INIT(niveau_resultant,NIVEAU_UNDEF)); EGAL(niveau_resultant,GENP(TRNP(combinaison_lineaire_precise))); /* Conversion... */ Test(IL_FAUT(Iinterpolation_barycentrique_____eviter_l_apparition_du_NOIR)) Bblock Test(IFET(IFEQ(niveau_resultant,NOIR),IZGT(combinaison_lineaire_precise))) Bblock EGAL(niveau_resultant,NOIR_PLANCHER); /* Le 20090529132030 a ete introduit cette possibilite suite a des experiences ayant mis */ /* en evidence le probleme 'v $xci/cache.21$Z 20090529113226'. */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes store_point(niveau_resultant ,imageR ,X,Y ,FVARIABLE ); /* Rangement du resultat de l'interpolation barycentrique. */ Eblock end_image RETI(imageR); Eblock EFonctionP /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E L A L U M I N A N C E D ' U N T R I P L E T ( R , V , B ) : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(Logical,SINT(Iluminance_____eviter_l_apparition_du_NOIR,FAUX))); /* Introduit le 20090529132030 pour eviter que du 'NOIR' apparaisse, par exemple, avec */ /* des ponderations trop faibles... */ DEFV(Common,DEFV(FonctionP,POINTERp(Iluminance(imageR,imageA_ROUGE,imageA_VERTE,imageA_BLEUE)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=luminance(imageA_ROUGE,imageA_VERTE,imageA_BLEUE). */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Premiere image Argument (representant la composante ROUGE), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Seconde image Argument (representant la composante VERTE), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Troisieme image Argument (representant la composante BLEUE). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ BSaveModifyVariable(Logical ,Iinterpolation_barycentrique_____eviter_l_apparition_du_NOIR ,Iluminance_____eviter_l_apparition_du_NOIR ); CALS(Iinterpolation_barycentrique(imageR ,LUMINANCE_DU_ROUGE,imageA_ROUGE ,LUMINANCE_DU_VERTE,imageA_VERTE ,LUMINANCE_DU_BLEUE,imageA_BLEUE ) ); /* On notera le 20210514180713 que l'on n'utilise pas 'CALCUL_DE_LA_LUMINANCE(...)' (qui */ /* devrait donc etre ici dans une structure {begin_image,end_image}) pour des raisons */ /* mysterieuses... */ ESaveModifyVariable(Logical ,Iinterpolation_barycentrique_____eviter_l_apparition_du_NOIR ); RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N T E R P O L A T I O N E N T R E T R O I S I M A G E S " F L O T T A N T E S " : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Logical,SINT(IFinterpolation_barycentrique_____verifier_la_somme_des_ponderations,VRAI))); /* Introduit le 20090630101549 pour 'v $xrs/rotate3D.01$Z Fverifier_somme_ponderations'. */ DEFV(Common,DEFV(Logical,SINT(IFinterpolation_barycentrique_____utiliser_l_arithmetique_etendue_au_lieu_de_l_arithmetique_de_base ,FAUX ) ) ); /* Introduit le 20090629151934... */ DEFV(Common,DEFV(FonctionF,POINTERF(IFinterpolation_barycentrique(imageR,alpha,imageA1,beta_,imageA2,gamma,imageA3)))) /* Fonction introduite le 20031110165005. */ DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=alpha*imageA1 + beta*imageA2 + gamma*imageA3. */ DEFV(Argument,DEFV(Float,alpha)); /* Premier coefficient d'interpolation, */ DEFV(Argument,DEFV(imageF,imageA1)); /* Premiere image Argument. */ DEFV(Argument,DEFV(Float,beta_)); /* Second coefficient d'interpolation, */ DEFV(Argument,DEFV(imageF,imageA2)); /* Seconde image Argument. */ DEFV(Argument,DEFV(Float,gamma)); /* Troisieme coefficient d'interpolation, */ DEFV(Argument,DEFV(imageF,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ Test(IL_FAUT(IFinterpolation_barycentrique_____verifier_la_somme_des_ponderations)) /* Test introduit le 20090630101549... */ Bblock Test(IFOU(IFLE(ADD3(alpha,beta_,gamma),FZERO),IFGT(ADD3(alpha,beta_,gamma),FU))) Bblock PRINT_ATTENTION("interpolation_barycentrique : alpha + beta + gamma n'est pas dans ]0,1]") CAL1(Prer4("(%g + %g + %g = %g)\n",alpha,beta_,gamma,ADD3(alpha,beta_,gamma))); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes begin_image Bblock DEFV(genere_Float,INIT(niveau_imageA1,loadF_point(imageA1,X,Y))); DEFV(genere_Float,INIT(niveau_imageA2,loadF_point(imageA2,X,Y))); DEFV(genere_Float,INIT(niveau_imageA3,loadF_point(imageA3,X,Y))); /* Niveaux courants des images Arguments evalues a l'exterieur de la procedure */ /* 'USs_GooF______CONDITIONNEL(...)' pour des raisons evidentes de "simplification" et */ /* d'evitement d'appication du 'GooF' a autre chose... */ DEFV(genere_Float,INIT(niveau_imageR,FLOT__NIVEAU_UNDEF)); /* Niveau Resultat... */ #define IFinterpolation_bary_____utiliser_l_arithmetique_etendue_au_lieu_de_l_arithmetique_de_base \ IFinterpolation_barycentrique_____utiliser_l_arithmetique_etendue_au_lieu_de_l_arithmetique_de_base \ /* Pour raccourcir la ligne suivante... */ USs_GooF______CONDITIONNEL(IFinterpolation_bary_____utiliser_l_arithmetique_etendue_au_lieu_de_l_arithmetique_de_base /* Possibilite introduite le 20090629151934... */ ,BLOC( Bblock EGAL(niveau_imageR ,INTERPOLATION_BARYCENTRIQUE(alpha,niveau_imageA1 ,beta_,niveau_imageA2 ,gamma,niveau_imageA3 ) ); Eblock ) ); #undef IFinterpolation_bary_____utiliser_l_arithmetique_etendue_au_lieu_de_l_arithmetique_de_base storeF_point(niveau_imageR ,imageR ,X,Y ); /* Rangement du resultat de l'interpolation barycentrique. */ Eblock end_image RETIF(imageR); Eblock EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E L A L U M I N A N C E D ' U N T R I P L E T ( R , V , B ) : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(FonctionF,POINTERF(IFluminance(imageR,imageA_ROUGE,imageA_VERTE,imageA_BLEUE)))) /* Fonction introduite le 20031110165005. */ DEFV(Argument,DEFV(imageF,imageR)); /* Image Resultat, telle que : imageR=luminance(imageA_ROUGE,imageA_VERTE,imageA_BLEUE). */ DEFV(Argument,DEFV(imageF,imageA_ROUGE)); /* Premiere image Argument (representant la composante ROUGE), */ DEFV(Argument,DEFV(imageF,imageA_VERTE)); /* Seconde image Argument (representant la composante VERTE), */ DEFV(Argument,DEFV(imageF,imageA_BLEUE)); /* Troisieme image Argument (representant la composante BLEUE). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ CALS(IFinterpolation_barycentrique(imageR ,LUMINANCE_DU_ROUGE,imageA_ROUGE ,LUMINANCE_DU_VERTE,imageA_VERTE ,LUMINANCE_DU_BLEUE,imageA_BLEUE ) ); /* On notera le 20210514180713 que l'on n'utilise pas 'CALCUL_DE_LA_LUMINANCE(...)' (qui */ /* devrait donc etre ici dans une structure {begin_image,end_image}) pour des raisons */ /* mysterieuses... */ RETIF(imageR); Eblock EFonctionF _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E D E S F A U S S E S A U X V R A I E S C O U L E U R S : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Ivraies_couleurs(imageR_ROUGE,imageR_VERTE,imageR_BLEUE ,imageA ,generer_l_image_ROUGE,generer_l_image_VERTE,generer_l_image_BLEUE ,increment_des_niveaux ,translater_le_NOIR ) ) ) DEFV(Argument,DEFV(image,imageR_ROUGE)); /* Image Resultat-ROUGE, telle que : imageR_ROUGE=R(imageA), */ DEFV(Argument,DEFV(image,imageR_VERTE)); /* Image Resultat-VERTE, telle que : imageR_VERTE=V(imageA), */ DEFV(Argument,DEFV(image,imageR_BLEUE)); /* Image Resultat-BLEUE, telle que : imageR_BLEUE=B(imageA), */ /* le passage des "fausses" aux "vraies" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(image,imageA)); /* Image Argument, telle qu'elle est consideree en fausse couleurs. */ DEFV(Argument,DEFV(Logical,generer_l_image_ROUGE)); /* Indique s'il faut extraire la composante ROUGE ('VRAI') ou pas ('FAUX'), */ DEFV(Argument,DEFV(Logical,generer_l_image_VERTE)); /* Indique s'il faut extraire la composante VERTE ('VRAI') ou pas ('FAUX'), */ DEFV(Argument,DEFV(Logical,generer_l_image_BLEUE)); /* Indique s'il faut extraire la composante BLEUE ('VRAI') ou pas ('FAUX'). */ DEFV(Argument,DEFV(Int,increment_des_niveaux)); /* Increment du niveau courant dans [NOIR,BLANC] afin de pouvoir simuler un decalage de */ /* palette (voir 'IXpalette(...)' dans '$xiidX'). */ DEFV(Argument,DEFV(Logical,translater_le_NOIR)); /* Indique si le niveau 'NOIR' est translatable ('LE_NOIR_EST_TRANSLATABLE') ou pas */ /* ('LE_NOIR_N_EST_PAS_TRANSLATABLE')... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ PUSH_FILTRAGE; /* Sauvegarde de l'etat courant du filtrage des niveaux. */ SET_FILTRAGE(ACTIF); /* On autorise tous les filtrages afin d'avoir la 'SUBSTITUTION'. */ PUSH_SUBSTITUTION; /* Sauvegarde de la substitution courante. */ Test(IL_FAUT(generer_l_image_ROUGE)) Bblock SUBSTITUTION(L_SUBSTITUTION_ROUGE); CALS(Imove_avec_rotation_des_niveaux(imageR_ROUGE,imageA,increment_des_niveaux,translater_le_NOIR)); /* Generation de la composante ROUGE, */ Eblock ATes Bblock Eblock ETes Test(IL_FAUT(generer_l_image_VERTE)) Bblock SUBSTITUTION(L_SUBSTITUTION_VERTE); CALS(Imove_avec_rotation_des_niveaux(imageR_VERTE,imageA,increment_des_niveaux,translater_le_NOIR)); /* Generation de la composante VERTE, */ Eblock ATes Bblock Eblock ETes Test(IL_FAUT(generer_l_image_BLEUE)) Bblock SUBSTITUTION(L_SUBSTITUTION_BLEUE); CALS(Imove_avec_rotation_des_niveaux(imageR_BLEUE,imageA,increment_des_niveaux,translater_le_NOIR)); /* Generation de la composante BLEUE, */ Eblock ATes Bblock Eblock ETes PULL_SUBSTITUTION; PULL_FILTRAGE; /* Et restauration des conditions initiales... */ RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E D E S F A U S S E S C O U L E U R S */ /* A D E S V R A I E S C O U L E U R S A L E A T O I R E S : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(Float,SINT(Ivraies_couleurs_aleatoires_____luminance_du_ROUGE,LUMINANCE_DU_ROUGE))); DEFV(Common,DEFV(Float,SINT(Ivraies_couleurs_aleatoires_____luminance_du_VERTE,LUMINANCE_DU_VERTE))); DEFV(Common,DEFV(Float,SINT(Ivraies_couleurs_aleatoires_____luminance_du_BLEUE,LUMINANCE_DU_BLEUE))); DEFV(Common,DEFV(genere_p,SINT(Ivraies_couleurs_aleatoires_____borne_inferieure_courante_ROUGE,NOIR))); DEFV(Common,DEFV(genere_p,SINT(Ivraies_couleurs_aleatoires_____borne_superieure_courante_ROUGE,BLANC))); DEFV(Common,DEFV(genere_p,SINT(Ivraies_couleurs_aleatoires_____borne_inferieure_courante_VERTE,NOIR))); DEFV(Common,DEFV(genere_p,SINT(Ivraies_couleurs_aleatoires_____borne_superieure_courante_VERTE,BLANC))); DEFV(Common,DEFV(genere_p,SINT(Ivraies_couleurs_aleatoires_____borne_inferieure_courante_BLEUE,NOIR))); DEFV(Common,DEFV(genere_p,SINT(Ivraies_couleurs_aleatoires_____borne_superieure_courante_BLEUE,BLANC))); #define solution_X \ solution_ROUGE #define solution_Y \ solution_VERTE #define solution_Z \ solution_BLEUE #define graine_X \ graine_ROUGE #define graine_Y \ graine_VERTE #define graine_Z \ graine_BLEUE #define facteur_X \ facteur_ROUGE #define facteur_Y \ facteur_VERTE #define facteur_Z \ facteur_BLEUE DEFV(Common,DEFV(FonctionI,Ivraies_couleurs_aleatoires(imageR_ROUGE,imageR_VERTE,imageR_BLEUE ,imageA ,utiliser_le_point_courant_comme_borne_superieure ,nombre_maximal_d_iterations ,graine_ROUGE,graine_VERTE,graine_BLEUE ,facteur_ROUGE,facteur_VERTE,facteur_BLEUE ) ) ) /* Fonction introduite le 20210520100923. */ DEFV(Argument,DEFV(image,imageR_ROUGE)); /* Image Resultat-ROUGE, telle que : imageR_ROUGE=R(imageA), */ DEFV(Argument,DEFV(image,imageR_VERTE)); /* Image Resultat-VERTE, telle que : imageR_VERTE=V(imageA), */ DEFV(Argument,DEFV(image,imageR_BLEUE)); /* Image Resultat-BLEUE, telle que : imageR_BLEUE=B(imageA), */ /* le passage des "fausses" aux "vraies" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(image,imageA)); /* Image Argument, telle qu'elle est consideree en fausse couleurs. */ DEFV(Argument,DEFV(Logical,utiliser_le_point_courant_comme_borne_superieure)); /* Afin de savoir si les bornes superieures seront fixees priori ou bien seront egales */ /* a la valeur du point courant (introduit le 20210520144056)... */ DEFV(Argument,DEFV(Positive,nombre_maximal_d_iterations)); /* Nombre maximal d'iterations de resolution des equations... */ DEFV(Argument,DEFV(Int,graine_ROUGE)); DEFV(Argument,DEFV(Int,graine_VERTE)); DEFV(Argument,DEFV(Int,graine_BLEUE)); /* Graines de generation aleatoire... */ DEFV(Argument,DEFV(Float,facteur_ROUGE)); DEFV(Argument,DEFV(Float,facteur_VERTE)); DEFV(Argument,DEFV(Float,facteur_BLEUE)); /* Afin de calculer les bornes inferieure et superieure de generation aleatoire... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ GENERATION_D_UNE_VALEUR_ALEATOIRE__DONNEES_GLOBALES; /*..............................................................................................................................*/ GENERATION_D_UNE_VALEUR_ALEATOIRE__INITIALISATIONS; begin_image Bblock DEFV(genere_p,INIT(point_courant,load_point(imageA,X,Y))); #define borne_inferieure_courante_ROUGE \ FLOT(Ivraies_couleurs_aleatoires_____borne_inferieure_courante_ROUGE) #define borne_superieure_courante_ROUGE \ FLOT(Ivraies_couleurs_aleatoires_____borne_superieure_courante_ROUGE) #define borne_inferieure_courante_VERTE \ FLOT(Ivraies_couleurs_aleatoires_____borne_inferieure_courante_VERTE) #define borne_superieure_courante_VERTE \ FLOT(Ivraies_couleurs_aleatoires_____borne_superieure_courante_VERTE) #define borne_inferieure_courante_BLEUE \ FLOT(Ivraies_couleurs_aleatoires_____borne_inferieure_courante_BLEUE) #define borne_superieure_courante_BLEUE \ FLOT(Ivraies_couleurs_aleatoires_____borne_superieure_courante_BLEUE) RESOLUTION_EQUATION_LINEAIRE_INDETERMINEE_3D__DONNEES_UTILES_LOCALES; RESOLUTION_EQUATION_LINEAIRE_INDETERMINEE_3D(Ivraies_couleurs_aleatoires_____luminance_du_ROUGE ,Ivraies_couleurs_aleatoires_____luminance_du_VERTE ,Ivraies_couleurs_aleatoires_____luminance_du_BLEUE ,FLOT(point_courant) ,utiliser_le_point_courant_comme_borne_superieure ,borne_inferieure_courante_ROUGE ,borne_superieure_courante_ROUGE ,borne_inferieure_courante_VERTE ,borne_superieure_courante_VERTE ,borne_inferieure_courante_BLEUE ,borne_superieure_courante_BLEUE ); #undef borne_superieure_courante_BLEUE #undef borne_inferieure_courante_BLEUE #undef borne_superieure_courante_VERTE #undef borne_inferieure_courante_VERTE #undef borne_superieure_courante_ROUGE #undef borne_inferieure_courante_ROUGE store_point(GENP(solution_ROUGE) ,imageR_ROUGE ,X,Y ,FVARIABLE ); store_point(GENP(solution_VERTE) ,imageR_VERTE ,X,Y ,FVARIABLE ); store_point(GENP(solution_BLEUE) ,imageR_BLEUE ,X,Y ,FVARIABLE ); Eblock end_image RETU_ERROR; Eblock EFonctionI #undef facteur_Z #undef facteur_Y #undef facteur_X #undef graine_Z #undef graine_Y #undef graine_X #undef solution_Z #undef solution_Y #undef solution_X _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E D E S F A U S S E S C O U L E U R S */ /* A D E S V R A I E S C O U L E U R S N O N A L E A T O I R E S : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(Positive,SINT(Ivraies_couleurs_non_aleatoires_____selectionner_aleatoirement_les_index,VRAI))); DEFV(Common,DEFV(Int,SINT(Ivraies_couleurs_non_aleatoires_____graine_de_selection_aleatoire_des_index,MAGIK))); /* Introduit le 20210523081314. Le dispositif a ete active par defaut le 20210523085644 */ /* (en passant de 'FAUX' a 'VRAI') car, en effet, cela marche parfaitement... */ DEFV(Common,DEFV(Positive,SINT(Ivraies_couleurs_non_aleatoires_____nombre_de_repetitions,FU))); /* Introduit le 20210522075419... */ #define NOMBRE_DE_TRIPLETS_RVB \ EXP3(COULEURS) #define INDEX_MINIMAL_DES_TRIPLETS_RVB \ INDEX0 #define INDEX_MAXIMAL_DES_TRIPLETS_RVB \ LSTX(INDEX_MINIMAL_DES_TRIPLETS_RVB,NOMBRE_DE_TRIPLETS_RVB) /* Nombre de triplets {ROUGE,VERTE,BLEUE}... */ #define INDEX_PERMUTE(index) \ ITb1(liste_PERTUMATION,index) \ /* Permutation d'un index apres tri... */ DEFV(Common,DEFV(FonctionI,Ivraies_couleurs_non_aleatoires(imageR_ROUGE,imageR_VERTE,imageR_BLEUE ,imageA ) ) ) /* Fonction introduite le 20210521082524. */ DEFV(Argument,DEFV(image,imageR_ROUGE)); DEFV(Argument,DEFV(image,imageR_VERTE)); DEFV(Argument,DEFV(image,imageR_BLEUE)); /* Image Resultat en vraies couleurs et dont la luminance est donnee par 'imageA'... */ DEFV(Argument,DEFV(image,imageA)); /* Image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ DEFV(genere_p,DTb1(liste___LUMINANCE,NOMBRE_DE_TRIPLETS_RVB)); DEFV(genere_p,DTb1(liste_______ROUGE,NOMBRE_DE_TRIPLETS_RVB)); DEFV(genere_p,DTb1(liste_______VERTE,NOMBRE_DE_TRIPLETS_RVB)); DEFV(genere_p,DTb1(liste_______BLEUE,NOMBRE_DE_TRIPLETS_RVB)); DEFV(Int,DTb1(liste_PERTUMATION,NOMBRE_DE_TRIPLETS_RVB)); begin_nouveau_block Bblock DEFV(genere_p,INIT(niveau____ROUGE,NIVEAU_UNDEF)); DEFV(genere_p,INIT(niveau____VERTE,NIVEAU_UNDEF)); DEFV(genere_p,INIT(niveau____BLEUE,NIVEAU_UNDEF)); DEFV(Int,INIT(index,INDEX_MINIMAL_DES_TRIPLETS_RVB)); BoIn(niveau____ROUGE,NOIR,BLANC,PAS_COULEURS) Bblock BoIn(niveau____VERTE,NOIR,BLANC,PAS_COULEURS) Bblock BoIn(niveau____BLEUE,NOIR,BLANC,PAS_COULEURS) Bblock DEFV(Float,INIT(luminance,FLOT__UNDEF)); EGAL(ITb1(liste_______ROUGE,index),niveau____ROUGE); EGAL(ITb1(liste_______VERTE,index),niveau____VERTE); EGAL(ITb1(liste_______BLEUE,index),niveau____BLEUE); /* Generation de toutes les combinaisons de {ROUGE,VERTE,BLEUE}. */ EGAL(luminance,CALCUL_DE_LA_LUMINANCE(FLOT(niveau____ROUGE),FLOT(niveau____VERTE),FLOT(niveau____BLEUE))); Test(IFEXff(luminance,FLOT(NOIR),FLOT(BLANC))) /* ATTENTION, je note le 20220204185950 qu'on ne peut utiliser ici : */ /* */ /* Test(IFEXff(luminance,FLOT__NOIR,FLOT__BLANC)) */ /* */ /* car, en effet, c'est vraiment [NOIR,BLANC] qu'il faut tester. Or un jour 'FLOT__NOIR' */ /* ou 'FLOT__BLANC' pourraient changer de definition... */ Bblock PRINT_ERREUR("la luminance est hors de [NOIR,BLANC]"); CAL1(Prer4("({R,V,B} = {%d,%d,%d} --> L = %f)\n" ,niveau____ROUGE,niveau____VERTE,niveau____BLEUE,luminance ) ); Eblock ATes Bblock Eblock ETes EGAL(ITb1(liste___LUMINANCE,index),GENP(luminance)); /* Generation de toutes les LUMINANCEs possibles... */ EGAL(ITb1(liste_PERTUMATION,index),index); /* En vue du tri... */ INCR(index,I); Eblock EBoI Eblock EBoI Eblock EBoI Eblock end_nouveau_block TRI_D_UNE_LISTE_QUELCONQUE_VERSION_N_LOG_N(liste___LUMINANCE ,liste_PERTUMATION ,INDEX_MINIMAL_DES_TRIPLETS_RVB ,INDEX_MAXIMAL_DES_TRIPLETS_RVB ,ITb1 ); /* Tri rapide des luminances avec generation d'une liste de permutation permettant l'acces */ /* a toutes les listes triees par LUMINANCEs croissantes... */ begin_nouveau_block Bblock GENERATION_D_UNE_VALEUR_ALEATOIRE__DONNEES_GLOBALES; /* Introduit le 20210523083350... */ DEFV(Int,DTb1(liste_index___debut_LUMINANCE,COULEURS)); DEFV(Int,DTb1(liste_index_____fin_LUMINANCE,COULEURS)); DEFV(Float,DTb1(liste_index_courant_LUMINANCE,COULEURS)); /* Listes destinees a substituer une LUMINANCE par un triplet {ROUGE,VERTE,BLEUE} */ /* possedant cette meme luminance... */ /* */ /* Le 20210522075419, 'liste_index_courant_LUMINANCE' est passee de 'Int' a 'Float' de */ /* facon a permettre de repeter plusieurs fois de suite l'usage de la meme affectation */ /* entre 'LUMINANCE' et {ROUGE,VERTE,BLEUE}... */ DEFV(Int,INIT(index1,UNDEF)); DEFV(Int,INIT(index2,NOIR)); EGAL(ITb1(liste_index___debut_LUMINANCE,index2),INDEX_MINIMAL_DES_TRIPLETS_RVB); EGAL(ITb1(liste_index_courant_LUMINANCE,index2),FLOT(ITb1(liste_index___debut_LUMINANCE,index2))); /* Initialisation de la generation des listes de substitution des LUMINANCEs... */ BoIn(index1,INDEX_MINIMAL_DES_TRIPLETS_RVB,INDEX_MAXIMAL_DES_TRIPLETS_RVB,I) Bblock Test(IFEQ(ITb1(liste___LUMINANCE,INDEX_PERMUTE(index1)) ,ITb1(liste___LUMINANCE,INDEX_PERMUTE(ITb1(liste_index___debut_LUMINANCE,index2))) ) ) Bblock EGAL(ITb1(liste_index_____fin_LUMINANCE,index2),index1); Eblock ATes Bblock INCR(index2,I); EGAL(ITb1(liste_index___debut_LUMINANCE,index2),index1); EGAL(ITb1(liste_index_courant_LUMINANCE,index2),FLOT(ITb1(liste_index___debut_LUMINANCE,index2))); /* Generation des listes de substitution des LUMINANCEs... */ Eblock ETes Eblock EBoI EGAL(ITb1(liste_index_____fin_LUMINANCE,index2),INDEX_MAXIMAL_DES_TRIPLETS_RVB); /* Fin de la generation des listes de substitution des LUMINANCEs... */ Test(IFNE(index2,BLANC)) Bblock PRINT_ERREUR("un index n'a pas parcouru [NOIR,BLANC] correctement"); CAL1(Prer1("(il vaut %d\n",index2)); Eblock ATes Bblock Eblock ETes Test(IL_FAUT(Ivraies_couleurs_non_aleatoires_____selectionner_aleatoirement_les_index)) /* Test introduit le 20210523083350... */ Bblock GENERATION_D_UNE_VALEUR_ALEATOIRE__INITIALISATIONS; Eblock ATes Bblock Eblock ETes begin_image Bblock DEFV(genere_p,INIT(point_courant,load_point(imageA,X,Y))); DEFV(Int,INIT(index,UNDEF)); Test(IL_FAUT(Ivraies_couleurs_non_aleatoires_____selectionner_aleatoirement_les_index)) /* Test introduit le 20210523081314... */ Bblock DEFV(Float,INIT(index_aleatoire,FLOT__UNDEF)); GENERATION_D_UNE_VALEUR_ALEATOIRE__CALCUL (index_aleatoire ,Ivraies_couleurs_non_aleatoires_____graine_de_selection_aleatoire_des_index ,FLOT(ITb1(liste_index___debut_LUMINANCE,point_courant)) ,FLOT(ITb1(liste_index_____fin_LUMINANCE,point_courant)) ); EGAL(index,INTE(index_aleatoire)); Eblock ATes Bblock EGAL(index,INTE(ITb1(liste_index_courant_LUMINANCE,point_courant))); Eblock ETes store_point(ITb1(liste_______ROUGE,INDEX_PERMUTE(index)),imageR_ROUGE,X,Y,FVARIABLE); store_point(ITb1(liste_______VERTE,INDEX_PERMUTE(index)),imageR_VERTE,X,Y,FVARIABLE); store_point(ITb1(liste_______BLEUE,INDEX_PERMUTE(index)),imageR_BLEUE,X,Y,FVARIABLE); /* Generation de l'image en couleurs {imageR_ROUGE,imageR_VERTE,imageR_BLEUE} ayant comme */ /* LUMINANCE l'image 'imageA'... */ Test(IL_FAUT(Ivraies_couleurs_non_aleatoires_____selectionner_aleatoirement_les_index)) /* Test introduit le 20210523081314... */ Bblock Eblock ATes Bblock Test(IFLT(index,ITb1(liste_index_____fin_LUMINANCE,point_courant))) Bblock INCR(ITb1(liste_index_courant_LUMINANCE,point_courant) ,INVZ(FLOT(Ivraies_couleurs_non_aleatoires_____nombre_de_repetitions)) ); /* Ainsi, l'increment peut etre inferieur a 1 et donc provoquer en quelque sorte un */ /* "sur place" de l'affectation entre 'LUMINANCE' et {ROUGE,VERTE,BLEUE}... */ Eblock ATes Bblock EGAL(ITb1(liste_index_courant_LUMINANCE,point_courant) ,FLOT(ITb1(liste_index___debut_LUMINANCE,point_courant)) ); Eblock ETes Eblock ETes Eblock end_image Eblock end_nouveau_block RETU_ERROR; Eblock EFonctionI #undef INDEX_PERMUTE #undef INDEX_MAXIMAL_DES_TRIPLETS_RVB #undef INDEX_MINIMAL_DES_TRIPLETS_RVB #undef NOMBRE_DE_TRIPLETS_RVB _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M I N I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( R , V , B ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 2 , 2 , 2 ) : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_RVB_222_universel(imageR,imageA_ROUGE,imageA_VERTE,imageA_BLEUE)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : */ /* */ /* imageR=MULTIPLEXAGE_RVB_222(imageA_ROUGE,imageA_VERTE,imageA_BLEUE), */ /* */ /* ce qui donne donc une image "fausses couleurs" compatible avec, par exemple, la */ /* palette '$xiP/universel.31' avec la precision minimale, mais equitable entre */ /* les trois composantes chromatiques : {R,V,B} = (2+2+2). */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Premiere image Argument (correspondant a la composante 'ROUGE'), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Seconde image Argument (correspondant a la composante 'VERTE'), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Troisieme image Argument (correspondant a la composante 'BLEUE'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock store_point(MULTIPLEXAGE_RVB_222(load_point(imageA_ROUGE,X,Y) ,load_point(imageA_VERTE,X,Y) ,load_point(imageA_BLEUE,X,Y) ) ,imageR ,X,Y ,FVARIABLE ); Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M I N I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( R , V , B ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 2 , 2 , 3 ) : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_RVB_223_universel(imageR,imageA_ROUGE,imageA_VERTE,imageA_BLEUE)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : */ /* */ /* imageR=MULTIPLEXAGE_RVB_223(imageA_ROUGE,imageA_VERTE,imageA_BLEUE), */ /* */ /* ce qui donne donc une image "fausses couleurs" compatible avec, par exemple, la */ /* palette '$xiP/universel.21' avec la precision minimale, mais equitable entre */ /* les trois composantes chromatiques : {R,V,B} = (2+2+3). */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Premiere image Argument (correspondant a la composante 'ROUGE'), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Seconde image Argument (correspondant a la composante 'VERTE'), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Troisieme image Argument (correspondant a la composante 'BLEUE'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock store_point(MULTIPLEXAGE_RVB_223(load_point(imageA_ROUGE,X,Y) ,load_point(imageA_VERTE,X,Y) ,load_point(imageA_BLEUE,X,Y) ) ,imageR ,X,Y ,FVARIABLE ); Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( R , V , B ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 3 , 3 , 2 ) : */ /* */ /*************************************************************************************************************************************/ BFonctionP #ifdef SLRS_RVB_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */ DEFV(Common,DEFV(Logical,_____SLRS_RVB_VERSION_01)); #Aifdef SLRS_RVB_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */ #Eifdef SLRS_RVB_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */ #ifdef SLRS_RVB_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */ DEFV(Common,DEFV(Logical,_____SLRS_RVB_VERSION_02)); #Aifdef SLRS_RVB_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */ #Eifdef SLRS_RVB_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */ DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_RVB_332_universel(imageR,imageA_ROUGE,imageA_VERTE,imageA_BLEUE)))) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : */ /* */ /* imageR=MULTIPLEXAGE_RVB_332(imageA_ROUGE,imageA_VERTE,imageA_BLEUE), */ /* */ /* ce qui donne donc une image "fausses couleurs" compatible avec, par exemple, la */ /* palette '$xiP/universel.11' avec la precision maximale, mais non equitable entre */ /* les trois composantes chromatiques : {R,V,B} = (3+3+2). */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Premiere image Argument (correspondant a la composante 'ROUGE'), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Seconde image Argument (correspondant a la composante 'VERTE'), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Troisieme image Argument (correspondant a la composante 'BLEUE'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ begin_image Bblock store_point(MULTIPLEXAGE_RVB_332(load_point(imageA_ROUGE,X,Y) ,load_point(imageA_VERTE,X,Y) ,load_point(imageA_BLEUE,X,Y) ) ,imageR ,X,Y ,FVARIABLE ); Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P R O C E D U R E S D E M U L T I P L E X A G E M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) : */ /* */ /*************************************************************************************************************************************/ #define MX_RVBg(niveau_ROUGE,niveau_VERTE,niveau_BLEUE) \ MULTIPLEXAGE_RVBg_888(niveau_ROUGE,niveau_VERTE,niveau_BLEUE) \ /* Definition temporaire de 'MULTIPLEXAGE_RVBg_888(...)' afin de reduire la longueur de */ \ /* son nom de facon a ce qu'il que la generation des fonction puisse tenir sur une seule */ \ /* ligne... */ #define MX_BVR(niveau_ROUGE,niveau_VERTE,niveau_BLEUE) \ MULTIPLEXAGE_BVR_888(niveau_ROUGE,niveau_VERTE,niveau_BLEUE) \ /* Definition temporaire de 'MULTIPLEXAGE_BVR_888(...)' afin de reduire la longueur de */ \ /* son nom de facon a ce qu'il que la generation des fonction puisse tenir sur une seule */ \ /* ligne... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) : */ /* */ /*************************************************************************************************************************************/ #define GENERE__FonctionI_MX(nom_et_arguments_de_la_fonction,nom_du_multiplexage) \ /* ATTENTION : le nom de la fonction est suivi de ses arguments pour des raisons liees */ \ /* a la recuperation automatique des fichiers d'arguments ; on trouvera donc : */ \ /* */ \ /* GENERE__FonctionI_MX(nom_de_la_fonction(...)) */ \ /* */ \ /* ou 'avant' designe 'premier_plan' et 'arriere', 'arriere_plan'. */ \ DEFV(FonctionI,nom_et_arguments_de_la_fonction) \ /* ATTENTION, il ne faut pas ecrire : */ \ /* */ \ /* DEFV(Common,DEFV(FonctionI,nom_et_arguments_de_la_fonction)) */ \ /* */ \ /* puisqu'en effet la directive 'Common' est utilisee lors de l'appel par : */ \ /* */ \ /* DEFV(Common,GENERE__FonctionI_MX(...)) */ \ /* */ \ \ DEFV(Argument,DEFV(imageUB,iR)); \ /* Image Resultat, telle que : */ \ /* */ \ /* imageR=nom_du_multiplexage(imageA_ROUGE,imageA_VERTE,imageA_BLEUE), */ \ /* */ \ /* ce qui donne donc une image "fausses couleurs" avec la precision maximale, et en */ \ /* faisant ATTENTION au fait que l'ordre adopte est (B,V,R)... */ \ DEFV(Argument,DEFV(image,iA_R)); \ /* Premiere image Argument (correspondant a la composante 'ROUGE'), */ \ DEFV(Argument,DEFV(image,iA_V)); \ /* Seconde image Argument (correspondant a la composante 'VERTE'), */ \ DEFV(Argument,DEFV(image,iA_B)); \ /* Troisieme image Argument (correspondant a la composante 'BLEUE'). */ \ /*-----------------------------------------------------------------------------------------------------------------------------------*/ \ Bblock \ INIT_ERROR; \ /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ \ /* ('BDEFV','EDEFV') suivraient... */ \ /*..............................................................................................................................*/ \ begin_image \ Bblock \ storeUB_point(nom_du_multiplexage(load_point(iA_R,X,Y) \ ,load_point(iA_V,X,Y) \ ,load_point(iA_B,X,Y) \ ) \ ,iR \ ,X,Y \ ); \ Eblock \ end_image \ \ RETU_ERROR; \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( R , V , B ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) */ /* A V E C C A D R A G E A G A U C H E : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,GENERE__FonctionI_MX(Ifausses_couleurs_RVBg_888_universel(iR,iA_R,iA_V,iA_B),MX_RVBg)) /* Common,DEFV(Fonction,) : */ EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( B , V , R ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,GENERE__FonctionI_MX(Ifausses_couleurs_BVR_888_universel(iR,iA_R,iA_V,iA_B),MX_BVR)) /* Common,DEFV(Fonction,) : */ EFonctionI #undef GENERE__FonctionI_MX _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E ( 8 , 8 , 8 ) D ' U N E I M A G E */ /* E N V R A I E S C O U L E U R S ( R , V , B ) : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(genere_p,SINT(Imultiplexage_888_RVB_____composante_ALPHA,NOIR))); /* Il y a en fait 4 composantes : {ROUGE,VERTE,BLEUE} plus 'ALPHA'. A priori, cette */ /* derniere est 'NOIR', mais il peut etre utile de temps en temps de la forcer a 'BLANC' */ /* ('v $xci/RVB_store$K Imultiplexage_888_RVB_____composante_ALPHA' ainsi que */ /* 'v $Fdivers ALPHA='). */ DEFV(Common,DEFV(FonctionI,Imultiplexage_888_RVB(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ) ) ) DEFV(Argument,DEFV(imageUB,imageR)); /* Image Resultat, telle que : */ /* */ /* imageR=MULTIPLEXAGE_RVBg_888(imageA_ROUGE,imageA_VERTE,imageA_BLEUE), */ /* */ /* en faisant ATTENTION au fait que l'ordre adopte est {R,V,B}... */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Premiere image Argument (correspondant a la composante 'ROUGE'), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Seconde image Argument (correspondant a la composante 'VERTE'), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Troisieme image Argument (correspondant a la composante 'BLEUE'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock DEFV(genere_p,INIT(point_courant_ROUGE,load_point(imageA_ROUGE,X,Y))); DEFV(genere_p,INIT(point_courant_VERTE,load_point(imageA_VERTE,X,Y))); DEFV(genere_p,INIT(point_courant_BLEUE,load_point(imageA_BLEUE,X,Y))); /* Point courant des images Arguments. */ DEFV(genere_vrai_Positive_de_base,INIT(point_courant ,MULTIPLEXAGE_RVBg_888(point_courant_ROUGE,point_courant_VERTE,point_courant_BLEUE) ) ); /* Point courant apres multiplexage {ROUGE,VERTE,BLEUE}. */ storeUB_point(OUIN(ETLO(point_courant,OUEX(MMOT,MOCD)),Imultiplexage_888_RVB_____composante_ALPHA) ,imageR ,X,Y ); /* Multiplexage des trois composantes... */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E M U L T I P L E X A G E ( 8 , 8 , 8 ) D ' U N E I M A G E */ /* E N V R A I E S C O U L E U R S ( R , V , B ) : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Idemultiplexage_888_RVB(imageR_ROUGE,imageR_VERTE,imageR_BLEUE ,imageA ) ) ) DEFV(Argument,DEFV(image,imageR_ROUGE)); /* Premiere image Resultat (correspondant a la composante 'ROUGE'), */ DEFV(Argument,DEFV(image,imageR_VERTE)); /* Seconde image Resultat (correspondant a la composante 'VERTE'), */ DEFV(Argument,DEFV(image,imageR_BLEUE)); /* Troisieme image Resultat (correspondant a la composante 'BLEUE'). */ DEFV(Argument,DEFV(imageUB,imageA)); /* Image Argument, telle que : */ /* */ /* imageA=MULTIPLEXAGE_RVBg_888(imageR_ROUGE,imageR_VERTE,imageR_BLEUE), */ /* */ /* en faisant ATTENTION au fait que l'ordre adopte est {R,V,B}... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock DEFV(genere_vrai_Positive_de_base,INIT(point_courant,loadUB_point(imageA,X,Y))); /* Point courant de l'image Argument. */ store_point(DEMULTIPLEXAGE_RVBg_888_ROUGE(point_courant),imageR_ROUGE,X,Y,FVARIABLE); store_point(DEMULTIPLEXAGE_RVBg_888_VERTE(point_courant),imageR_VERTE,X,Y,FVARIABLE); store_point(DEMULTIPLEXAGE_RVBg_888_BLEUE(point_courant),imageR_BLEUE,X,Y,FVARIABLE); /* Demultiplexage des trois composantes... */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E M U L T I P L E X A G E D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) */ /* E N S E S T R O I S C O M P O S A N T E S C H R O M A T I Q U E S ( B , V , R ) : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,IBVR_888_universel_fausses_couleurs(imageR_ROUGE,imageR_VERTE,imageR_BLEUE ,imageA ) ) ) DEFV(Argument,DEFV(image,imageR_ROUGE)); /* Premiere image Resultat (correspondant a la composante 'ROUGE'), */ DEFV(Argument,DEFV(image,imageR_VERTE)); /* Seconde image Resultat (correspondant a la composante 'VERTE'), */ DEFV(Argument,DEFV(image,imageR_BLEUE)); /* Troisieme image Resultat (correspondant a la composante 'BLEUE'). */ DEFV(Argument,DEFV(imageUB,imageA)); /* Image Argument, telle que : */ /* */ /* imageA=MULTIPLEXAGE_BVR_888(imageR_ROUGE,imageR_VERTE,imageR_BLEUE), */ /* */ /* ce qui donne donc une image "fausses couleurs" avec la precision maximale, et en */ /* faisant ATTENTION au fait que l'ordre adopte est (B,V,R)... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock DEFV(genere_vrai_Positive_de_base,INIT(point_courant,loadUB_point(imageA,X,Y))); /* Point courant de l'image Argument. */ store_point(DEMULTIPLEXAGE_BVR_888_ROUGE(point_courant),imageR_ROUGE,X,Y,FVARIABLE); store_point(DEMULTIPLEXAGE_BVR_888_VERTE(point_courant),imageR_VERTE,X,Y,FVARIABLE); store_point(DEMULTIPLEXAGE_BVR_888_BLEUE(point_courant),imageR_BLEUE,X,Y,FVARIABLE); /* Demultiplexage des trois composantes... */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) */ /* A V E C R E - A J U S T E M E N T E V E N T U E L D E L A L U M I N A N C E : */ /* */ /*************************************************************************************************************************************/ #define GENERE__FonctionI_AJ(nom_et_arguments_de_la_fonction,nom_du_multiplexage) \ /* ATTENTION : le nom de la fonction est suivi de ses arguments pour des raisons liees */ \ /* a la recuperation automatique des fichiers d'arguments ; on trouvera donc : */ \ /* */ \ /* GENERE__FonctionI_AJ(nom_de_la_fonction(...)) */ \ /* */ \ /* ou 'avant' designe 'premier_plan' et 'arriere', 'arriere_plan'. */ \ DEFV(FonctionI,nom_et_arguments_de_la_fonction) \ /* ATTENTION, il ne faut pas ecrire : */ \ /* */ \ /* DEFV(Common,DEFV(FonctionI,nom_et_arguments_de_la_fonction)) */ \ /* */ \ /* puisqu'en effet la directive 'Common' est utilisee lors de l'appel par : */ \ /* */ \ /* DEFV(Common,GENERE__FonctionI_AJ(...)) */ \ /* */ \ \ DEFV(Argument,DEFV(imageUB,iR)); \ /* Image Resultat, telle que : */ \ /* */ \ /* imageR=nom_du_multiplexage(imageA_ROUGE,imageA_VERTE,imageA_BLEUE), */ \ /* */ \ /* ce qui donne donc une image "fausses couleurs" avec la precision maximale, et en */ \ /* faisant ATTENTION au fait que l'ordre adopte est (B,V,R). D'autre part la Luminance */ \ /* de l'image Argument (le triplet (ROUGE,VERTE,BLEUE)) peut etre reajuste, sauf aux points */ \ /* ou la Luminance est 'NOIR'... */ \ DEFV(Argument,DEFV(image,iA_R)); \ /* Premiere image Argument (correspondant a la composante 'ROUGE'), */ \ DEFV(Argument,DEFV(image,iA_V)); \ /* Seconde image Argument (correspondant a la composante 'VERTE'), */ \ DEFV(Argument,DEFV(image,iA_B)); \ /* Troisieme image Argument (correspondant a la composante 'BLEUE'). */ \ DEFV(Argument,DEFV(genere_p,mL)); \ /* Minimum demande pour la luminance (a l'exception des points 'NOIR' qui le resteront...). */ \ DEFV(Argument,DEFV(genere_p,ML)); \ /* Maximum demande pour la luminance. */ \ /*-----------------------------------------------------------------------------------------------------------------------------------*/ \ Bblock \ INIT_ERROR; \ /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ \ /* ('BDEFV','EDEFV') suivraient... */ \ /*..............................................................................................................................*/ \ begin_image \ Bblock \ DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); \ /* NR = niveau du point courant imageA_ROUGE(X,Y), */ \ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); \ /* NV = niveau du point courant imageA_VERTE(X,Y), */ \ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); \ /* NB = niveau du point courant imageA_BLEUE(X,Y). */ \ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'HLS' a */ \ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ \ EGAL(niveau_ROUGE,load_point(iA_R,X,Y)); \ EGAL(niveau_VERTE,load_point(iA_V,X,Y)); \ EGAL(niveau_BLEUE,load_point(iA_B,X,Y)); \ /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ \ \ Test(I3OU(IFNE(niveau_ROUGE,NOIR) \ ,IFNE(niveau_VERTE,NOIR) \ ,IFNE(niveau_BLEUE,NOIR) \ ) \ ) \ Bblock \ /* Le re-ajustement de la luminance n'est fait que sur les points non 'NOIR's... */ \ /* */ \ /* ATTENTION, on notera que la solution suivante ne marche pas : */ \ /* */ \ /* DEFV(Float,INIT(Hue_du_point_courant,FLOT__UNDEF)); */ \ /* /* donne la teinte du point {X,Y} courant, */ \ /* DEFV(Float,INIT(Luminance_du_point_courant,FLOT__UNDEF)); */ \ /* /* donne la luminance du point {X,Y} courant, */ \ /* DEFV(Float,INIT(Saturation_du_point_courant,FLOT__UNDEF)); */ \ /* /* donne la saturation du point {X,Y} courant. */ \ /* */ \ /* PASSAGE_RVB_HLS(Hue_du_point_courant */ \ /* ,Luminance_du_point_courant */ \ /* ,Saturation_du_point_courant */ \ /* ,niveau_ROUGE */ \ /* ,niveau_VERTE */ \ /* ,niveau_BLEUE */ \ /* ); */ \ /* /* passage de l'espace 'RVB' a l'espace 'HLS' pour */ \ /* /* le point {X,Y} courant. */ \ /* PASSAGE_HLS_RVB(niveau_ROUGE */ \ /* ,niveau_VERTE */ \ /* ,niveau_BLEUE */ \ /* ,Hue_du_point_courant */ \ /* ,HOMO(Luminance_du_point_courant */ \ /* ,NOIR,BLANC */ \ /* ,mL,ML */ \ /* ) */ \ /* ,Saturation_du_point_courant */ \ /* ); */ \ /* /* passage inverse de l'espace 'HLS' a l'espace */ \ /* /* 'RVB' pour le point {X,Y} courant, apres le */ \ /* /* re-ajustement de la luminance (sauf pour les */ \ /* /* points 'NOIR'...). */ \ /* */ \ /* En effet, supposons : */ \ /* */ \ /* ROUGE=0, */ \ /* VERTE=0, */ \ /* BLEUE=1 (dans [NOIR,BLANC]=[0,255]), */ \ /* */ \ /* cela donne : */ \ /* */ \ /* MAXI(ROUGE,VERTE,BLEUE) - MINI(ROUGE,VERTE,BLEUE) 1 - 0 */ \ /* Saturation = --------------------------------------------------- = ------- = 1, */ \ /* MAXI(ROUGE,VERTE,BLEUE) + MINI(ROUGE,VERTE,BLEUE) 1 + 0 */ \ /* */ \ /* la 'Saturation' est donc maximale ; puis supposons pour le re-ajustement de la Luminance */ \ /* les extrema suivants : */ \ /* */ \ /* minimum=0, */ \ /* maximum=127, */ \ /* */ \ /* apres, ce processus, on trouve alors : */ \ /* */ \ /* Luminance=127 (a epsilon pres), */ \ /* Saturation=1, */ \ /* */ \ /* d'ou : */ \ /* */ \ /* Niveau1=0 */ \ /* Niveau2=255 */ \ /* */ \ /* puis donc : */ \ /* */ \ /* ROUGE=0, */ \ /* VERTE=0, */ \ /* BLEUE=255, */ \ /* */ \ /* le niveau de BLEUE est donc trop accentue ; cela semble venir du fait que la saturation */ \ /* soit alors maximale (voir sa definition dans 'v $xiii/quad_image$DEF')... */ \ EGAL(niveau_ROUGE \ ,HOMO(niveau_ROUGE \ ,NOIR,BLANC \ ,mL,ML \ ) \ ); \ EGAL(niveau_VERTE \ ,HOMO(niveau_VERTE \ ,NOIR,BLANC \ ,mL,ML \ ) \ ); \ EGAL(niveau_BLEUE \ ,HOMO(niveau_BLEUE \ ,NOIR,BLANC \ ,mL,ML \ ) \ ); \ /* Pour les points non 'NOIR's, les trois composantes sont re-ajustees separemment... */ \ Eblock \ ATes \ Bblock \ /* Lorsqu'un point est NOIR, il le reste... */ \ Eblock \ ETes \ \ storeUB_point(nom_du_multiplexage(niveau_ROUGE \ ,niveau_VERTE \ ,niveau_BLEUE \ ) \ ,iR \ ,X,Y \ ); \ /* Puis rangement du point courant apres le re-ajustement... */ \ Eblock \ end_image \ \ RETU_ERROR; \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( B , V , R ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) */ /* A V E C R E - A J U S T E M E N T E V E N T U E L D E L A L U M I N A N C E */ /* E T A V E C C A D R A G E A G A U C H E : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,GENERE__FonctionI_AJ(Iajustement_de_la_luminance_RVBg_888(iR,iA_R,iA_V,iA_B,mL,ML),MX_RVBg)) /* Common,DEFV(Fonction,) : */ EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M U L T I P L E X A G E " U N I V E R S E L " M A X I M A L D E S T R O I S C O M P O S A N T E S */ /* C H R O M A T I Q U E S ( B , V , R ) D ' U N E I M A G E E N V R A I E S C O U L E U R S ( 8 , 8 , 8 ) */ /* A V E C R E - A J U S T E M E N T E V E N T U E L D E L A L U M I N A N C E : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,GENERE__FonctionI_AJ(Iajustement_de_la_luminance_BVR_888(iR,iA_R,iA_V,iA_B,mL,ML),MX_BVR)) /* Common,DEFV(Fonction,) : */ EFonctionI /* ATTENTION, avant l'introduction de la procedure 'GENERE__FonctionI_AJ(...)' cette */ /* fonction s'appelait : */ /* */ /* Iajustement_de_la_luminance_BVR_888_universel */ /* */ /* mais, malheureusement, ce nom etait trop long pour que la generation de cette fonction */ /* tienne sur une ligne... */ #undef GENERE__FonctionI_AJ #undef MX_BVR #undef MX_RVBg _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E E X A C T D E S V R A I E S A U X F A U S S E S C O U L E U R S */ /* P A R P A R C O U R S E X H A U S T I F D E L ' E S P A C E ' R V B ' : */ /* */ /*************************************************************************************************************************************/ BFonctionP #define PONDERATION_DE_LA_LUMINANCE \ FU \ /* Afin de ponderer la luminance par rapport aux niveaux {R,V,B} ; plus cette valeur est */ \ /* grande, plus la luminance a d'importance (cf. 'MUL2'). */ #define PONDERATION_DES_PONDERATIONS_DES_COULEURS \ FU \ /* Afin de ponderer les niveaux {R,V,B} entre eux ; plus cette valeur est grande, plus on */ \ /* privilegie une couleur par rapport aux autres (cf. 'MUL2'). */ DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_RVB_exactes(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ,ponderation_de_la_luminance ,ponderation_des_ponderations_des_couleurs ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle qu'elle est consideree en fausse couleurs, telle que : */ /* */ /* R(imageR) = imageA_ROUGE, */ /* V(imageR) = imageA_VERTE, */ /* B(imageR) = imageA_BLEUE. */ /* */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Image Argument-ROUGE, telle que : imageA_ROUGE=R(imageR), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Image Argument-VERTE, telle que : imageA_VERTE=V(imageR), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Image Argument-BLEUE, telle que : imageA_BLEUE=B(imageR), */ /* le passage des "vraies" aux "fausses" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(Float,ponderation_de_la_luminance)); /* Afin de ponderer la luminance par rapport aux niveaux {R,V,B} ; plus cette valeur est */ /* grande, plus la luminance a d'importance (cf. 'MUL2') ; 1.0 semble une bonne valeur... */ DEFV(Argument,DEFV(Float,ponderation_des_ponderations_des_couleurs)); /* Afin de ponderer les niveaux {R,V,B} entre eux ; plus cette valeur est grande, plus on */ /* privilegie une couleur par rapport aux autres (cf. 'MUL2') ; 1.0 semble une bonne valeur. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Float,DTb1(luminance_des_couleurs,COULEURS)); /* Cette table contient la luminance de chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); /* NR = niveau du point courant imageA_ROUGE(X,Y), */ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); /* NV = niveau du point courant imageA_VERTE(X,Y), */ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); /* NB = niveau du point courant imageA_BLEUE(X,Y). */ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'RVB' a */ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ DEFV(Float,INIT(luminance_du_point_courant,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant. */ DEFV(Float,INIT(ponderation_ROUGE,FLOT__UNDEF)); /* Definit une ponderation permettant d'amplifier le ROUGE si c'est la couleur dominante, */ /* la valeur obtenue est dans [0,1] telle que plus une couleur est presente, plus sa */ /* ponderation est faible, et donc plus elle se rapproche du point a approximer... */ DEFV(Float,INIT(ponderation_VERTE,FLOT__UNDEF)); /* Definit une ponderation permettant d'amplifier le VERTE si c'est la couleur dominante, */ /* la valeur obtenue est dans [0,1] telle que plus une couleur est presente, plus sa */ /* ponderation est faible, et donc plus elle se rapproche du point a approximer... */ DEFV(Float,INIT(ponderation_BLEUE,FLOT__UNDEF)); /* Definit une ponderation permettant d'amplifier le BLEUE si c'est la couleur dominante, */ /* la valeur obtenue est dans [0,1] telle que plus une couleur est presente, plus sa */ /* ponderation est faible, et donc plus elle se rapproche du point a approximer... */ DEFV(Float,INIT(carre_de_la_distance_dans_l_espace_RVB,FLOT__UNDEF)); /* On construit a l'aide des trois listes de substitution 'RVB' et de leur Luminance, un */ /* espace a 4 dimensions. Pour chaque {X,Y} on prend un point dans chaque image Argument, */ /* ce qui donne les trois niveaux precedents {nR,nV,nB} et leur luminance 'L' ; puis on */ /* calcule la distance du point (L,nR,nV,nB) dit "vraies couleurs", aux 'COULEURS' points */ /* dits "fausses couleurs" l'espace 'RVB', afin d'en trouver le plus proche qui sera celui */ /* qui definira la fausse couleur Resultat. */ DEFV(Float,INIT(carre_de_la_distance_minimale_dans_l_espace_RVB,FLOT__UNDEF)); /* Afin de rechercher le point le plus proche du point courant. */ DEFV(genere_p,INIT(niveau_exact_le_plus_proche,NIVEAU_UNDEF)); /* Point le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ BoIn(niveau_courant,NOIR,BLANC,pas_COULEURS) Bblock EGAL(ITb1(luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,CALCUL_DE_LA_LUMINANCE(ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ) ); /* Calcul de la luminance de chacun des 'COULEURS' points de l'espace 'RVB'. */ Eblock EBoI begin_image Bblock EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ EGAL(luminance_du_point_courant ,CALCUL_DE_LA_LUMINANCE(niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ) ); /* Calcul de la luminance du point {X,Y} courant. */ EGAL(ponderation_ROUGE,COMP(MUL2(ponderation_des_ponderations_des_couleurs,______NORMALISE_NIVEAU(niveau_ROUGE)))); EGAL(ponderation_VERTE,COMP(MUL2(ponderation_des_ponderations_des_couleurs,______NORMALISE_NIVEAU(niveau_VERTE)))); EGAL(ponderation_BLEUE,COMP(MUL2(ponderation_des_ponderations_des_couleurs,______NORMALISE_NIVEAU(niveau_BLEUE)))); /* Initialisation des trois ponderations chromatiques ; la valeur obtenue est dans [0,1] */ /* telle que plus une couleur est presente, plus sa ponderation est faible... */ EGAL(carre_de_la_distance_minimale_dans_l_espace_RVB,F_INFINI); /* Afin de rechercher le point le plus proche du point courant (on initialise sur une */ /* distance tres grande et donc impossible...). */ EGAL(niveau_exact_le_plus_proche,NIVEAU_UNDEF); /* Ce qui donnera a la fin de la prochaine iteration le point le plus proche en fausse */ /* couleur du point {nR,nV,nB} en vraie couleur... */ BoIn(niveau_courant,NOIR,BLANC,pas_COULEURS) Bblock EGAL(carre_de_la_distance_dans_l_espace_RVB ,ADD2(MUL2(ponderation_de_la_luminance ,EXP2(SOUS(luminance_du_point_courant,ITb1(luminance_des_couleurs,INDX(niveau_courant,NOIR)))) ) ,ADD3(MUL2(ponderation_ROUGE ,EXP2(FLOT(SOUS(ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,niveau_ROUGE ) ) ) ) ,MUL2(ponderation_VERTE ,EXP2(FLOT(SOUS(ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,niveau_VERTE ) ) ) ) ,MUL2(ponderation_BLEUE ,EXP2(FLOT(SOUS(ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ,niveau_BLEUE ) ) ) ) ) ) ); /* Calcul de la distance du point {nR,nV,nB} dit "vraies couleurs" aux 'COULEURS' points, */ /* dits "fausses couleurs", de l'espace 'RVB' et defini par les trois listes de */ /* substitution (ROUGE,VERTE,BLEUE) ; on notera que les composantes de cette distance */ /* sont ponderees afin de "rapprocher" artificiellement la couleur dominante. */ /* Enfin, on notera l'introduction d'un quatrieme axe preponderant : celui de la */ /* luminance ; en effet, il est important que ce parametre essentiel soit respecte. */ /* */ /* */ /* 'nxxx' represente les */ /* 'COULEURS' points "fausses couleurs" */ /* definis par les 'COULEURS' entrees des */ /* listes de COLORIAGE */ /* . */ /* . */ /* BLEUE ^ . */ /* | . VERTE + */ /* | * + */ /* | n117 + */ /* | * + */ /* | * n2 + */ /* | n209 + * */ /* | + n255 */ /* | * + le point 'N' dit "vraies couleurs" */ /* | n75 + + N=(nR,nV,nB) . . . sera representee en "fausses couleurs" */ /* | * + * par le niveau 'nxxx' qui est le plus pres. */ /* | n193+ nxxx * */ /* | + n197 */ /* | + * */ /* | + * n1 */ /* | + n0 */ /* |------------------------------> */ /* + ROUGE */ /* + */ /* + */ /* + */ /* + LUMINANCE */ /* */ Test(IFLT(carre_de_la_distance_dans_l_espace_RVB ,carre_de_la_distance_minimale_dans_l_espace_RVB ) ) Bblock EGAL(carre_de_la_distance_minimale_dans_l_espace_RVB ,carre_de_la_distance_dans_l_espace_RVB ); EGAL(niveau_exact_le_plus_proche,niveau_courant); /* Point courant le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ Eblock ATes Bblock Eblock ETes Eblock EBoI store_point(niveau_exact_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente a l'aide du point le plus proche parmi les 'COULEURS' points de */ /* espace 'RVB' des fausses couleurs... */ Eblock end_image RETI(imageR); Eblock EFonctionP /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E A P P R O X I M E D E S V R A I E S A U X F A U S S E S C O U L E U R S */ /* P A R P A R C O U R S L I M I T E D E L ' E S P A C E ' R V B ' : */ /* */ /*************************************************************************************************************************************/ BFonctionP #define INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes) \ SUCC(QUOD(nombre_de_points_testes,PAS_DE_VARIATION_DE_L_INCREMENT)) \ /* Lors du calcul de l'increment du niveau courant, on utilise en fait une fonction */ \ /* du nombre de points deja traites dont cette constante est l'un des parametres ; cette */ \ /* fonction est telle que l'increment varie de plus en plus vite au fur et a mesure que */ \ /* le nombre de points traites augmente (1,2,3,...). */ #define PAS_DE_VARIATION_DE_L_INCREMENT \ DEUX \ /* Lors du calcul de l'increment du niveau courant, on utilise en fait une fonction */ \ /* du nombre de points deja traites dont cette constante est l'un des parametres ; plus */ \ /* il est proche de UN, plus cela va vite, mais aussi plus il y a de defauts... */ DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_RVB_approximees(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ,carre_de_la_distance_de_voisinage ,ponderation_de_la_luminance ,ponderation_des_ponderations_des_couleurs ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle qu'elle est consideree en fausse couleurs, telle que : */ /* */ /* R(imageR) = imageA_ROUGE, */ /* V(imageR) = imageA_VERTE, */ /* B(imageR) = imageA_BLEUE. */ /* */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Image Argument-ROUGE, telle que : imageA_ROUGE=R(imageR), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Image Argument-VERTE, telle que : imageA_VERTE=V(imageR), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Image Argument-BLEUE, telle que : imageA_BLEUE=B(imageR), */ /* le passage des "vraies" aux "fausses" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(Float,carre_de_la_distance_de_voisinage)); /* Lors de l'exploration de l'espace 'RVB' on ne teste par les 'COULEURS' points, mais */ /* ceux qui sont dans une fenetre centree autour du niveau approxime trouve au coup */ /* precedent ; des qu'un point 'P' de cet espace contient dans sa sphere de voisinage */ /* (c'est-a-dire une sphere centree en 'P' et dont le carre du rayon est l'argument */ /* ici defini), on approxime le point courant avec 'P'... */ DEFV(Argument,DEFV(Float,ponderation_de_la_luminance)); /* Afin de ponderer la luminance par rapport aux niveaux {R,V,B} ; plus cette valeur est */ /* grande, plus la luminance a d'importance (cf. 'MUL2') ; 1.0 semble une bonne valeur... */ DEFV(Argument,DEFV(Float,ponderation_des_ponderations_des_couleurs)); /* Afin de ponderer les niveaux {R,V,B} entre eux ; plus cette valeur est grande, plus on */ /* privilegie une couleur par rapport aux autres (cf. 'MUL2') ; 1.0 semble une bonne valeur. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Float,DTb1(luminance_des_couleurs,COULEURS)); /* Cette table contient la luminance de chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); /* NR = niveau du point courant imageA_ROUGE(X,Y), */ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); /* NV = niveau du point courant imageA_VERTE(X,Y), */ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); /* NB = niveau du point courant imageA_BLEUE(X,Y). */ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'RVB' a */ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ DEFV(Float,INIT(luminance_du_point_courant,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant. */ DEFV(Float,INIT(ponderation_ROUGE,FLOT__UNDEF)); /* Definit une ponderation permettant d'amplifier le ROUGE si c'est la couleur dominante, */ /* la valeur obtenue est dans [0,1] telle que plus une couleur est presente, plus sa */ /* ponderation est faible, et donc plus elle se rapproche du point a approximer... */ DEFV(Float,INIT(ponderation_VERTE,FLOT__UNDEF)); /* Definit une ponderation permettant d'amplifier le VERTE si c'est la couleur dominante, */ /* la valeur obtenue est dans [0,1] telle que plus une couleur est presente, plus sa */ /* ponderation est faible, et donc plus elle se rapproche du point a approximer... */ DEFV(Float,INIT(ponderation_BLEUE,FLOT__UNDEF)); /* Definit une ponderation permettant d'amplifier le BLEUE si c'est la couleur dominante, */ /* la valeur obtenue est dans [0,1] telle que plus une couleur est presente, plus sa */ /* ponderation est faible, et donc plus elle se rapproche du point a approximer... */ DEFV(Logical,INIT(ne_pas_arreter_la_recherche,VRAI)); /* Indicateur logique de continuation de la boucle de calcul des distances. */ DEFV(Logical,INIT(on_a_atteint_le_NOIR,FAUX)); DEFV(Logical,INIT(on_a_atteint_le_BLANC,FAUX)); /* Ces deux indicateurs permettent de detecter la sortie definitive de 'niveau_courant' */ /* du segment [NOIR,BLANC]. */ DEFV(Positive,INIT(nombre_de_points_testes,UNDEF)); /* Permet de savoir combien de points en "fausses couleurs" ont ete testes pour le */ /* point en "vraies couleurs" courant. */ DEFV(Int,INIT(niveau_courant,UNDEF)); /* Definit la point courant dans l'espace 'RVB' ; on notera que c'est un 'Int' car */ /* en effet, on va rencontrer des valeurs hors de [NOIR,BLANC]... Cette variable permet */ /* donc l'indexation simultanee des listes de COLORIAGE ; pour chacune de ses valeurs */ /* dans [NOIR,BLANC] on definit donc un point en fausses couleurs de l'espace 'RVB'. */ DEFV(Int,INIT(increment_du_niveau_courant,UNDEF)); DEFV(Float,INIT(carre_de_la_distance_dans_l_espace_RVB,FLOT__UNDEF)); /* On construit a l'aide des trois listes de substitution 'RVB' et de leur Luminance, un */ /* espace a 4 dimensions. Pour chaque {X,Y} on prend un point dans chaque image Argument, */ /* ce qui donne les trois niveaux precedents {nR,nV,nB} et leur luminance 'L' ; puis on */ /* calcule la distance du point (L,nR,nV,nB) dit "vraies couleurs", aux 'COULEURS' points */ /* dits "fausses couleurs" l'espace 'RVB', afin d'en trouver le plus proche qui sera celui */ /* qui definira la fausse couleur Resultat. */ DEFV(Float,INIT(carre_de_la_distance_minimale_dans_l_espace_RVB,FLOT__UNDEF)); /* Afin de rechercher le point le plus proche du point courant. */ /* definit l'increment de parcourt des points de l'espace 'RVB' ; il vaudra (+1,-2,+3,...). */ DEFV(genere_p,INIT(niveau_approxime_le_plus_proche,NIVEAU_UNDEF)); /* Point approxime le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ BoIn(niveau_courant,NOIR,BLANC,PAS_COULEURS) Bblock EGAL(ITb1(luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,CALCUL_DE_LA_LUMINANCE(ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ) ); /* Calcul de la luminance de chacun des 'COULEURS' points de l'espace 'RVB'. */ Eblock EBoI begin_image Bblock EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ EGAL(luminance_du_point_courant ,CALCUL_DE_LA_LUMINANCE(niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ) ); /* Calcul de la luminance du point {X,Y} courant. */ EGAL(ponderation_ROUGE,COMP(MUL2(ponderation_des_ponderations_des_couleurs,______NORMALISE_NIVEAU(niveau_ROUGE)))); EGAL(ponderation_VERTE,COMP(MUL2(ponderation_des_ponderations_des_couleurs,______NORMALISE_NIVEAU(niveau_VERTE)))); EGAL(ponderation_BLEUE,COMP(MUL2(ponderation_des_ponderations_des_couleurs,______NORMALISE_NIVEAU(niveau_BLEUE)))); /* Initialisation des trois ponderations chromatiques ; la valeur obtenue est dans [0,1] */ /* telle que plus une couleur est presente, plus sa ponderation est faible... */ EGAL(ne_pas_arreter_la_recherche,VRAI); /* Afin de faire la boucle au moins une fois... */ EGAL(on_a_atteint_le_NOIR,FAUX); EGAL(on_a_atteint_le_BLANC,FAUX); /* Ces deux indicateurs permettent de detecter la sortie definitive de 'niveau_courant' */ /* du segment [NOIR,BLANC] qui n'a donc pas encore eu lieu... */ Test(IFEQ(INTY(Y),Ymin)) Bblock EGAL(niveau_courant,INTE(GRIS)); /* Lorsqu'on est sur la premiere ligne, on se positionne au milieu de [NOIR,BLANC]. */ Eblock ATes Bblock EGAL(niveau_courant,INTE(load_point(imageR,X,PREY(Y)))); /* Pour les lignes suivantes, on se positionne par rapport au point trouve precedemment */ /* a la verticale du point courant sur la ligne precedente... */ Eblock ETes CLIR(increment_du_niveau_courant); /* Definit l'increment de parcours des points de l'espace 'RVB' ; il vaudra (+1,-2,+3,...). */ CLIR(nombre_de_points_testes); /* Afin de compter les points testes dans l'espace 'RVB'. */ EGAL(carre_de_la_distance_minimale_dans_l_espace_RVB,F_INFINI); /* Afin de rechercher le point le plus proche du point courant (on initialise sur une */ /* distance tres grande et donc impossible...). */ EGAL(niveau_approxime_le_plus_proche,NIVEAU_UNDEF); /* Ce qui donnera a la fin de la prochaine iteration le point le plus proche en fausse */ /* couleur du point {nR,nV,nB} en vraie couleur... */ Tant(EST_VRAI(ne_pas_arreter_la_recherche)) Bblock INCR(niveau_courant,increment_du_niveau_courant); /* Mise-a-jour du niveau courant (c'est-a-dire l'index du point auquel on va acceder */ /* l'espace 'RVB'). */ EGAL(increment_du_niveau_courant ,NEGA(ADD2(increment_du_niveau_courant ,COND(IZGE(increment_du_niveau_courant) ,NEUT(INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes)) ,NEGA(INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes)) ) ) ) ); /* Puis changement de son increment (+1,-2,+3,-4,etc...) : */ /* */ /* ..-8..................................... */ /* . . ordre d'acces aux niveaux */ /* . ..-6........................... . / */ /* . . . . / */ /* . . ..-4................. . . / */ /* . . . . . . / */ /* . . . ..-2....... . . . / */ /* . . . . . . . ./ */ /* ------------8----6----4----2----0.+1.1----3----5----7------------> */ /* . . . . ^ . . . niveau_courant */ /* . . . .....|......+3.. . . */ /* . . . | . . */ /* . . ..........|...........+5.. . */ /* . . | . */ /* . ...............|................+7.. */ /* . | \ */ /* ............. | \ */ /* | increment */ /* niveau_courant initial */ /* */ Test(INCLff(niveau_courant,INTE(NOIR),INTE(BLANC))) Bblock INCR(nombre_de_points_testes,I); /* Comptage des points testes dans l'espace 'RVB'. */ EGAL(carre_de_la_distance_dans_l_espace_RVB ,ADD2(MUL2(ponderation_de_la_luminance ,EXP2(SOUS(luminance_du_point_courant,ITb1(luminance_des_couleurs,INDX(niveau_courant,NOIR)))) ) ,ADD3(MUL2(ponderation_ROUGE ,EXP2(FLOT(SOUS(ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,niveau_ROUGE ) ) ) ) ,MUL2(ponderation_VERTE ,EXP2(FLOT(SOUS(ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,niveau_VERTE ) ) ) ) ,MUL2(ponderation_BLEUE ,EXP2(FLOT(SOUS(ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ,niveau_BLEUE ) ) ) ) ) ) ); /* Calcul de la distance du point {nR,nV,nB} dit "vraies couleurs" a quelques points, */ /* dits "fausses couleurs", de l'espace 'RVB' et defini par les trois listes de */ /* substitution (ROUGE,VERTE,BLEUE) ; on notera que les composantes de cette distance */ /* sont ponderees afin de "rapprocher" artificiellement la couleur dominante. */ /* Enfin, on notera l'introduction d'un quatrieme axe preponderant : celui de la */ /* luminance ; en effet, il est important que ce parametre essentiel soit respecte. */ /* */ /* */ /* 'nxxx' represente les */ /* 'COULEURS' points "fausses couleurs" */ /* definis par les 'COULEURS' entrees des */ /* listes de COLORIAGE */ /* . */ /* . */ /* BLEUE ^ . */ /* | . VERTE + */ /* | * + */ /* | n117 + */ /* | * + */ /* | * n2 + */ /* | n209 + * */ /* | + n255 */ /* | * + le point 'N' dit "vraies couleurs" */ /* | n75 + + N=(nR,nV,nB) . . . sera representee en "fausses couleurs" */ /* | * + * par le niveau 'nxxx' qui est le plus pres. */ /* | n193+ nxxx * */ /* | + n197 */ /* | + * */ /* | + * n1 */ /* | + n0 */ /* |------------------------------> */ /* + ROUGE */ /* + */ /* + */ /* + */ /* + LUMINANCE */ /* */ Test(IFLT(carre_de_la_distance_dans_l_espace_RVB ,carre_de_la_distance_minimale_dans_l_espace_RVB ) ) Bblock EGAL(carre_de_la_distance_minimale_dans_l_espace_RVB ,carre_de_la_distance_dans_l_espace_RVB ); EGAL(niveau_approxime_le_plus_proche,GENP(niveau_courant)); /* Point courant le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ Test(IFET(IFNE(INTY(Y),Ymin) ,IFLE(carre_de_la_distance_minimale_dans_l_espace_RVB,carre_de_la_distance_de_voisinage) ) ) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsque l'on n'est pas sur la premiere ligne et que l'on a trouve un point de l'espace */ /* 'RVB' en fausses couleurs qui contienne dans sa sphere de voisinage le point courant en */ /* vraies couleurs, on s'arrete... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Test(IFLT(niveau_courant,INTE(NOIR))) Bblock EGAL(on_a_atteint_le_NOIR,VRAI); /* Afin de pouvoir detecter la sortie definitive de 'niveau_courant' du segment */ /* [NOIR,BLANC]. */ Eblock ATes Bblock Eblock ETes Test(IFGT(niveau_courant,INTE(BLANC))) Bblock EGAL(on_a_atteint_le_BLANC,VRAI); /* Afin de pouvoir detecter la sortie definitive de 'niveau_courant' du segment */ /* [NOIR,BLANC]. */ Eblock ATes Bblock Eblock ETes Eblock ETes Test(IFET(EST_VRAI(on_a_atteint_le_NOIR),EST_VRAI(on_a_atteint_le_BLANC))) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsqu'on est sorti definitivement de [NOIR,BLANC], on ne peut que s'arreter... */ Eblock ATes Bblock Eblock ETes Eblock ETan store_point(niveau_approxime_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente par l'approximation obtenue... */ Eblock end_image RETI(imageR); Eblock #undef INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT EFonctionP #undef PAS_DE_VARIATION_DE_L_INCREMENT #undef PONDERATION_DES_PONDERATIONS_DES_COULEURS #undef PONDERATION_DE_LA_LUMINANCE _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E D U S Y S T E M E ' R V B ' A U S Y S T E M E ' H L S ' : */ /* */ /* */ /* Definition : */ /* */ /* Le systeme HLS (Hue ou teinte, Luminance */ /* Saturation) est un systeme de couleurs a */ /* trois dimensions. */ /* */ /* */ /* ^ Luminance */ /* | */ /* | */ /* | */ /* (Blanc) 1.0 + */ /* /O\ */ /* / . \ */ /* / O \ */ /* / . . . \ */ /* / O.O \ */ /* / . . . \ */ /* / O . O \ */ /* / . . . \ */ /* / O . O \ */ /* / . . . \ */ /* / O . O \ */ /* / . . . \ */ /* Ve/t O . O J\une */ /* / . . . . . . . . . . . \ */ /* / . O . O . \ */ /* / . . . . . \ */ /* /. O . O .\ */ /* / . . . \ */ /* Cyan O - - - - O - 0.5 + - - - O - - - - O Rouge */ /* \O . . . O/ */ /* \ O O . O O / */ /* \ O . . . O / */ /* \ O O O O O O O O O O O / */ /* Bleu . . . Magenta */ /* \ O . O / */ /* \ . . . / */ /* \ O . O / */ /* \ . . . / */ /* \ O . O / */ /* \ . . . / */ /* \ O . O / */ /* \ ... / . */ /* \ O / . */ /* \ . / . ^ */ /* \ O / . | Hue (angle mesure dans le plan RVB) */ /* \./ . | */ /* (Noir) 0.0 +------------------+--------------> */ /* | 1.0 */ /* | Saturation */ /* | */ /* | */ /* */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E E X A C T D E S V R A I E S A U X F A U S S E S C O U L E U R S */ /* P A R P A R C O U R S E X H A U S T I F D E L ' E S P A C E ' H L S ' : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_HLS_exactes(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ,ponderation_Hue,ponderation_Luminance,ponderation_Saturation ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle qu'elle est consideree en fausse couleurs, telle que : */ /* */ /* R(imageR) = imageA_ROUGE, */ /* V(imageR) = imageA_VERTE, */ /* B(imageR) = imageA_BLEUE. */ /* */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Image Argument-ROUGE, telle que : imageA_ROUGE=R(imageR), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Image Argument-VERTE, telle que : imageA_VERTE=V(imageR), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Image Argument-BLEUE, telle que : imageA_BLEUE=B(imageR), */ /* le passage des "vraies" aux "fausses" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(Float,ponderation_Hue)); /* Ponderation de la teinte ('Hue') lors du calcul de la distance dans l'espace 'HLS', */ /* plus cette valeur est grande, plus la teinte a d'importance, */ DEFV(Argument,DEFV(Float,ponderation_Luminance)); /* Ponderation de la luminance ('Luminance') lors du calcul de la distance dans */ /* l'espace 'HLS', plus cette valeur est grande, plus la luminance a d'importance, */ DEFV(Argument,DEFV(Float,ponderation_Saturation)); /* Ponderation de la saturation ('Saturation') lors du calcul de la distance dans */ /* l'espace 'HLS', plus cette valeur est grande, plus la saturation a d'importance. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Float,DTb1(Hue_des_couleurs,COULEURS)); /* Cette table contient la teinte de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Luminance_des_couleurs,COULEURS)); /* Cette table contient la luminance de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Saturation_des_couleurs,COULEURS)); /* Cette table contient la saturation de chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); /* NR = niveau du point courant imageA_ROUGE(X,Y), */ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); /* NV = niveau du point courant imageA_VERTE(X,Y), */ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); /* NB = niveau du point courant imageA_BLEUE(X,Y). */ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'HLS' a */ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ DEFV(Float,INIT(Hue_du_point_courant,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant, */ DEFV(Float,INIT(Luminance_du_point_courant,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant, */ DEFV(Float,INIT(Saturation_du_point_courant,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant. */ DEFV(Float,INIT(Hue_relative,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS', */ DEFV(Float,INIT(Luminance_relative,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS', */ DEFV(Float,INIT(Saturation_relative,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS'. */ DEFV(Float,INIT(carre_de_la_distance_dans_l_espace_HLS,FLOT__UNDEF)); /* On construit a l'aide des trois listes de substitution 'RVB' converties en 'HLS', un */ /* espace a 3 dimensions. Pour chaque {X,Y} on prend un point dans chaque image Argument, */ /* ce qui donne les trois niveaux precedents {nR,nV,nB} traduit en (H,L,S) ; puis on */ /* calcule la distance du point (H,L,S) dit "vraies couleurs", aux 'COULEURS' points */ /* dits "fausses couleurs" l'espace 'HLS', afin d'en trouver le plus proche qui sera celui */ /* qui definira la fausse couleur Resultat. */ DEFV(Float,INIT(carre_de_la_distance_minimale_dans_l_espace_HLS,FLOT__UNDEF)); /* Afin de rechercher le point le plus proche du point courant. */ DEFV(genere_p,INIT(niveau_exact_le_plus_proche,NIVEAU_UNDEF)); /* Point le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ BoIn(niveau_courant,NOIR,BLANC,pas_COULEURS) Bblock PASSAGE_RVB_HLS(ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR)) ,ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour les tables de COLORIAGE. */ Eblock EBoI begin_image Bblock EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ PASSAGE_RVB_HLS(Hue_du_point_courant ,Luminance_du_point_courant ,Saturation_du_point_courant ,niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour le point {X,Y} courant. */ EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS,F_INFINI); /* Afin de rechercher le point le plus proche du point courant (on initialise sur une */ /* distance tres grande et donc impossible...). */ EGAL(niveau_exact_le_plus_proche,NIVEAU_UNDEF); /* Ce qui donnera a la fin de la prochaine iteration le point le plus proche en fausse */ /* couleur du point {nR,nV,nB} en vraie couleur... */ BoIn(niveau_courant,NOIR,BLANC,pas_COULEURS) Bblock EGAL(Hue_relative,SOUS(Hue_du_point_courant,ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)))); EGAL(Hue_relative,ABSO(Hue_relative)); Test(IFGE(Hue_relative,MOIT(ECHELLE_GENERALE_HLS))) Bblock EGAL(Hue_relative,SOUS(ECHELLE_GENERALE_HLS,Hue_relative)); /* La teinte relative est situee sur un cercle trigonometrique, d'ou ce "repliement"... */ Eblock ATes Bblock Eblock ETes EGAL(Hue_relative ,MUL2(ponderation_Hue ,Hue_relative ) ); /* Calcul de la teinte relative 'H' du point courant. */ EGAL(Luminance_relative ,MUL2(ponderation_Luminance ,SOUS(Luminance_du_point_courant,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Luminance 'L' relative du point courant. */ EGAL(Saturation_relative ,MUL2(ponderation_Saturation ,SOUS(Saturation_du_point_courant,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Saturation 'S' relative du point courant. */ EGAL(carre_de_la_distance_dans_l_espace_HLS ,ADD3(EXP2(Hue_relative) ,EXP2(Luminance_relative) ,EXP2(Saturation_relative) ) ); /* Calcul de la distance du point {nR,nV,nB} dit "vraies couleurs" aux 'COULEURS' points, */ /* dits "fausses couleurs", de l'espace 'HLS' et defini par les trois vecteurs */ /* (Hue,Luminance,Saturation) ; on notera que les composantes de cette distance */ /* sont ponderees afin de favoriser l'un ou l'autre des parametres. */ /* */ /* */ /* 'nxxx' represente les */ /* 'COULEURS' points "fausses couleurs" */ /* definis par les 'COULEURS' entrees des */ /* listes de COLORIAGE */ /* . */ /* SATURATION . */ /* ^ . */ /* | . LUMINANCE + */ /* | * + */ /* | n117 + */ /* | * + */ /* | * n2 + */ /* | n209 + * */ /* | + n255 */ /* | * + le point 'N' dit "vraies couleurs" */ /* | n75 + + N=(nR,nV,nB) . . . sera representee en "fausses couleurs" */ /* | * + * par le niveau 'nxxx' qui est le plus pres. */ /* | n193+ nxxx * */ /* | + n197 */ /* | + * */ /* | + * n1 */ /* | + n0 */ /* |------------------------------> */ /* HUE */ /* */ Test(IFLT(carre_de_la_distance_dans_l_espace_HLS ,carre_de_la_distance_minimale_dans_l_espace_HLS ) ) Bblock EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS ,carre_de_la_distance_dans_l_espace_HLS ); EGAL(niveau_exact_le_plus_proche,niveau_courant); /* Point courant le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ Eblock ATes Bblock Eblock ETes Eblock EBoI store_point(niveau_exact_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente a l'aide du point le plus proche parmi les 'COULEURS' points de */ /* espace 'HLS' des fausses couleurs... */ Eblock end_image RETI(imageR); Eblock EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E A P P R O X I M E D E S V R A I E S A U X F A U S S E S C O U L E U R S */ /* P A R P A R C O U R S L I M I T E D E L ' E S P A C E ' H L S ' ( P R E M I E R E M E T H O D E ) : */ /* */ /*************************************************************************************************************************************/ #define INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes) \ SUCC(QUOD(nombre_de_points_testes,PAS_DE_VARIATION_DE_L_INCREMENT)) \ /* Lors du calcul de l'increment du niveau courant, on utilise en fait une fonction */ \ /* du nombre de points deja traites dont cette constante est l'un des parametres ; cette */ \ /* fonction est telle que l'increment varie de plus en plus vite au fur et a mesure que */ \ /* le nombre de points traites augmente (1,2,3,...). */ BFonctionP #define PAS_DE_VARIATION_DE_L_INCREMENT \ DEUX \ /* Lors du calcul de l'increment du niveau courant, on utilise en fait une fonction */ \ /* du nombre de points deja traites dont cette constante est l'un des parametres ; plus */ \ /* il est proche de UN, plus cela va vite, mais aussi plus il y a de defauts... */ DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_HLS_approximees_1(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ,ponderation_Hue,ponderation_Luminance,ponderation_Saturation ,carre_de_la_distance_de_voisinage ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle qu'elle est consideree en fausse couleurs, telle que : */ /* */ /* R(imageR) = imageA_ROUGE, */ /* V(imageR) = imageA_VERTE, */ /* B(imageR) = imageA_BLEUE. */ /* */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Image Argument-ROUGE, telle que : imageA_ROUGE=R(imageR), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Image Argument-VERTE, telle que : imageA_VERTE=V(imageR), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Image Argument-BLEUE, telle que : imageA_BLEUE=B(imageR), */ /* le passage des "vraies" aux "fausses" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(Float,ponderation_Hue)); /* Ponderation de la teinte ('Hue') lors du calcul de la distance dans l'espace 'HLS', */ /* plus cette valeur est grande, plus la teinte a d'importance, */ DEFV(Argument,DEFV(Float,ponderation_Luminance)); /* Ponderation de la luminance ('Luminance') lors du calcul de la distance dans */ /* l'espace 'HLS', plus cette valeur est grande, plus la luminance a d'importance, */ DEFV(Argument,DEFV(Float,ponderation_Saturation)); /* Ponderation de la saturation ('Saturation') lors du calcul de la distance dans */ /* l'espace 'HLS', plus cette valeur est grande, plus la saturation a d'importance. */ DEFV(Argument,DEFV(Float,carre_de_la_distance_de_voisinage)); /* Lors de l'exploration de l'espace 'HLS' on ne teste par les 'COULEURS' points, mais */ /* ceux qui sont dans une fenetre centree autour du niveau approxime trouve au coup */ /* precedent ; des qu'un point 'P' de cet espace contient dans sa sphere de voisinage */ /* (c'est-a-dire une sphere centree en 'P' et dont le carre du rayon est l'argument */ /* ici defini), on approxime le point courant avec 'P'... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Float,DTb1(Hue_des_couleurs,COULEURS)); /* Cette table contient la teinte de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Luminance_des_couleurs,COULEURS)); /* Cette table contient la luminance de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Saturation_des_couleurs,COULEURS)); /* Cette table contient la saturation de chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); /* NR = niveau du point courant imageA_ROUGE(X,Y), */ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); /* NV = niveau du point courant imageA_VERTE(X,Y), */ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); /* NB = niveau du point courant imageA_BLEUE(X,Y). */ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'HLS' a */ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ DEFV(Float,INIT(Hue_du_point_courant,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant, */ DEFV(Float,INIT(Luminance_du_point_courant,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant, */ DEFV(Float,INIT(Saturation_du_point_courant,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant. */ DEFV(Float,INIT(Hue_relative,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS', */ DEFV(Float,INIT(Luminance_relative,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS', */ DEFV(Float,INIT(Saturation_relative,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS'. */ DEFV(Logical,INIT(ne_pas_arreter_la_recherche,VRAI)); /* Indicateur logique de continuation de la boucle de calcul des distances. */ DEFV(Logical,INIT(on_a_atteint_le_NOIR,FAUX)); DEFV(Logical,INIT(on_a_atteint_le_BLANC,FAUX)); /* Ces deux indicateurs permettent de detecter la sortie definitive de 'niveau_courant' */ /* du segment [NOIR,BLANC]. */ DEFV(Positive,INIT(nombre_de_points_testes,UNDEF)); /* Permet de savoir combien de points en "fausses couleurs" ont ete testes pour le */ /* point en "vraies couleurs" courant. */ DEFV(Int,INIT(niveau_courant,UNDEF)); /* Definit la point courant dans l'espace 'HLS' ; on notera que c'est un 'Int' car */ /* en effet, on va rencontrer des valeurs hors de [NOIR,BLANC]... Cette variable permet */ /* donc l'indexation simultanee des listes de COLORIAGE ; pour chacune de ses valeurs */ /* dans [NOIR,BLANC] on definit donc un point en fausses couleurs de l'espace 'HLS'. */ DEFV(Int,INIT(increment_du_niveau_courant,UNDEF)); DEFV(Float,INIT(carre_de_la_distance_dans_l_espace_HLS,FLOT__UNDEF)); /* On construit a l'aide des trois listes de substitution 'RVB' converties en 'HLS', un */ /* espace a 3 dimensions. Pour chaque {X,Y} on prend un point dans chaque image Argument, */ /* ce qui donne les trois niveaux precedents {nR,nV,nB} traduit en (H,L,S) ; puis on */ /* calcule la distance du point (H,L,S) dit "vraies couleurs", aux 'COULEURS' points */ /* dits "fausses couleurs" l'espace 'HLS', afin d'en trouver le plus proche qui sera celui */ /* qui definira la fausse couleur Resultat. */ DEFV(Float,INIT(carre_de_la_distance_minimale_dans_l_espace_HLS,FLOT__UNDEF)); /* Afin de rechercher le point le plus proche du point courant. */ /* definit l'increment de parcourt des points de l'espace 'HLS' ; il vaudra (+1,-2,+3,...). */ DEFV(genere_p,INIT(niveau_approxime_le_plus_proche,NIVEAU_UNDEF)); /* Point approxime le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ BoIn(niveau_courant,NOIR,BLANC,PAS_COULEURS) Bblock PASSAGE_RVB_HLS(ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR)) ,ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour les tables de COLORIAGE. */ Eblock EBoI begin_image Bblock EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ PASSAGE_RVB_HLS(Hue_du_point_courant ,Luminance_du_point_courant ,Saturation_du_point_courant ,niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour le point {X,Y} courant. */ EGAL(ne_pas_arreter_la_recherche,VRAI); /* Afin de faire la boucle au moins une fois... */ EGAL(on_a_atteint_le_NOIR,FAUX); EGAL(on_a_atteint_le_BLANC,FAUX); /* Ces deux indicateurs permettent de detecter la sortie definitive de 'niveau_courant' */ /* du segment [NOIR,BLANC] qui n'a donc pas encore eu lieu... */ Test(IFEQ(INTY(Y),Ymin)) Bblock EGAL(niveau_courant,INTE(GRIS)); /* Lorsqu'on est sur la premiere ligne, on se positionne au milieu de [NOIR,BLANC]. */ Eblock ATes Bblock EGAL(niveau_courant,INTE(load_point(imageR,X,PREY(Y)))); /* Pour les lignes suivantes, on se positionne par rapport au point trouve precedemment */ /* a la verticale du point courant sur la ligne precedente... */ Eblock ETes CLIR(increment_du_niveau_courant); /* Definit l'increment de parcours des points de l'espace 'HLS' ; il vaudra (+1,-2,+3,...). */ CLIR(nombre_de_points_testes); /* Afin de compter les points testes dans l'espace 'HLS'. */ EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS,F_INFINI); /* Afin de rechercher le point le plus proche du point courant (on initialise sur une */ /* distance tres grande et donc impossible...). */ EGAL(niveau_approxime_le_plus_proche,NIVEAU_UNDEF); /* Ce qui donnera a la fin de la prochaine iteration le point le plus proche en fausse */ /* couleur du point {nR,nV,nB} en vraie couleur... */ Tant(EST_VRAI(ne_pas_arreter_la_recherche)) Bblock INCR(niveau_courant,increment_du_niveau_courant); /* Mise-a-jour du niveau courant (c'est-a-dire l'index du point auquel on va acceder */ /* l'espace 'HLS'). */ EGAL(increment_du_niveau_courant ,NEGA(ADD2(increment_du_niveau_courant ,COND(IZGE(increment_du_niveau_courant) ,NEUT(INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes)) ,NEGA(INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes)) ) ) ) ); /* Puis changement de son increment (+1,-2,+3,-4,etc...) : */ /* */ /* ..-8..................................... */ /* . . ordre d'acces aux niveaux */ /* . ..-6........................... . / */ /* . . . . / */ /* . . ..-4................. . . / */ /* . . . . . . / */ /* . . . ..-2....... . . . / */ /* . . . . . . . ./ */ /* ------------8----6----4----2----0.+1.1----3----5----7------------> */ /* . . . . ^ . . . niveau_courant */ /* . . . .....|......+3.. . . */ /* . . . | . . */ /* . . ..........|...........+5.. . */ /* . . | . */ /* . ...............|................+7.. */ /* . | \ */ /* ............. | \ */ /* | increment */ /* niveau_courant initial */ /* */ Test(INCLff(niveau_courant,INTE(NOIR),INTE(BLANC))) Bblock INCR(nombre_de_points_testes,I); /* Comptage des points testes dans l'espace 'HLS'. */ EGAL(Hue_relative,SOUS(Hue_du_point_courant,ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)))); EGAL(Hue_relative,ABSO(Hue_relative)); Test(IFGE(Hue_relative,MOIT(ECHELLE_GENERALE_HLS))) Bblock EGAL(Hue_relative,SOUS(ECHELLE_GENERALE_HLS,Hue_relative)); /* La teinte relative est situee sur un cercle trigonometrique, d'ou ce "repliement"... */ Eblock ATes Bblock Eblock ETes EGAL(Hue_relative ,MUL2(ponderation_Hue ,Hue_relative ) ); /* Calcul de la teinte relative 'H' du point courant. */ EGAL(Luminance_relative ,MUL2(ponderation_Luminance ,SOUS(Luminance_du_point_courant,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Luminance 'L' relative du point courant. */ EGAL(Saturation_relative ,MUL2(ponderation_Saturation ,SOUS(Saturation_du_point_courant,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Saturation 'S' relative du point courant. */ EGAL(carre_de_la_distance_dans_l_espace_HLS ,ADD3(EXP2(Hue_relative) ,EXP2(Luminance_relative) ,EXP2(Saturation_relative) ) ); /* Calcul de la distance du point {nR,nV,nB} dit "vraies couleurs" aux 'COULEURS' points, */ /* dits "fausses couleurs", de l'espace 'HLS' et defini par les trois vecteurs */ /* (Hue,Luminance,Saturation) ; on notera que les composantes de cette distance */ /* sont ponderees afin de favoriser l'un ou l'autre des parametres. */ /* */ /* */ /* 'nxxx' represente les */ /* 'COULEURS' points "fausses couleurs" */ /* definis par les 'COULEURS' entrees des */ /* listes de COLORIAGE */ /* . */ /* SATURATION . */ /* ^ . */ /* | . LUMINANCE + */ /* | * + */ /* | n117 + */ /* | * + */ /* | * n2 + */ /* | n209 + * */ /* | + n255 */ /* | * + le point 'N' dit "vraies couleurs" */ /* | n75 + + N=(nR,nV,nB) . . . sera representee en "fausses couleurs" */ /* | * + * par le niveau 'nxxx' qui est le plus pres. */ /* | n193+ nxxx * */ /* | + n197 */ /* | + * */ /* | + * n1 */ /* | + n0 */ /* |------------------------------> */ /* HUE */ /* */ Test(IFLT(carre_de_la_distance_dans_l_espace_HLS ,carre_de_la_distance_minimale_dans_l_espace_HLS ) ) Bblock EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS ,carre_de_la_distance_dans_l_espace_HLS ); EGAL(niveau_approxime_le_plus_proche,GENP(niveau_courant)); /* Point courant le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ Test(IFET(IFNE(INTY(Y),Ymin) ,IFLE(carre_de_la_distance_minimale_dans_l_espace_HLS,carre_de_la_distance_de_voisinage) ) ) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsque l'on n'est pas sur la premiere ligne et que l'on a trouve un point de l'espace */ /* 'HLS' en fausses couleurs qui contienne dans sa sphere de voisinage le point courant en */ /* vraies couleurs, on s'arrete... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Test(IFLT(niveau_courant,INTE(NOIR))) Bblock EGAL(on_a_atteint_le_NOIR,VRAI); /* Afin de pouvoir detecter la sortie definitive de 'niveau_courant' du segment */ /* [NOIR,BLANC]. */ Eblock ATes Bblock Eblock ETes Test(IFGT(niveau_courant,INTE(BLANC))) Bblock EGAL(on_a_atteint_le_BLANC,VRAI); /* Afin de pouvoir detecter la sortie definitive de 'niveau_courant' du segment */ /* [NOIR,BLANC]. */ Eblock ATes Bblock Eblock ETes Eblock ETes Test(IFET(EST_VRAI(on_a_atteint_le_NOIR),EST_VRAI(on_a_atteint_le_BLANC))) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsqu'on est sorti definitivement de [NOIR,BLANC], on ne peut que s'arreter... */ Eblock ATes Bblock Eblock ETes Eblock ETan store_point(niveau_approxime_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente par l'approximation obtenue... */ Eblock end_image RETI(imageR); Eblock #undef PAS_DE_VARIATION_DE_L_INCREMENT EFonctionP /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E A P P R O X I M E D E S V R A I E S A U X F A U S S E S C O U L E U R S */ /* P A R S O U S - E C H A N T I L L O N N A G E D E S I M A G E S ( S E C O N D E M E T H O D E ) : */ /* */ /*************************************************************************************************************************************/ BFonctionP #define PAS_HORIZONTAL_HLS \ HUIT \ /* Pas horizontal ('X') de sous-echantillonnage des images Arguments, */ #define PAS_VERTICAL_HLS \ HUIT \ /* Pas vertical ('y') de sous-echantillonnage des images Arguments. */ #define PAS_DE_VARIATION_DE_L_INCREMENT \ DEUX \ /* Lors du calcul de l'increment du niveau courant, on utilise en fait une fonction */ \ /* du nombre de points deja traites dont cette constante est l'un des parametres ; plus */ \ /* il est proche de UN, plus cela va vite, mais aussi plus il y a de defauts... */ DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_HLS_approximees_2(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ,ponderation_Hue,ponderation_Luminance,ponderation_Saturation ,carre_de_la_distance_de_voisinage ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle qu'elle est consideree en fausse couleurs, telle que : */ /* */ /* R(imageR) = imageA_ROUGE, */ /* V(imageR) = imageA_VERTE, */ /* B(imageR) = imageA_BLEUE. */ /* */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Image Argument-ROUGE, telle que : imageA_ROUGE=R(imageR), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Image Argument-VERTE, telle que : imageA_VERTE=V(imageR), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Image Argument-BLEUE, telle que : imageA_BLEUE=B(imageR), */ /* le passage des "vraies" aux "fausses" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ DEFV(Argument,DEFV(Float,ponderation_Hue)); /* Ponderation de la teinte ('Hue') lors du calcul de la distance dans l'espace 'HLS', */ /* plus cette valeur est grande, plus la teinte a d'importance, */ DEFV(Argument,DEFV(Float,ponderation_Luminance)); /* Ponderation de la luminance ('Luminance') lors du calcul de la distance dans */ /* l'espace 'HLS', plus cette valeur est grande, plus la luminance a d'importance, */ DEFV(Argument,DEFV(Float,ponderation_Saturation)); /* Ponderation de la saturation ('Saturation') lors du calcul de la distance dans */ /* l'espace 'HLS', plus cette valeur est grande, plus la saturation a d'importance. */ DEFV(Argument,DEFV(Float,carre_de_la_distance_de_voisinage)); /* Lors de l'exploration de l'espace 'HLS' on ne teste par les 'COULEURS' points, mais */ /* ceux qui sont dans une fenetre centree autour du niveau approxime trouve au coup */ /* precedent ; des qu'un point 'P' de cet espace contient dans sa sphere de voisinage */ /* (c'est-a-dire une sphere centree en 'P' et dont le carre du rayon est l'argument */ /* ici defini), on approxime le point courant avec 'P'... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Float,DTb1(Hue_des_couleurs,COULEURS)); /* Cette table contient la teinte de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Luminance_des_couleurs,COULEURS)); /* Cette table contient la luminance de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Saturation_des_couleurs,COULEURS)); /* Cette table contient la saturation de chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(Int,INIT(X_noeud_courant,UNDEF)); /* Abscisse du noeud courant lors du sous-echantillonnage des images Arguments, */ DEFV(Int,INIT(Y_noeud_courant,UNDEF)); /* Ordonnee du noeud courant lors du sous-echantillonnage des images Arguments. */ DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); /* NR = niveau du point courant imageA_ROUGE(X,Y), */ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); /* NV = niveau du point courant imageA_VERTE(X,Y), */ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); /* NB = niveau du point courant imageA_BLEUE(X,Y). */ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'HLS' a */ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ DEFV(Float,INIT(Hue_du_point_courant,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant, */ DEFV(Float,INIT(Luminance_du_point_courant,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant, */ DEFV(Float,INIT(Saturation_du_point_courant,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant. */ DEFV(Float,INIT(Hue_relative,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS', */ DEFV(Float,INIT(Luminance_relative,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS', */ DEFV(Float,INIT(Saturation_relative,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant relativement a celle du point courant de */ /* de l'espace 'HLS'. */ DEFV(Logical,INIT(ne_pas_arreter_la_recherche,VRAI)); /* Indicateur logique de continuation de la boucle de calcul des distances. */ DEFV(Logical,INIT(on_a_atteint_le_NOIR,FAUX)); DEFV(Logical,INIT(on_a_atteint_le_BLANC,FAUX)); /* Ces deux indicateurs permettent de detecter la sortie definitive de 'niveau_courant' */ /* du segment [NOIR,BLANC]. */ DEFV(Positive,INIT(nombre_de_points_testes,UNDEF)); /* Permet de savoir combien de points en "fausses couleurs" ont ete testes pour le */ /* point en "vraies couleurs" courant. */ DEFV(Int,INIT(niveau_courant,UNDEF)); /* Definit la point courant dans l'espace 'HLS' ; on notera que c'est un 'Int' car */ /* en effet, on va rencontrer des valeurs hors de [NOIR,BLANC]... Cette variable permet */ /* donc l'indexation simultanee des listes de COLORIAGE ; pour chacune de ses valeurs */ /* dans [NOIR,BLANC] on definit donc un point en fausses couleurs de l'espace 'HLS'. */ DEFV(Int,INIT(increment_du_niveau_courant,UNDEF)); DEFV(Float,INIT(carre_de_la_distance_dans_l_espace_HLS,FLOT__UNDEF)); /* On construit a l'aide des trois listes de substitution 'RVB' converties en 'HLS', un */ /* espace a 3 dimensions. Pour chaque {X,Y} on prend un point dans chaque image Argument, */ /* ce qui donne les trois niveaux precedents {nR,nV,nB} traduit en (H,L,S) ; puis on */ /* calcule la distance du point (H,L,S) dit "vraies couleurs", aux 'COULEURS' points */ /* dits "fausses couleurs" l'espace 'HLS', afin d'en trouver le plus proche qui sera celui */ /* qui definira la fausse couleur Resultat. */ DEFV(Float,INIT(carre_de_la_distance_minimale_dans_l_espace_HLS,FLOT__UNDEF)); /* Afin de rechercher le point le plus proche du point courant. */ /* definit l'increment de parcourt des points de l'espace 'HLS' ; il vaudra (+1,-2,+3,...). */ DEFV(genere_p,INIT(niveau_exact_le_plus_proche,NIVEAU_UNDEF)); /* Point exact le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur */ /* pour les points du maillage de sous-echantillonnage des images Arguments... */ DEFV(genere_p,INIT(niveau_approxime_le_plus_proche,NIVEAU_UNDEF)); /* Point approxime le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur, */ /* pour les points hors du maillage de sous-echantillonnage des images Arguments... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ BoIn(niveau_courant,NOIR,BLANC,PAS_COULEURS) Bblock PASSAGE_RVB_HLS(ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR)) ,ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour les tables de COLORIAGE. */ Eblock EBoI PUSH_ECHANTILLONNAGE; /* Sauvegarde du sous-echantillonnage courant... */ SET_ECHANTILLONNAGE(PAS_HORIZONTAL_HLS,PAS_VERTICAL_HLS); /* Et mise en place d'un sous-echantillonnage sur lequel on va faire une conversion */ /* non approximee des vraies couleurs en fausses couleurs... */ begin_image Bblock EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ PASSAGE_RVB_HLS(Hue_du_point_courant ,Luminance_du_point_courant ,Saturation_du_point_courant ,niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour le point {X,Y} courant. */ EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS,F_INFINI); /* Afin de rechercher le point le plus proche du point courant (on initialise sur une */ /* distance tres grande et donc impossible...). */ EGAL(niveau_exact_le_plus_proche,NIVEAU_UNDEF); /* Ce qui donnera a la fin de la prochaine iteration le point le plus proche en fausse */ /* couleur du point {nR,nV,nB} en vraie couleur... */ BoIn(niveau_courant,NOIR,BLANC,pas_COULEURS) Bblock EGAL(Hue_relative,SOUS(Hue_du_point_courant,ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)))); EGAL(Hue_relative,ABSO(Hue_relative)); Test(IFGE(Hue_relative,MOIT(ECHELLE_GENERALE_HLS))) Bblock EGAL(Hue_relative,SOUS(ECHELLE_GENERALE_HLS,Hue_relative)); /* La teinte relative est situee sur un cercle trigonometrique, d'ou ce "repliement"... */ Eblock ATes Bblock Eblock ETes EGAL(Hue_relative ,MUL2(ponderation_Hue ,Hue_relative ) ); /* Calcul de la teinte relative 'H' du point courant. */ EGAL(Luminance_relative ,MUL2(ponderation_Luminance ,SOUS(Luminance_du_point_courant,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Luminance 'L' relative du point courant. */ EGAL(Saturation_relative ,MUL2(ponderation_Saturation ,SOUS(Saturation_du_point_courant,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Saturation 'S' relative du point courant. */ EGAL(carre_de_la_distance_dans_l_espace_HLS ,ADD3(EXP2(Hue_relative) ,EXP2(Luminance_relative) ,EXP2(Saturation_relative) ) ); /* Calcul de la distance du point {nR,nV,nB} dit "vraies couleurs" aux 'COULEURS' points, */ /* dits "fausses couleurs", de l'espace 'HLS' et defini par les trois vecteurs */ /* (Hue,Luminance,Saturation) ; on notera que les composantes de cette distance */ /* sont ponderees afin de favoriser l'un ou l'autre des parametres. */ /* */ /* */ /* 'nxxx' represente les */ /* 'COULEURS' points "fausses couleurs" */ /* definis par les 'COULEURS' entrees des */ /* listes de COLORIAGE */ /* . */ /* SATURATION . */ /* ^ . */ /* | . LUMINANCE + */ /* | * + */ /* | n117 + */ /* | * + */ /* | * n2 + */ /* | n209 + * */ /* | + n255 */ /* | * + le point 'N' dit "vraies couleurs" */ /* | n75 + + N=(nR,nV,nB) . . . sera representee en "fausses couleurs" */ /* | * + * par le niveau 'nxxx' qui est le plus pres. */ /* | n193+ nxxx * */ /* | + n197 */ /* | + * */ /* | + * n1 */ /* | + n0 */ /* |------------------------------> */ /* HUE */ /* */ Test(IFLT(carre_de_la_distance_dans_l_espace_HLS ,carre_de_la_distance_minimale_dans_l_espace_HLS ) ) Bblock EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS ,carre_de_la_distance_dans_l_espace_HLS ); EGAL(niveau_exact_le_plus_proche,niveau_courant); /* Point courant le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ Eblock ATes Bblock Eblock ETes Eblock EBoI store_point(niveau_exact_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente a l'aide du point le plus proche parmi les 'COULEURS' points de */ /* espace 'HLS' des fausses couleurs, mais uniquement sur le reseau de sous-echantillonnage */ /* des images Arguments. */ Eblock end_image PULL_ECHANTILLONNAGE; /* Restauration du sous-echantillonnage courant... */ begin_image Bblock PUSH_ECHANTILLONNAGE; /* Sauvegarde du sous-echantillonnage courant... */ SET_ECHANTILLONNAGE(PAS_HORIZONTAL_HLS,PAS_VERTICAL_HLS); /* Et mise en place d'un sous-echantillonnage en dehors du lequel on va faire une */ /* conversion approximee des vraies couleurs en fausses couleurs... */ EGAL(X_noeud_courant,INTX(X)); EGAL(Y_noeud_courant,INTY(Y)); /* Recuperation du noeud courant de sous-echantillonnage des images Arguments. */ PULL_ECHANTILLONNAGE; /* Restauration du sous-echantillonnage courant... */ Test(IFOU(IFNE(X,X_noeud_courant) ,IFNE(Y,Y_noeud_courant) ) ) Bblock /* Lorsque l'on n'est pas sur un noeud du reseau de sous-echantillonnage des images */ /* Arguments, on approxime la conversion des vraies en fausses couleurs... */ EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ PASSAGE_RVB_HLS(Hue_du_point_courant ,Luminance_du_point_courant ,Saturation_du_point_courant ,niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour le point {X,Y} courant. */ EGAL(ne_pas_arreter_la_recherche,VRAI); /* Afin de faire la boucle au moins une fois... */ EGAL(on_a_atteint_le_NOIR,FAUX); EGAL(on_a_atteint_le_BLANC,FAUX); /* Ces deux indicateurs permettent de detecter la sortie definitive de 'niveau_courant' */ /* du segment [NOIR,BLANC] qui n'a donc pas encore eu lieu... */ EGAL(niveau_courant,INTE(load_point(imageR,X_noeud_courant,Y_noeud_courant))); /* On choisit comme niveau de depart, celui du noeud courant de sous-echantillonnage des */ /* images Arguments. */ CLIR(increment_du_niveau_courant); /* Definit l'increment de parcours des points de l'espace 'HLS' ; il vaudra (+1,-2,+3,...). */ CLIR(nombre_de_points_testes); /* Afin de compter les points testes dans l'espace 'HLS'. */ EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS,F_INFINI); /* Afin de rechercher le point le plus proche du point courant (on initialise sur une */ /* distance tres grande et donc impossible...). */ EGAL(niveau_approxime_le_plus_proche,NIVEAU_UNDEF); /* Ce qui donnera a la fin de la prochaine iteration le point le plus proche en fausse */ /* couleur du point {nR,nV,nB} en vraie couleur... */ Tant(EST_VRAI(ne_pas_arreter_la_recherche)) Bblock INCR(niveau_courant,increment_du_niveau_courant); /* Mise-a-jour du niveau courant (c'est-a-dire l'index du point auquel on va acceder */ /* l'espace 'HLS'). */ EGAL(increment_du_niveau_courant ,NEGA(ADD2(increment_du_niveau_courant ,COND(IZGE(increment_du_niveau_courant) ,NEUT(INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes)) ,NEGA(INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT(nombre_de_points_testes)) ) ) ) ); /* Puis changement de son increment (+1,-2,+3,-4,etc...) : */ /* */ /* ..-8..................................... */ /* . . ordre d'acces aux niveaux */ /* . ..-6........................... . / */ /* . . . . / */ /* . . ..-4................. . . / */ /* . . . . . . / */ /* . . . ..-2....... . . . / */ /* . . . . . . . ./ */ /* ------------8----6----4----2----0.+1.1----3----5----7------------> */ /* . . . . ^ . . . niveau_courant */ /* . . . .....|......+3.. . . */ /* . . . | . . */ /* . . ..........|...........+5.. . */ /* . . | . */ /* . ...............|................+7.. */ /* . | \ */ /* ............. | \ */ /* | increment */ /* niveau_courant initial */ /* */ Test(INCLff(niveau_courant,INTE(NOIR),INTE(BLANC))) Bblock INCR(nombre_de_points_testes,I); /* Comptage des points testes dans l'espace 'HLS'. */ EGAL(Hue_relative,SOUS(Hue_du_point_courant,ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)))); EGAL(Hue_relative,ABSO(Hue_relative)); Test(IFGE(Hue_relative,MOIT(ECHELLE_GENERALE_HLS))) Bblock EGAL(Hue_relative,SOUS(ECHELLE_GENERALE_HLS,Hue_relative)); /* La teinte relative est situee sur un cercle trigonometrique, d'ou ce "repliement"... */ Eblock ATes Bblock Eblock ETes EGAL(Hue_relative ,MUL2(ponderation_Hue ,Hue_relative ) ); /* Calcul de la teinte relative 'H' du point courant. */ EGAL(Luminance_relative ,MUL2(ponderation_Luminance ,SOUS(Luminance_du_point_courant,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Luminance 'L' relative du point courant. */ EGAL(Saturation_relative ,MUL2(ponderation_Saturation ,SOUS(Saturation_du_point_courant,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR))) ) ); /* Calcul de la Saturation 'S' relative du point courant. */ EGAL(carre_de_la_distance_dans_l_espace_HLS ,ADD3(EXP2(Hue_relative) ,EXP2(Luminance_relative) ,EXP2(Saturation_relative) ) ); /* Calcul de la distance du point {nR,nV,nB} dit "vraies couleurs" aux 'COULEURS' points, */ /* dits "fausses couleurs", de l'espace 'HLS' et defini par les trois vecteurs */ /* (Hue,Luminance,Saturation) ; on notera que les composantes de cette distance */ /* sont ponderees afin de favoriser l'un ou l'autre des parametres. */ /* */ /* */ /* 'nxxx' represente les */ /* 'COULEURS' points "fausses couleurs" */ /* definis par les 'COULEURS' entrees des */ /* listes de COLORIAGE */ /* . */ /* SATURATION . */ /* ^ . */ /* | . LUMINANCE + */ /* | * + */ /* | n117 + */ /* | * + */ /* | * n2 + */ /* | n209 + * */ /* | + n255 */ /* | * + le point 'N' dit "vraies couleurs" */ /* | n75 + + N=(nR,nV,nB) . . . sera representee en "fausses couleurs" */ /* | * + * par le niveau 'nxxx' qui est le plus pres. */ /* | n193+ nxxx * */ /* | + n197 */ /* | + * */ /* | + * n1 */ /* | + n0 */ /* |------------------------------> */ /* HUE */ /* */ Test(IFLT(carre_de_la_distance_dans_l_espace_HLS ,carre_de_la_distance_minimale_dans_l_espace_HLS ) ) Bblock EGAL(carre_de_la_distance_minimale_dans_l_espace_HLS ,carre_de_la_distance_dans_l_espace_HLS ); EGAL(niveau_approxime_le_plus_proche,GENP(niveau_courant)); /* Point courant le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ Test(IFLE(carre_de_la_distance_minimale_dans_l_espace_HLS,carre_de_la_distance_de_voisinage)) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsque l'on a trouve un point de l'espace 'HLS' en fausses couleurs qui contienne */ /* dans sa sphere de voisinage le point courant en vraies couleurs, on s'arrete... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Test(IFLT(niveau_courant,INTE(NOIR))) Bblock EGAL(on_a_atteint_le_NOIR,VRAI); /* Afin de pouvoir detecter la sortie definitive de 'niveau_courant' du segment */ /* [NOIR,BLANC]. */ Eblock ATes Bblock Eblock ETes Test(IFGT(niveau_courant,INTE(BLANC))) Bblock EGAL(on_a_atteint_le_BLANC,VRAI); /* Afin de pouvoir detecter la sortie definitive de 'niveau_courant' du segment */ /* [NOIR,BLANC]. */ Eblock ATes Bblock Eblock ETes Eblock ETes Test(IFET(EST_VRAI(on_a_atteint_le_NOIR),EST_VRAI(on_a_atteint_le_BLANC))) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsqu'on est sorti definitivement de [NOIR,BLANC], on ne peut que s'arreter... */ Eblock ATes Bblock Eblock ETes Eblock ETan store_point(niveau_approxime_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente par l'approximation obtenue hors du reseau de sous-echantillonnage */ /* des images Arguments. */ Eblock ATes Bblock /* Lorsque l'on est sur un noeud de sous-echantillonnage des iamges Arguments, */ /* la conversion des vraies en fausses couleurs est parfaite, et deja faite... */ Eblock ETes Eblock end_image RETI(imageR); Eblock #undef PAS_DE_VARIATION_DE_L_INCREMENT #undef PAS_VERTICAL_HLS #undef PAS_HORIZONTAL_HLS EFonctionP #undef INCREMENT_DE_L_INCREMENT_DU_NIVEAU_COURANT _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A S S A G E A P P R O X I M E D E S V R A I E S A U X F A U S S E S C O U L E U R S */ /* P A R I N V E R S I O N D E L ' E S P A C E ' H L S ' ( T R O I S I E M E M E T H O D E ) : */ /* */ /*************************************************************************************************************************************/ BFonctionP #define COLLISION_HLS(niveau) \ NEUT(niveau) \ /* Permet de reduire l'echelle des differentes composantes 'HLS'. */ #define PSEUDO_PRODUIT_HLS(Hue,Luminance,Saturation) \ AXPB(AXPB(COLLISION_HLS(NIVR(Hue)) \ ,COLLISION_HLS(ECHELLE_GENERALE_HLS) \ ,COLLISION_HLS(NIVR(Luminance)) \ ) \ ,COLLISION_HLS(ECHELLE_GENERALE_HLS) \ ,COLLISION_HLS(NIVR(Saturation)) \ ) \ /* Calcul un pseudo-produit entre les trois grandeurs (H,L,S). */ #define H_NOIR NIVR(NOIR) \ /* Hue minimale, */ #define L_NOIR NIVR(NOIR) \ /* Luminance minimale, */ #define S_NOIR NIVR(NOIR) \ /* Saturation minimale. */ #define PSEUDO_PRODUIT_NOIR \ INTE(PSEUDO_PRODUIT_HLS(H_NOIR,L_NOIR,S_NOIR)) \ /* Pseudo-produit HSL minimal. */ #define H_BLANC ADD2(H_NOIR,TRMU(ECHELLE_GENERALE_HLS)) \ /* Hue maximale, */ #define L_BLANC ADD2(L_NOIR,TRMU(ECHELLE_GENERALE_HLS)) \ /* Luminance maximale, */ #define S_BLANC ADD2(S_NOIR,TRMU(ECHELLE_GENERALE_HLS)) \ /* Saturation maximale. */ #define PSEUDO_PRODUIT_BLANC \ INTE(PSEUDO_PRODUIT_HLS(H_BLANC,L_BLANC,S_BLANC)) \ /* Pseudo-produit HSL maximal. */ #if ( (! defined(BUG_SYSTEME_APC_GCC_too_large_stack_frames)) \ && (! defined(BUG_SYSTEME_DECALPHA_OSF1_CC_large_stack_frames_not_yet_supported)) \ ) #Aif ( (! defined(BUG_SYSTEME_APC_GCC_too_large_stack_frames)) \ && (! defined(BUG_SYSTEME_DECALPHA_OSF1_CC_large_stack_frames_not_yet_supported)) \ ) DEFV(Local,DEFV(genere_p,DTb1(espace_inverse,INTE(EXP3(COLLISION_HLS(ECHELLE_GENERALE_HLS_ENTIERE)))))); /* Voir le commentaire de la deuxieme implantation possible de 'espace_inverse'... */ #Eif ( (! defined(BUG_SYSTEME_APC_GCC_too_large_stack_frames)) \ && (! defined(BUG_SYSTEME_DECALPHA_OSF1_CC_large_stack_frames_not_yet_supported)) \ ) DEFV(Common,DEFV(FonctionP,POINTERp(Ifausses_couleurs_HLS_approximees_3(imageR ,imageA_ROUGE,imageA_VERTE,imageA_BLEUE ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle qu'elle est consideree en fausse couleurs, telle que : */ /* */ /* R(imageR) = imageA_ROUGE, */ /* V(imageR) = imageA_VERTE, */ /* B(imageR) = imageA_BLEUE. */ /* */ DEFV(Argument,DEFV(image,imageA_ROUGE)); /* Image Argument-ROUGE, telle que : imageA_ROUGE=R(imageR), */ DEFV(Argument,DEFV(image,imageA_VERTE)); /* Image Argument-VERTE, telle que : imageA_VERTE=V(imageR), */ DEFV(Argument,DEFV(image,imageA_BLEUE)); /* Image Argument-BLEUE, telle que : imageA_BLEUE=B(imageR), */ /* le passage des "vraies" aux "fausses" couleurs se faisant par */ /* l'intermediaire des trois listes de substitution de COLORIAGE. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Float,DTb1(Hue_des_couleurs,COULEURS)); /* Cette table contient la teinte de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Luminance_des_couleurs,COULEURS)); /* Cette table contient la luminance de chacune des 'COULEURS' points de l'espace 'RVB', */ DEFV(Float,DTb1(Saturation_des_couleurs,COULEURS)); /* Cette table contient la saturation de chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(Int,DTb1(pseudo_produit_HLS,COULEURS)); /* Cette table contient une fonction de (H,L,S) calcule par 'PSEUDO_PRODUIT_HLS' pour */ /* chacune des 'COULEURS' points de l'espace 'RVB'. */ DEFV(Logical,INIT(ne_pas_arreter_la_recherche,VRAI)); /* Indicateur logique de continuation de la boucle de recherche du premier point de */ /* l'espace inverse contenant exactement une entree des listes de COLORIAGE. */ DEFV(Int,INIT(pseudo_produit_courant,UNDEF)); /* Index d'acces a l'espace inverse. */ #if ( (! defined(BUG_SYSTEME_APC_GCC_too_large_stack_frames)) \ && (! defined(BUG_SYSTEME_DECALPHA_OSF1_CC_large_stack_frames_not_yet_supported)) \ ) DEFV(genere_p,DTb1(espace_inverse,INTE(EXP3(COLLISION_HLS(ECHELLE_GENERALE_HLS_ENTIERE))))); /* Cette table va contenir pour chaque triplet (H,L,S) possible (ce qui fait beacoup...) */ /* un niveau d'acces (le plus proche...) aux listes de COLORIAGE {R,V,B}. */ /* */ /* */ /* espace_inverse listes de substitution */ /* dites de COLORIAGE */ /* 3 ------- */ /* BLANC | | */ /* | | */ /* | | */ /* |.....| */ /* . . . . . .> HLS : | N |. . . . . . */ /* . |.....| . */ /* . | | . ------------------- */ /* . | | . BLANC | | | | */ /* . | | . | | | | */ /* . | | . | | | | */ /* . | | . |.....|.....|.....| */ /* . | | . . . . .> N : | R | V | B | */ /* point | | |.....|.....|.....| */ /* courant | | | | | | */ /* {R,V,B} | | | | | | */ /* (H,L,S) | | NOIR | | | | */ /* | | ------------------- */ /* | | */ /* | | */ /* | | */ /* | | */ /* | | ('HLS' designe le pseudo-produit-HLS */ /* 3 | | du point courant en vraies couleurs) */ /* NOIR | | */ /* ------- */ /* */ /* On notera que cette methode possede un defaut important : elle permet de trouver la */ /* bonne teinte ('H'), en general, mais malheureusement au detriment d'une mauvaise */ /* luminance ('L') ce qui s'explique bien par le remplissage puis l'acces a la table */ /* de l'espace inverse... */ #Aif ( (! defined(BUG_SYSTEME_APC_GCC_too_large_stack_frames)) \ && (! defined(BUG_SYSTEME_DECALPHA_OSF1_CC_large_stack_frames_not_yet_supported)) \ ) #Eif ( (! defined(BUG_SYSTEME_APC_GCC_too_large_stack_frames)) \ && (! defined(BUG_SYSTEME_DECALPHA_OSF1_CC_large_stack_frames_not_yet_supported)) \ ) DEFV(genere_p,INIT(niveau_ROUGE,NIVEAU_UNDEF)); /* NR = niveau du point courant imageA_ROUGE(X,Y), */ DEFV(genere_p,INIT(niveau_VERTE,NIVEAU_UNDEF)); /* NV = niveau du point courant imageA_VERTE(X,Y), */ DEFV(genere_p,INIT(niveau_BLEUE,NIVEAU_UNDEF)); /* NB = niveau du point courant imageA_BLEUE(X,Y). */ /* Ces trois niveaux determinent un point {nR,nV,nB} appartenant a un espace 'HLS' a */ /* trois dimensions ; on qualifiera ce point de "vraies couleurs". */ DEFV(Float,INIT(Hue_du_point_courant,FLOT__UNDEF)); /* Donne la teinte du point {X,Y} courant, */ DEFV(Float,INIT(Luminance_du_point_courant,FLOT__UNDEF)); /* Donne la luminance du point {X,Y} courant, */ DEFV(Float,INIT(Saturation_du_point_courant,FLOT__UNDEF)); /* Donne la saturation du point {X,Y} courant. */ DEFV(genere_p,INIT(niveau_approxime_le_plus_proche,NIVEAU_UNDEF)); /* Point approxime le plus proche en fausse couleur du point {nR,nV,nB} en vraie couleur... */ /*..............................................................................................................................*/ MISE_A_L_ETAT_INITIAL_LISTE_DE_SUBSTITUTION; /* Au cas ou elles n'auraient pas encore ete initialisees... */ DoIn(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR,PSEUDO_PRODUIT_BLANC,PAS_COULEURS) Bblock EGAL(ITb1(espace_inverse ,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR) ) ,NOIR ); /* Initialisation a NOIR de l'espace inverse. */ Eblock EDoI BoIn(niveau_courant,NOIR,BLANC,PAS_COULEURS) Bblock PASSAGE_RVB_HLS(ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR)) ,ACCES_listes_de_substitution(L_SUBSTITUTION_ROUGE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_VERTE,niveau_courant) ,ACCES_listes_de_substitution(L_SUBSTITUTION_BLEUE,niveau_courant) ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour les tables de COLORIAGE. */ EGAL(ITb1(pseudo_produit_HLS,INDX(niveau_courant,NOIR)) ,INTE(ADD2(PSEUDO_PRODUIT_HLS(ITb1(Hue_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Luminance_des_couleurs,INDX(niveau_courant,NOIR)) ,ITb1(Saturation_des_couleurs,INDX(niveau_courant,NOIR)) ) ,PSEUDO_PRODUIT_NOIR ) ) ); /* Puis calcul du pseudo-produit pour les tables de COLORIAGE. */ EGAL(ITb1(espace_inverse ,INDX(ITb1(pseudo_produit_HLS,INDX(niveau_courant,NOIR)),PSEUDO_PRODUIT_NOIR) ) ,niveau_courant ); /* Mise en place dans l'espace inverse des entrees correspondant exactement a des entrees */ /* des listes de COLORIAGE 'RVB'. */ Eblock EBoI EGAL(ne_pas_arreter_la_recherche,VRAI); /* Afin de faire la boucle au moins une fois... */ EGAL(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR); /* Afin de partir sur la premiere entree de l'espace inverse... */ Tant(EST_VRAI(ne_pas_arreter_la_recherche)) Bblock Test(IFNE(ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR)),NOIR)) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsque l'on trouve une entree non NOIR, on est sur que c'est le premier point de */ /* l'espace inverse correspondant exactement a une entree des listes de COLORIAGE ; on peut */ /* donc s'arreter... */ Eblock ATes Bblock Test(IFEQ(ITb1(pseudo_produit_HLS,INDX(NOIR,NOIR)),pseudo_produit_courant)) Bblock EGAL(ne_pas_arreter_la_recherche,FAUX); /* Lorsque l'on trouve une entree NOIR, il faut faire la difference entre la valeur mise */ /* initialement dans l'espace inverse ('NOIR') et l'entree 'NOIR' des listes de COLORIAGE ; */ /* lorsque l'on a trouve cette derniere, on peut s'arreter... */ Eblock ATes Bblock Test(IFGE(pseudo_produit_courant,PSEUDO_PRODUIT_BLANC)) Bblock PRINT_ATTENTION("les listes COLORIAGE semblent etre completement NOIR"); EGAL(ne_pas_arreter_la_recherche,FAUX); /* Et il faut s'arreter... */ Eblock ATes Bblock INCR(pseudo_produit_courant,PAS_COULEURS); /* Lorsqu'on a trouve une entree vide, il faut passer a la suivante lorsqu'elle existe... */ Eblock ETes Eblock ETes Eblock ETes Eblock ETan EGAL(niveau_approxime_le_plus_proche,ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR))); /* On fixe ainsi le premier niveau approxime le plus proche avec la premiere entree */ /* "significative" de l'espace inverse... */ DoIn(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR,PSEUDO_PRODUIT_BLANC,PAS_COULEURS) Bblock Test(IFNE(ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR)),NOIR)) Bblock EGAL(niveau_approxime_le_plus_proche,ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR))); /* Lorsque l'on trouve une entree non NOIR, on est sur que ce n'est pas un "trou" dans */ /* l'espace inverse ; il correspond exactement a une entree des listes de COLORIAGE ; */ /* on peut donc la prendre comme niveau approxime courant... */ Eblock ATes Bblock Test(IFEQ(ITb1(pseudo_produit_HLS,INDX(NOIR,NOIR)),pseudo_produit_courant)) Bblock EGAL(niveau_approxime_le_plus_proche,ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR))); /* Lorsque l'on trouve une entree NOIR, il faut faire la difference entre la valeur mise */ /* initialement dans l'espace inverse ('NOIR') et l'entree 'NOIR' des listes de COLORIAGE ; */ /* lorsque l'on a trouve cette derniere, on peut la prendre comme niveau approxime courant. */ Eblock ATes Bblock EGAL(ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR)),niveau_approxime_le_plus_proche); /* Enfin, lorsque l'on a trouve un vrai "trou" de l'espace inverse, on le bouche grace a */ /* la valeur du niveau approxime courant... */ Eblock ETes Eblock ETes Eblock EDoI begin_image Bblock EGAL(niveau_ROUGE,load_point(imageA_ROUGE,X,Y)); EGAL(niveau_VERTE,load_point(imageA_VERTE,X,Y)); EGAL(niveau_BLEUE,load_point(imageA_BLEUE,X,Y)); /* Generation pour {X,Y} du point {nR,nV,nB} en vraies couleurs dans l'espace 'RVB'... */ PASSAGE_RVB_HLS(Hue_du_point_courant ,Luminance_du_point_courant ,Saturation_du_point_courant ,niveau_ROUGE ,niveau_VERTE ,niveau_BLEUE ); /* Passage de l'espace 'RVB' a l'espace 'HLS' pour le point {X,Y} courant. */ EGAL(pseudo_produit_courant ,ADD2(PSEUDO_PRODUIT_HLS(Hue_du_point_courant ,Luminance_du_point_courant ,Saturation_du_point_courant ) ,PSEUDO_PRODUIT_NOIR ) ); /* Puis calcul du pseudo-produit pour le point courant, */ EGAL(niveau_approxime_le_plus_proche,ITb1(espace_inverse,INDX(pseudo_produit_courant,PSEUDO_PRODUIT_NOIR))); /* Et inversion de l'espace... */ store_point(niveau_approxime_le_plus_proche,imageR,X,Y,FVARIABLE); /* Finalement, le point en vraie couleur {nR,nV,nB} issu des trois images Argument */ /* est represente par l'approximation obtenue... */ Eblock end_image RETI(imageR); Eblock #undef PSEUDO_PRODUIT_BLANC #undef S_BLANC #undef L_BLANC #undef H_BLANC #undef PSEUDO_PRODUIT_NOIR #undef S_NOIR #undef L_NOIR #undef H_NOIR #undef PSEUDO_PRODUIT_HLS #undef COLLISION_HLS EFonctionP _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E S M A T R I C E S ' M O D U L E ' E T ' A R G U M E N T ' */ /* A P A R T I R D E D E U X M A T R I C E S ' P A R T I E S R E E L L E S ' */ /* E T ' P A R T I E S I M A G I N A I R E S ' : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Iconversion_XY_RT(moduleR ,phaseR ,partie_reelleA ,partie_imaginaireA ) ) ) DEFV(Argument,DEFV(imageF,moduleR)); /* Matrice flottante dans laquelle se trouveront les modules au retour, */ DEFV(Argument,DEFV(imageF,phaseR)); /* Matrice flottante dans laquelle se trouveront les arguments au retour dans [0,2.PI]. */ DEFV(Argument,DEFV(imageF,partie_reelleA)); /* Matrice flottante dans laquelle se trouvent les parties reelles a l'appel, */ DEFV(Argument,DEFV(imageF,partie_imaginaireA)); /* Matrice flottante dans laquelle se trouvent les parties imaginaires a l'appel. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock DEFV(complexe,point_courant); /* Nombre complexe courant dont on cherche le module et la phase. */ Cinitialisation(point_courant ,loadF_point(partie_reelleA,X,Y) ,loadF_point(partie_imaginaireA,X,Y) ); /* Recuperation du nombre complexe courant au point {X,Y}. */ storeF_point(Cmodule(point_courant) ,moduleR ,X,Y ); /* Calcul du module du point courant, */ storeF_point(Cargument_2PI(point_courant) ,phaseR ,X,Y ); /* Et de sa phase dans [0,2.PI]. */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E S M A T R I C E S ' P A R T I E S R E E L L E S ' E T */ /* ' P A R T I E S I M A G I N A I R E S ' A P A R T I R D E S D E U X */ /* M A T R I C E S ' M O D U L E ' E T ' P H A S E ' : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Iconversion_RT_XY(partie_reelleR ,partie_imaginaireR ,moduleA ,phaseA ) ) ) DEFV(Argument,DEFV(imageF,partie_reelleR)); /* Matrice flottante dans laquelle se trouvent les parties reelles au retour, */ DEFV(Argument,DEFV(imageF,partie_imaginaireR)); /* Matrice flottante dans laquelle se trouvent les parties imaginaires au retour. */ DEFV(Argument,DEFV(imageF,moduleA)); /* Matrice flottante dans laquelle se trouveront les modules a l'appel, */ DEFV(Argument,DEFV(imageF,phaseA)); /* Matrice flottante dans laquelle se trouveront les arguments a l'appel dans [0,2.PI]. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock storeF_point(Xcartesienne_2D(loadF_point(moduleA,X,Y),loadF_point(phaseA,X,Y)) ,partie_reelleR ,X,Y ); /* Calcul de la partie reelle du point courant (X = R.cos(t)), */ storeF_point(Ycartesienne_2D(loadF_point(moduleA,X,Y),loadF_point(phaseA,X,Y)) ,partie_imaginaireR ,X,Y ); /* Et de sa partie imaginaire (Y = R.sin(t)). */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N S P H E R I Q U E --> C A R T E S I E N N E D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ #define GENERE__FonctionF_conver_RPT_XYZ(nom_et_arguments_de_la_fonction,Fconversion) \ /* Ce generateur a ete introduit le 20080920090807... */ \ DEFV(FonctionF,POINTERF(nom_et_arguments_de_la_fonction)) \ /* Fonction introduite le 20080918142402. */ \ DEFV(Argument,DEFV(imageF,iR)); \ /* Image Resultat, telle que : iR=Fconversion(iAR,iAP,iAT). */ \ DEFV(Argument,DEFV(imageF,iAR)); \ /* Premiere image Argument definissant 'RHO', */ \ DEFV(Argument,DEFV(imageF,iAP)); \ /* Seconde image Argument definissant 'PHI', */ \ DEFV(Argument,DEFV(imageF,iAT)); \ /* Troisieme image Argument definissant 'THETA'. */ \ /*-----------------------------------------------------------------------------------------------------------------------------------*/ \ Bblock \ /*..............................................................................................................................*/ \ begin_image \ Bblock \ storeF_point(ADD2(Fconversion(loadF_point(iAR,X,Y) \ ,loadF_point(iAP,X,Y) \ ,loadF_point(iAT,X,Y) \ ) \ ,NomDeLaFonctionCourante QD@@__ _____Post___Translation \ ) \ ,iR \ ,X,Y \ ); \ Eblock \ end_image \ \ RETIF(iR); \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N S P H E R I Q U E --> C A R T E S I E N N E { X } D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Float,SINT(IFconversion_RPT_X_____Post___Translation,FZERO))); DEFV(Common,GENERE__FonctionF_conver_RPT_XYZ(IFconversion_RPT_X(iR,iAR,iAP,iAT),Xcartesienne_3D)) /* Common,DEFV(Fonction,) : */ EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N S P H E R I Q U E --> C A R T E S I E N N E { Y } D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Float,SINT(IFconversion_RPT_Y_____Post___Translation,FZERO))); DEFV(Common,GENERE__FonctionF_conver_RPT_XYZ(IFconversion_RPT_Y(iR,iAR,iAP,iAT),Ycartesienne_3D)) /* Common,DEFV(Fonction,) : */ EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N S P H E R I Q U E --> C A R T E S I E N N E { Z } D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Float,SINT(IFconversion_RPT_Z_____Post___Translation,FZERO))); DEFV(Common,GENERE__FonctionF_conver_RPT_XYZ(IFconversion_RPT_Z(iR,iAR,iAP,iAT),Zcartesienne_3D)) /* Common,DEFV(Fonction,) : */ EFonctionF #undef GENERE__FonctionF_conver_RPT_XYZ _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N {Rho,Phi,Theta} --> {X,Y,Z} : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Iconversion_RPT_XYZ(matriceR_X___ ,matriceR_Y___ ,matriceR_Z___ ,matriceA_Rho_ ,matriceA_Phi_ ,matriceA_Theta ) ) ) /* Fonction introduite le 20191115110616... */ DEFV(Argument,DEFV(imageF,matriceR_X___)); DEFV(Argument,DEFV(imageF,matriceR_Y___)); DEFV(Argument,DEFV(imageF,matriceR_Z___)); /* Matrices {X,Y,Z} Resultats. */ DEFV(Argument,DEFV(imageF,matriceA_Rho_)); DEFV(Argument,DEFV(imageF,matriceA_Phi_)); DEFV(Argument,DEFV(imageF,matriceA_Theta)); /* Matrices {Rho,Phi,Theta} Arguments. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock storeF_point(Xcartesienne_3D(loadF_point(matriceA_Rho_,X,Y),loadF_point(matriceA_Phi_,X,Y),loadF_point(matriceA_Theta,X,Y)) ,matriceR_X___ ,X,Y ); storeF_point(Ycartesienne_3D(loadF_point(matriceA_Rho_,X,Y),loadF_point(matriceA_Phi_,X,Y),loadF_point(matriceA_Theta,X,Y)) ,matriceR_Y___ ,X,Y ); storeF_point(Zcartesienne_3D(loadF_point(matriceA_Rho_,X,Y),loadF_point(matriceA_Phi_,X,Y),loadF_point(matriceA_Theta,X,Y)) ,matriceR_Z___ ,X,Y ); /* Et conversion {Rho,Phi,Theta} --> {X,Y,Z}... */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N C A R T E S I E N N E --> S P H E R I Q U E D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ #define GENERE__FonctionF_conver_XYZ_RPT(nom_et_arguments_de_la_fonction,Fconversion) \ /* Ce generateur a ete introduit le 20080920090807... */ \ DEFV(FonctionF,POINTERF(nom_et_arguments_de_la_fonction)) \ /* Fonction introduite le 20080918142402. */ \ DEFV(Argument,DEFV(imageF,iR)); \ /* Image Resultat, telle que : iR=Fconversion(iAX,iAY,iAZ). */ \ DEFV(Argument,DEFV(imageF,iAX)); \ /* Premiere image Argument definissant 'X', */ \ DEFV(Argument,DEFV(imageF,iAY)); \ /* Seconde image Argument definissant 'Y', */ \ DEFV(Argument,DEFV(imageF,iAZ)); \ /* Troisieme image Argument definissant 'Z'. */ \ /*-----------------------------------------------------------------------------------------------------------------------------------*/ \ Bblock \ /*..............................................................................................................................*/ \ begin_image \ Bblock \ storeF_point(Fconversion(SOUS(loadF_point(iAX,X,Y),NomDeLaFonctionCourante QD@@__ _____PreAntiTranslation_X) \ ,SOUS(loadF_point(iAY,X,Y),NomDeLaFonctionCourante QD@@__ _____PreAntiTranslation_Y) \ ,SOUS(loadF_point(iAZ,X,Y),NomDeLaFonctionCourante QD@@__ _____PreAntiTranslation_Z) \ ) \ ,iR \ ,X,Y \ ); \ Eblock \ end_image \ \ RETIF(iR); \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N C A R T E S I E N N E --> S P H E R I Q U E { RHO } D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_R_____PreAntiTranslation_X,FZERO))); DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_R_____PreAntiTranslation_Y,FZERO))); DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_R_____PreAntiTranslation_Z,FZERO))); DEFV(Common,GENERE__FonctionF_conver_XYZ_RPT(IFconversion_XYZ_R(iR,iAX,iAY,iAZ),Rho_3D)) /* Common,DEFV(Fonction,) : */ EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N C A R T E S I E N N E --> S P H E R I Q U E { PHI } D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_P_____PreAntiTranslation_X,FZERO))); DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_P_____PreAntiTranslation_Y,FZERO))); DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_P_____PreAntiTranslation_Z,FZERO))); DEFV(Common,GENERE__FonctionF_conver_XYZ_RPT(IFconversion_XYZ_P(iR,iAX,iAY,iAZ),Phi_3D)) /* Common,DEFV(Fonction,) : */ EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N C A R T E S I E N N E --> S P H E R I Q U E { THETA } D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_T_____PreAntiTranslation_X,FZERO))); DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_T_____PreAntiTranslation_Y,FZERO))); DEFV(Common,DEFV(Float,SINT(IFconversion_XYZ_T_____PreAntiTranslation_Z,FZERO))); DEFV(Common,GENERE__FonctionF_conver_XYZ_RPT(IFconversion_XYZ_T(iR,iAX,iAY,iAZ),Theta_3D)) /* Common,DEFV(Fonction,) : */ EFonctionF #undef GENERE__FonctionF_conver_XYZ_RPT _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N {X,Y,Z} --> {Rho,Phi,Theta} : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Iconversion_XYZ_RPT(matriceR_Rho_ ,matriceR_Phi_ ,matriceR_Theta ,matriceA_X___ ,matriceA_Y___ ,matriceA_Z___ ) ) ) /* Fonction introduite le 20191115110616... */ DEFV(Argument,DEFV(imageF,matriceR_Rho_)); DEFV(Argument,DEFV(imageF,matriceR_Phi_)); DEFV(Argument,DEFV(imageF,matriceR_Theta)); /* Matrices {X,Y,Z} --> {Rho,Phi,Theta} Resultats. */ DEFV(Argument,DEFV(imageF,matriceA_X___)); DEFV(Argument,DEFV(imageF,matriceA_Y___)); DEFV(Argument,DEFV(imageF,matriceA_Z___)); /* Matrices {X,Y,Z} Arguments. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ /*..............................................................................................................................*/ begin_image Bblock storeF_point(Rho_3D(loadF_point(matriceA_X___,X,Y),loadF_point(matriceA_Y___,X,Y),loadF_point(matriceA_Z___,X,Y)) ,matriceR_Rho_ ,X,Y ); storeF_point(Phi_3D(loadF_point(matriceA_X___,X,Y),loadF_point(matriceA_Y___,X,Y),loadF_point(matriceA_Z___,X,Y)) ,matriceR_Phi_ ,X,Y ); storeF_point(Theta_3D(loadF_point(matriceA_X___,X,Y),loadF_point(matriceA_Y___,X,Y),loadF_point(matriceA_Z___,X,Y)) ,matriceR_Theta ,X,Y ); /* Et conversion {X,Y,Z} --> {Rho,Phi,Theta}... */ Eblock end_image RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* S U I V I D U G R A D I E N T D A N S U N E S T R U C T U R E T R I - D I M E N S I O N N E L L E : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,Isuivi_du_gradient(imageAR,facteur_multiplicatif_du_gradient,imageA1,imageA2,imageA3))) DEFV(Argument,DEFV(imageJ,imageAR)); /* Image Argument et Resultat donnant en chaque point le cumul du gradient local. */ /* */ /* */ /* imageA3 ------------------------ Z+1 */ /* | /| | */ /* | X/ | | */ /* imageA2 ------------------------ Z | */ /* | /| . | | */ /* | / | . | | */ /* imageA1 ------------------------ Z-1| | */ /* | . . . | | | */ /* | . . . | | | */ /* | . . . | | | */ /* | . .. | | | */ /* | . P........|---|Y | */ /* | . . | |--- */ /* | .. | | */ /* | . | | */ /* | |--- */ /* | | */ /* | | */ /* ------------------------ */ /* */ /* au point P(X,Y,Z), on calcule le gradient local a partir des trois images Argument, */ /* avec la formule : */ /* */ /* soit 'Mb' la matrice "de brouillage" courante ('imageAR'), et */ /* */ /* Xf = R(Mb(X,Y)) ('R' designe la partie Reelle), */ /* Yf = I(Mb(X,Y)) ('I' designe la partie Imaginaire). */ /* */ /* ( I2(Xf+Px,Yf)-I2(Xf-Px,Yf) I2(Xf,Yf+Py)-I2(Xf,Yf-Py) I3(Xf,Yf)-I1(Xf,Yf) ) */ /* G = (--------------------------- , --------------------------- , ---------------------) */ /* ( 2.Px 2.Py 2.Pz ) */ /* */ /* enfin, la matrice "de brouillage" est mise a jour de la facon suivante : */ /* */ /* Gx */ /* R(Mb(X,Y)) = R(Mb(X,Y)) + facteur.----- */ /* |G| */ /* */ /* Gy */ /* I(Mb(X,Y)) = I(Mb(X,Y)) + facteur.----- */ /* |G| */ /* */ /* Ainsi, partant d'un etat initial de 'Mb' obtenu par la fonction */ /* 'IJinitialisation_matrice_de_brouillage()', on peut se deplacer dans une structure */ /* tridimensionnelle d'images (I(0), I(1),... ,I(n-1), I(n), I(n+1),...) en suivant le */ /* gradient local et en mettant a jour a chaque pas le long de l'axe 'OZ' la matrice 'Mb' */ /* par la fonction 'Isuivi_du_gradient()'... */ DEFV(Argument,DEFV(Float,facteur_multiplicatif_du_gradient)); /* Afin d'accentuer ou diminuer les effets du gradient local... */ DEFV(Argument,DEFV(image,imageA1)); /* Premiere image Argument, */ DEFV(Argument,DEFV(image,imageA2)); /* Seconde image Argument, */ DEFV(Argument,DEFV(image,imageA3)); /* Troisieme image Argument. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */ /* ('BDEFV','EDEFV') suivraient... */ DEFV(deltaF_3D,gradient_local_tri_dimensionnel); /* Gradient local (Gx,Gy,Gz). */ DEFV(Float,INIT(module_du_gradient_local_tri_dimensionnel,FLOT__UNDEF)); /* Module |G| du gradient local (Gx,Gy,Gz). */ DEFV(complexe,valeur_initiale); /* Valeur initiale du gradient local bi-dimensionnel. */ BDEFV(imageJ,gradient_local_bi_dimensionnel); /* Image intermediaire complexe destinee a memoriser : */ /* */ /* Gx Gy */ /* (facteur.-----,facteur.-----) */ /* |G| |G| */ /* */ /* appele ici 'gradient local bi-dimensionnel'. */ DEFV(Float,INIT(Xf,FLOT__UNDEF)); DEFV(Float,INIT(Yf,FLOT__UNDEF)); /* Coordonnees flottantes 'Xf' et 'Yf'. */ /*..............................................................................................................................*/ Cinitialisation(valeur_initiale,FZERO,FZERO); CALS(IJinitialisation(gradient_local_bi_dimensionnel,ADRESSE(valeur_initiale))); /* Initialisation du gradient local bi-dimensionnel avec (0,0). */ begin_image Bblock EGAL(Xf,loadRJ_point(imageAR,X,Y)); EGAL(Yf,loadIJ_point(imageAR,X,Y)); /* Recuperation des coordonnees "brouillees" courantes dans [0,1]. */ Test(TEST_DANS_L_IMAGE(_cDENORMALISE_OX(Xf),_cDENORMALISE_OY(Yf))) Bblock INITIALISATION_ACCROISSEMENT_3D(gradient_local_tri_dimensionnel ,DIVI(SOUS(______NORMALISE_NIVEAU(load_point_valide(imageA2 ,SUCX(_cDENORMALISE_OX(Xf)) ,NEUT(_cDENORMALISE_OY(Yf)) ) ) ,______NORMALISE_NIVEAU(load_point_valide(imageA2 ,PREX(_cDENORMALISE_OX(Xf)) ,NEUT(_cDENORMALISE_OY(Yf)) ) ) ) ,_____lNORMALISE_OX(DOUB(pasX)) ) ,DIVI(SOUS(______NORMALISE_NIVEAU(load_point_valide(imageA2 ,NEUT(_cDENORMALISE_OX(Xf)) ,SUCY(_cDENORMALISE_OY(Yf)) ) ) ,______NORMALISE_NIVEAU(load_point_valide(imageA2 ,NEUT(_cDENORMALISE_OX(Xf)) ,PREY(_cDENORMALISE_OY(Yf)) ) ) ) ,_____lNORMALISE_OY(DOUB(pasY)) ) ,DIVI(SOUS(______NORMALISE_NIVEAU(load_point_valide(imageA3 ,NEUT(_cDENORMALISE_OX(Xf)) ,NEUT(_cDENORMALISE_OY(Yf)) ) ) ,______NORMALISE_NIVEAU(load_point_valide(imageA1 ,NEUT(_cDENORMALISE_OX(Xf)) ,NEUT(_cDENORMALISE_OY(Yf)) ) ) ) ,_____lNORMALISE_OZ(DOUB(pasZ)) ) ); /* Calcul des trois composantes du gradient local au point {Xf,Yf}. */ EGAL(module_du_gradient_local_tri_dimensionnel ,longF3D(gradient_local_tri_dimensionnel) ); /* Calcul du module |G| du gradient local au point {Xf,Yf}. */ Test(IZNE(module_du_gradient_local_tri_dimensionnel)) Bblock storeRJ_point(SCAL(ASD1(gradient_local_tri_dimensionnel,dx) ,module_du_gradient_local_tri_dimensionnel ,facteur_multiplicatif_du_gradient ) ,gradient_local_bi_dimensionnel ,X,Y ); storeIJ_point(SCAL(ASD1(gradient_local_tri_dimensionnel,dy) ,module_du_gradient_local_tri_dimensionnel ,facteur_multiplicatif_du_gradient ) ,gradient_local_bi_dimensionnel ,X,Y ); /* Mise a jour des parties Reelle et Imaginaire du gradient local bi-dimensionnel, */ /* uniquement lorsque le module n'est pas nulle, et que {Xf,Yf} est dans l'image... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock end_image CALS(IJaddition_complexe(imageAR,imageAR,gradient_local_bi_dimensionnel)); /* Et mise a jour de la matrice "de brouillage" Argument a l'aide du gradient local */ /* bi-dimensionnel... */ EDEFV(imageJ,gradient_local_bi_dimensionnel); /* Image intermediaire complexe destinee a memoriser : */ /* */ /* Gx Gy */ /* (facteur.-----,facteur.-----) */ /* |G| |G| */ /* */ /* appele ici 'gradient local bi-dimensionnel'. */ RETU_ERROR; Eblock EFonctionI _______________________________________________________________________________________________________________________________________ _______________________________________________________________________________________________________________________________________ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T I O N D ' U N A U T O S T E R E O G R A M M E : */ /* */ /* */ /* O-oo::o:-o%o:o:-O-oo::o:-o%o:o:-O-oo::o:-o%o:o:-O-oo::o:-o%o:o:- */ /* -oo::O:.-::oOoo:-oo::O:.-::oOoo:-oo::O:.-::oOoo:-oo::O:.-::oOoo: */ /* :o:-OoO.-:OOo:o::o:-OoO.-:OOo:o::o:-OoO.-:OOo:o::o:-OoO.-:OOo:o: */ /* :o::::-OOOO-:oOo:o::::-OOOO-:oOo-o::::-OOOO-:oOo-o::::-OOOO-:oOo */ /* ::-o-o.o:oO:-oo-::-o-o.ooOo-oo-::-:::-::oOo-oo-::-:::-::oOo-oo-: */ /* :o-::oo::.:oo:Oo:o-::oo:.oooOo:o-::oo:.-ooo-%o:o-::oo:.-ooo-%o:o */ /* ::o-:O:o.o:ooooo::::O::o:o-oOo:--:%o-Ooo-ooO::::-:%o-Ooo-ooO:::: */ /* O-o-oOOoOOo:o:--oo-OOOOoooo:o:-oo-OO%O:oo::o-O-o-:OO%O:oo::o-O-o */ /* -o:-:o::oOo-::O-o::o:::OOo:-::O-o::o::oOo-::::o:-:o:::oOo-::::o: */ /* o-:-oO-o:ooo:o:-::oO::o::ooo:o:-::oO::o::oo::-:OoOOo-:o::oo::-:O */ /* :o-:::%::O:O-O:oo::::O%::O:O-O:oo::::O%::O:o%:.:::::o%%::O:o%:.: */ /* :-:::-oo::%-:-:-:o:::-oo::%-:-:-:o:::-oo::%-:--o:::--ooo::%-:--o */ /* :-o::Ooooo-:-%O-:OO-:Ooooo-:-%O-:OO-:Ooooo-:-O::O-oooooooo-:-O:: */ /* :::ooooOoOoo::o::-oooooOoOoo::o::-oooooOoOoo::o::o:OOoo%oOoo::o: */ /* o:oooo:::Ooo:-oo::oooo:::Ooo:-oo::oooo:::Ooo:-o:::o::::::Ooo:-o: */ /* :o::o::oO-:-.:::o:::o::oO-:-.:::o:::o::oO-:-.::o::o:::o:O-:-.::o */ /* o-oo:O::-oOoO-o:-ooo:O::-oOoO-o:-ooo:O::-oOoO-o-oo-Oo::--oOoO-o- */ /* o-o::oo:oo-::::-:oO::oo:oo-::::-:oO::oo:oo-:::::oo:OOoo:oo-::::: */ /* -o::-o:O-O-:oo-o::-:-o:O-O-:oo-o::-:-o:O-O-:ooo:-:-oo:oO-O-:ooo: */ /* O:Ooo:o:ooo:OoO:OOooo:o:ooo:OoO:OOooo:o:ooo:oo:%ooo::O::ooo:oo:% */ /* o:oO-o:oo::%Ooo:oO:-o::oo::%Ooo:oO:-o::oo:::ooOO--oo:::oo:::ooOO */ /* ::O:o-o:o::oO:-:o:o:-Oo:o::oO:-:o:o:-Oo:o:oO%:%oo:--:Oo:o:oO%:%o */ /* O.-:ooOOoo:ooo%O.:ooOO:ooo-Ooo%O.:oo%Oooo:oooo.-:ooO%Oooo:oooo.- */ /* O.o::-O:oo:o::o--o:.O:oo:o:o:O--o:.Ooo:o:o:O-O.o:o.Ooo:o:o:O-O.o */ /* oOO:-oo::oo%oo-:ooo-oo-ooOO:-o:oo-Oo:OooO:--ooOoo-Oo:OooO:--ooOo */ /* ooo:oO:Ooo:oo%o:ooo:o:OooO:#o:ooO:ooOoo-O:%%o:ooO:ooOoo-O:%%o:oo */ /* oo:ooo-o%-:%o:o:oo:ooo-OO-%ooo-oo:Oo:::%:-%ooo-oo:Oo:::%:-%ooo-o */ /* O:O:o:o:%::Oo:oOO:O:o:o:%::Oo:oOO:O:o:o:%::Oo:oOO:O:o:o:%::Oo:oO */ /* Oo:o:o:-Oo::oo-oOo:o:o:-Oo::oo-oOo:o:o:-Oo::oo-oOo:o:o:-Oo::oo-o */ /* ::::o::::o:ooO-O::::o::::o:ooO-O::::o::::o:ooO-O::::o::::o:ooO-O */ /* :o:-o::o-::::%Oo:o:-o::o-::::%Oo:o:-o::o-::::%Oo:o:-o::o-::::%Oo */ /* :o::::OO%-o::::.:o::::OO%-o::::.:o::::OO%-o::::.:o::::OO%-o::::. */ /* */ /* */ /* obtenu par : */ /* */ /* $xci/stereogra.01$X T=$xiio/BAND_RDN.11.41 C=$xT/ANNEAU pf=0.25 | $xci/liste$X */ /* */ /* ou la periode de la trame de camouflage est "compatible" avec l'echantillonnage "standard" de 'v $xci/liste$K'. */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(Logical,SINT(fX_CIRCULAIRE_____compatibilite_20110602,FAUX))); /* Permet de generer des images suivant la methode anterieure au 20110602170556 en */ /* ce qui concerne la periodisation des abscisses ('X'). */ #define X_CIRCULAIRE(x,periode_horizontale) \ COND(IL_FAUT(fX_CIRCULAIRE_____compatibilite_20110602) \ ,COXA(FiMODS(COXR(x),COXR(Xmin),_lDENORMALISE_OX(periode_horizontale))) \ ,_cDENORMALISE_OX(FfMODF(_____cNORMALISE_OX(x),_____cNORMALISE_OX(Xmin),periode_horizontale)) \ ) \ /* Definition d'une abscisse 'X' "circulaire" destinee a acceder aux lignes de la trame */ \ /* courante. ATTENTION, j'ai utilise pendant quelques temps : */ \ /* */ \ /* MODU(x,Xmin,COXA(_?DENORMALISE_OX(periode_horizontale))) */ \ /* */ \ /* mais la nouvelle definition semble plus logique. */ \ /* */ \ /* Puis j'ai utilise : */ \ /* */ \ /* COXA(MODU(COXR(x),COXR(Xmin),_?DENORMALISE_OX(periode_horizontale))) */ \ /* */ \ /* ce qui donnait, a cause de la fonction 'MODU(...)' tres "lourde" le message : */ \ /* */ \ /* cc: Internal error 7108: Investigation required - Please contact HP Support. */ \ /* */ \ /* sur 'SYSTEME_HP755_HPUX_CC' ; j'ai donc simplifie avec 'MODS(...)'. Malheureusement, */ \ /* cela ne fut pas suffisant, d'ou la fonction 'Local' suivante... */ \ /* */ \ /* Jusqu'au 20110615100551, la procedure 'X_CIRCULAIRE(...)' etait donc definie simplement */ \ /* a l'aide des procedures 'MODS(...)' et 'MODF(...)'. Malheureusement, sur '$LACT16' et */ \ /* sur '$LACT17' la compilation de cette fonction durait longtemps (abortee au bout de deux */ \ /* heures sur '$LACT16'...), alors que sur '$LACT18' ou '$CMAP28' cela ne posait aucun */ \ /* probleme, d'ou leur remplacement par 'FiMODS(...)' et 'FfMODF(...)' respectivement... */ DEFV(Local,DEFV(FonctionI,fX_CIRCULAIRE(abscisse,periode_horizontale))) DEFV(Argument,DEFV(Int,abscisse)); /* Abscisse que l'on veut "circulariser". */ DEFV(Argument,DEFV(Float,periode_horizontale)); /* Periode horizontale... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ RETU(X_CIRCULAIRE(abscisse,periode_horizontale)); Eblock #undef X_CIRCULAIRE EFonctionI DEFV(Common,DEFV(Logical,ZINT(GENERATION_D_UN_AUTOSTEREOGRAMME_____compatibilite_20110610,FAUX))); /* Permet de generer des images suivant la methode anterieure au 20110610103109 en */ /* ce qui concerne l'utilisation d'un 'TRNF(...)' ci-apres... */ #define GENERATION_D_UN_AUTOSTEREOGRAMME(TypeDecalage,ConversionDecalage,LoadPointCote,NormalisationNiveauEventuelle) \ /* Procedure introduite le 20110601184115... */ \ Bblock \ BDEFV(imageF,trame_courante); \ /* Trame courante (au cours du processus de periodisation...). */ \ /* */ \ /* Le 20110610095403 elle est passee du type 'image' au type 'imageF' et ce afin de */ \ /* pouvoir se debarasser d'un 'TRNF(...)' ci-apres... */ \ BDEFV(imageF,autostereogramme); \ /* Autostereogramme (introduit le 20110610095403). */ \ \ DEFV(Int,INIT(periode_horizontale_normalisee_a_forcer_dans_la_trame \ ,DIMENSION(Xmin,_lDENORMALISE_OX(periode_horizontale_a_forcer_dans_la_trame)) \ ) \ ); \ /* Periode horizontale a forcer dans la texture 'trameA' et definie dans [Xmin,Xmax]. */ \ /* On notera la fonction 'DIMENSION(...)' due a la definition de '_lDENORMALISE_OX(...)' */ \ /* via celle de '_?DENORMALISE_AXES(...)' qui elle-meme reference 'LONGUEUR(...)' ; tout */ \ /* cela signifie que '_lDENORMALISE_OX(...)' renvoie des coordonnees, et qu'il faut donc */ \ /* ensuite convertir celles-ci en dimensions (ou "nombre de points")... */ \ DEFV(Int,INIT(periode_horizontale_normalisee_intrinseque_de_la_trame \ ,DIMENSION(Xmin,_lDENORMALISE_OX(periode_horizontale_intrinseque_de_la_trame)) \ ) \ ); \ /* Periode horizontale intrinseque de la texture 'trameA' et definie dans [Xmin,Xmax]. */ \ /* On notera la fonction 'DIMENSION(...)' due a la definition de '_lDENORMALISE_OX(...)' */ \ /* via celle de '_?DENORMALISE_AXES(...)' qui elle-meme reference 'LONGUEUR(...)' ; tout */ \ /* cela signifie que '_lDENORMALISE_OX(...)' renvoie des coordonnees, et qu'il faut donc */ \ /* ensuite convertir celles-ci en dimensions (ou "nombre de points")... */ \ \ Test(IFET(IL_FAUT(repartir_les_points_de_la_trame),IL_FAUT(interpoler_la_trame))) \ Bblock \ PRINT_ATTENTION("l'option de repartition des points de la trame l'emporte sur l'interpolation de celle-ci"); \ /* Message introduit le 20110607162644... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IFOU(IZLE(periode_horizontale_a_forcer_dans_la_trame),IZLE(periode_horizontale_intrinseque_de_la_trame))) \ Bblock \ PRINT_ATTENTION("l'une au moins des deux periodes est negative ou nulle"); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IFGE(COXR(Xmin),_lDENORMALISE_OX(periode_horizontale_a_forcer_dans_la_trame))) \ Bblock \ PRINT_ATTENTION("le calcul de 'X_CIRCULAIRE(...)' via la fonction 'MODS(...)' sera incorrect"); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IZLT(facteur_multiplicatif)) \ Bblock \ PRINT_ATTENTION("le facteur multiplicatif du champ de cote ne peut etre negatif : resultat non garanti"); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IFGE(DECALAGE_DE_X(NormalisationNiveauEventuelle(BLANC)) \ ,periode_horizontale_normalisee_a_forcer_dans_la_trame \ ) \ ) \ Bblock \ PRINT_ATTENTION("le facteur multiplicatif du champ de cote est trop grand par rapport a la periode a forcer"); \ /* Il y a en effet un risque fort de repliement du decalage de la trame... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IFET(IFGT(periode_horizontale_normalisee_a_forcer_dans_la_trame \ ,periode_horizontale_normalisee_intrinseque_de_la_trame \ ) \ ,NON_DIVISIBLE(periode_horizontale_normalisee_a_forcer_dans_la_trame \ ,periode_horizontale_normalisee_intrinseque_de_la_trame \ ) \ ) \ ) \ Bblock \ PRINT_ATTENTION("les deux periodes normalisees ne sont pas commensurables"); \ CAL1(Prer1("periode horizontale normalisee a forcer dans la trame = %d\n" \ ,periode_horizontale_normalisee_a_forcer_dans_la_trame \ ) \ ); \ CAL1(Prer1("periode horizontale normalisee intrinseque dans la trame = %d\n" \ ,periode_horizontale_normalisee_intrinseque_de_la_trame \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ CALS(Istd_float_brutal(trame_courante,trameA)); \ /* Recuperation de l'integralite de chaque ligne de la trame (bien qu'en fait seule */ \ /* 'periode_horizontale_a_forcer_dans_la_trame' pour-cent situe au debut de chacune, */ \ /* a partir de 'Xmin', en soit en realite utilise...). */ \ \ begin_colonne \ Bblock \ DEFV(TypeDecalage,INIT(decalage_horizontal_du_point_precedent \ ,DECALAGE_DE_X(NormalisationNiveauEventuelle(NOIR)) \ ) \ ); \ /* Decalage absolu de la trame pour le point precedent (X-1,Y). On notera que cette valeur */ \ /* initiale suppose bien entendu que 'facteur_multiplicatif' est positif ou nul... */ \ begin_ligneQ(DoIn,Xmin,Xmax,pasX) \ /* ATTENTION, il est imperatif que 'begin_ligneQ' utilise la fonction 'DoIn(...)', ce qui */ \ /* signifie que les coordonnees sont traitees de facon croissante (de 'Xmin' a 'Xmax'), car */ \ /* en effet, cela est exploite ci-apres dans le decalage de la trame... */ \ Bblock \ DEFV(TypeDecalage,INIT(decalage_horizontal,DECALAGE_DE_X(LoadPointCote(champ_de_cote,X,Y)))); \ /* Decalage absolu de la trame pour le point courant {X,Y}. */ \ DEFV(TypeDecalage,INIT(decalage_horizontal_effectif,UNDEF)); \ EGAL(decalage_horizontal_effectif \ ,COND(IFOU(IL_FAUT(autoriser_les_permutations_horizontales_de_la_trame) \ ,IFLE(SOUS(decalage_horizontal_du_point_precedent \ ,decalage_horizontal \ ) \ ,pasX \ ) \ ) \ ,decalage_horizontal \ ,SOUS(decalage_horizontal_du_point_precedent,pasX) \ ) \ ); \ /* Decalage absolu de la trame reellement utilise pour le point courant {X,Y}. On notera */ \ /* l'initialisation de 'decalage_horizontal_effectif' en deux temps (via un 'INIT(...)' */ \ /* puis un 'EGAL(...)') afin de garantir la validite de 'decalage_horizontal'... */ \ \ Repe(QUOE(periode_horizontale_normalisee_a_forcer_dans_la_trame \ ,periode_horizontale_normalisee_intrinseque_de_la_trame \ ) \ ) \ /* ATTENTION, on notera que lorsque 'QUOE(...)' est effective, c'est-a-dire lorsque les */ \ /* deux periodes ne sont pas commensurables, il y a un risque de recouvrement... */ \ Bblock \ DEFV(Int,INIT(Xperiodique \ ,fX_CIRCULAIRE(ADD2(X \ ,MUL2(SOUS(compteur_des_repetitions_du_Repe \ ,PREMIERE_ITERATION_D_UN_Repe \ ) \ ,periode_horizontale_normalisee_intrinseque_de_la_trame \ ) \ ) \ ,periode_horizontale_a_forcer_dans_la_trame \ ) \ ) \ ); \ /* Definition d'une coordonnee "periodique" destinee a suivre l'eventuelle periodicite */ \ /* intrinseque de la texture... */ \ Test(IL_NE_FAUT_PAS(repartir_les_points_de_la_trame)) \ /* Possibilite introduite le 20110607162644 ('v $xtc/stereogra.11$c'). */ \ Bblock \ DEFV(genere_Float,INIT(niveau_decale,NIVEAU_UNDEF)); \ /* Niveau a attribuer au point courant de la trame apres decalage... */ \ \ Test(IL_NE_FAUT_PAS(interpoler_la_trame)) \ Bblock \ EGAL(niveau_decale \ ,loadF_point(trame_courante \ ,fX_CIRCULAIRE(ADD2(Xperiodique \ ,ConversionDecalage(decalage_horizontal_effectif) \ ) \ ,periode_horizontale_a_forcer_dans_la_trame \ ) \ ,Y \ ) \ ); \ /* Niveau a attribuer au point courant de la trame apres decalage lorsqu'il n'y a pas */ \ /* d'interpolation... */ \ Eblock \ ATes \ Bblock \ DEFV(Float,INIT(cumul_des_niveaux,FZERO)); \ /* Cumul des niveaux en vue de leur interpolation, */ \ DEFV(Int,INIT(nombre_de_niveaux_cumules,ZERO)); \ /* Et leur nombre... */ \ \ begin_ligneQ(DoIn \ ,COND(IZGE(decalage_horizontal_effectif) \ ,Xperiodique \ ,ADD2(Xperiodique,ConversionDecalage(decalage_horizontal_effectif)) \ ) \ ,COND(IZGE(decalage_horizontal_effectif) \ ,ADD2(Xperiodique,ConversionDecalage(decalage_horizontal_effectif)) \ ,Xperiodique \ ) \ ,pasX \ ) \ Bblock \ INCR(cumul_des_niveaux \ ,NIVR(loadF_point(trame_courante \ ,fX_CIRCULAIRE(X,periode_horizontale_a_forcer_dans_la_trame) \ ,Y \ ) \ ) \ ); \ INCR(nombre_de_niveaux_cumules,I); \ /* Cumul et decompte des niveaux a interpoler... */ \ Eblock \ end_ligneQ(EDoI) \ \ EGAL(niveau_decale,NIVA(DIVZ(cumul_des_niveaux,nombre_de_niveaux_cumules))); \ /* Niveau a attribuer au point courant de la trame apres decalage lorsqu'il y a */ \ /* d'interpolation... */ \ Eblock \ ETes \ \ storeF_point(niveau_decale \ ,trame_courante \ ,fX_CIRCULAIRE(Xperiodique,periode_horizontale_a_forcer_dans_la_trame) \ ,Y \ ); \ /* Decalage circulaire du debut de la ligne courante de la trame ; en fait, la fraction de */ \ /* ligne decalee depend du rapport des deux periodes ("a forcer" et "intrinseque")... */ \ /* */ \ /* Je note le 20110603145409 que c'est fort probablement ce decalage des points de */ \ /* 'trame_courante' qui se fait donc evidemment par pas entier (!) qui est responsable */ \ /* d'une degradation progressive de la gauche vers la droite des textures. Cela se voit, par */ \ /* exemple, sur une texture faite de barres verticales avec un champ de cote gaussien : les */ \ /* lignes verticales, au lieu de se courber "gentiment" et regulierement, donnent de plus en */ \ /* plus (de la gauche vers la droite) de marches d'escalier chaotiques et irregulieres... */ \ /* Les erreurs d'arrondi correspondant ici a ce passage flottant a entier se cumulent donc */ \ /* de gauche a droite et ainsi s'amplifient... D'avoir donne en option le type 'Float' a */ \ /* 'decalage_horizontal' et 'decalage_horizontal_effectif' est donc certainement d'aucune */ \ /* utilite... */ \ /* */ \ /* Je confirme le 20110603173113 que lorsque 'decalage_horizontal' est de type 'Float', */ \ /* il n'est en general pas entier, mais c'est sa partie entiere qui intervient lors des */ \ /* differentes indexations de 'trame_courante'... */ \ Eblock \ ATes \ Bblock \ DEFV(genere_Float,INIT(niveau_decale_a_gauche,FLOT__NIVEAU_UNDEF)); \ DEFV(genere_Float,INIT(niveau_decale_a_droite,FLOT__NIVEAU_UNDEF)); \ /* Niveau a attribuer au point courant de la trame apres decalage... */ \ \ DEFV(Float,INIT(fXperiodique_decale,ADD2(FLOT(Xperiodique),decalage_horizontal_effectif))); \ DEFV(Int,INIT(Xperiodique_decale,UNDEF)); \ DEFV(Float,INIT(parametre_d_interpolation,FLOT__UNDEF)); \ EGAL(Xperiodique_decale,INTE(fXperiodique_decale)); \ EGAL(parametre_d_interpolation,SOUS(fXperiodique_decale,FLOT(Xperiodique_decale))); \ /* Valeur de 'Xperiodique' decale de 'decalage_horizontal_effectif'... */ \ \ EGAL(niveau_decale_a_gauche \ ,BARY(loadF_point(trame_courante \ ,fX_CIRCULAIRE(NEUT(Xperiodique_decale) \ ,periode_horizontale_a_forcer_dans_la_trame \ ) \ ,Y \ ) \ ,loadF_point(trame_courante \ ,fX_CIRCULAIRE(NEUT(Xperiodique) \ ,periode_horizontale_a_forcer_dans_la_trame \ ) \ ,Y \ ) \ ,NEUT(parametre_d_interpolation) \ ) \ ); \ /* Niveau a donner au point 'NEUT(Xperiodique)'... */ \ \ Test(IL_FAUT(GENERATION_D_UN_AUTOSTEREOGRAMME_____compatibilite_20110610)) \ Bblock \ EGAL(niveau_decale_a_gauche,TRNF(niveau_decale_a_gauche)); \ /* Le 20110610103109, cette instruction de troncation dans [NOIR,BLANC] a pu etre supprimee */ \ /* (tout en restant accessible) en donnant a 'trame_courante' et a 'autostereogramme' le */ \ /* type 'imageF' (au lieu de 'image'...). */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EGAL(niveau_decale_a_droite \ ,BARY(loadF_point(trame_courante \ ,fX_CIRCULAIRE(SUCX(Xperiodique_decale) \ ,periode_horizontale_a_forcer_dans_la_trame \ ) \ ,Y \ ) \ ,loadF_point(trame_courante \ ,fX_CIRCULAIRE(SUCX(Xperiodique) \ ,periode_horizontale_a_forcer_dans_la_trame \ ) \ ,Y \ ) \ ,COMP(parametre_d_interpolation) \ ) \ ); \ /* Niveau a donner au point 'SUCX(Xperiodique)'... */ \ \ Test(IL_FAUT(GENERATION_D_UN_AUTOSTEREOGRAMME_____compatibilite_20110610)) \ Bblock \ EGAL(niveau_decale_a_droite,TRNF(niveau_decale_a_droite)); \ /* Le 20110610103109, cette instruction de troncation dans [NOIR,BLANC] a pu etre supprimee */ \ /* (tout en restant accessible) en donnant a 'trame_courante' et a 'autostereogramme' le */ \ /* type 'imageF' (au lieu de 'image'...). */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ storeF_point(OPC1(IL_NE_FAUT_PAS(GENERATION_D_UN_AUTOSTEREOGRAMME_____compatibilite_20110610) \ ,NEUT \ ,GENP \ ,niveau_decale_a_gauche \ ) \ ,trame_courante \ ,fX_CIRCULAIRE(NEUT(Xperiodique),periode_horizontale_a_forcer_dans_la_trame) \ ,Y \ ); \ storeF_point(OPC1(IL_NE_FAUT_PAS(GENERATION_D_UN_AUTOSTEREOGRAMME_____compatibilite_20110610) \ ,NEUT \ ,GENP \ ,niveau_decale_a_droite \ ) \ ,trame_courante \ ,fX_CIRCULAIRE(SUCX(Xperiodique),periode_horizontale_a_forcer_dans_la_trame) \ ,Y \ ); \ /* Ainsi on interpole aussi bien au niveau de la source du decalage que de sa destination... */ \ /* L'operation consiste a repartir, en particulier, un pixel "source" sur deux pixels */ \ /* "destination" (ce qui est logique puisqu'en general le decalage n'est pas entier) selon */ \ /* les formules : */ \ /* */ \ /* T(Xp+0) = (1-L).T((Xp+D)+0) + L.T(Xp+0) ("gauche" : +0) */ \ /* T(Xp+1) = L.T((Xp+D)+1) + (1-L).T(Xp+1) ("droite" : +1) */ \ /* ------- ----------- ------- */ \ /* | | | */ \ /* | | ---> contenu anterieur */ \ /* | | des pixels "destination" */ \ /* | | avant le decalage */ \ /* | | */ \ /* | ---------------------> contenu des pixels */ \ /* | "source" que l'on decale */ \ /* | */ \ /* ---------------------------------------> contenu des pixels */ \ /* "destination" apres le */ \ /* decalage */ \ /* */ \ /* ou : */ \ /* */ \ /* T = Texture 'trame_courante', */ \ /* Xp = abscisse entiere 'Xperiodique', */ \ /* D = Decalage 'decalage_horizontal_effectif', */ \ /* L = parametre d'interpolation 'parametre_d_interpolation' ("Lambda"). */ \ /* */ \ /* */ \ /* en n'oubliant pas que les abscisses ci-dessus sont en fait gerees "modulo" via la */ \ /* fonction 'fX_CIRCULAIRE' afin de respecter la periodicite de la Texture... */ \ Eblock \ ETes \ Eblock \ ERep \ \ EGAL(decalage_horizontal_du_point_precedent,decalage_horizontal_effectif); \ /* Et memorisation du futur decalage du point precedent... */ \ \ storeF_point(loadF_point(trame_courante,fX_CIRCULAIRE(X,periode_horizontale_a_forcer_dans_la_trame),Y) \ ,autostereogramme \ ,X,Y \ ); \ /* Et generation du stereogramme... */ \ Eblock \ end_ligneQ(EDoI) \ Eblock \ end_colonne \ \ Test(IL_NE_FAUT_PAS(NomDeLaFonctionCourante QD@@__ _____renormaliser_l_autostereogramme_et_la_trame)) \ Bblock \ CALS(Ifloat_std_brutal(trameR,trame_courante)); \ CALS(Ifloat_std_brutal(imageR,autostereogramme)); \ /* Renvoi "brutal" de la trame et de l'autostereogramme (introduit le 20110610095403). */ \ Eblock \ ATes \ Bblock \ CALS(Ifloat_std_avec_renormalisation(trameR,trame_courante)); \ CALS(Ifloat_std_avec_renormalisation(imageR,autostereogramme)); \ /* Renvoi "renormalise" de la trame et de l'autostereogramme (introduit le 20110610095403). */ \ Eblock \ ETes \ \ EDEFV(imageF,autostereogramme); \ /* Autostereogramme (introduit le 20110610095403). */ \ EDEFV(imageF,trame_courante); \ /* Trame courante (au cours du processus de periodisation...). */ \ /* */ \ /* Le 20110610095403 elle est passee du type 'image' au type 'imageF' et ce afin de */ \ /* pouvoir se debarasser d'un 'TRNF(...)' ci-apres... */ \ Eblock BFonctionP #define DECALAGE_DE_X(niveau) \ _lDENORMALISE_OX(MUL2(facteur_multiplicatif,______NORMALISE_NIVEAU(niveau))) \ /* Fonction de transformation d'un niveau en un decalage horizontal. */ \ /* */ \ /* On notera le 20110602133555 que '_lDENORMALISE_OX(...)' utilise 'FLIN(...)' qui est */ \ /* parametrable via la variable 'v $xiii/Images$STR DENORMALISE_AXES_____epsilon'. Ainsi, */ \ /* il est possible de choisir, par exemple, entre 'INTE(...)' et 'ARRI(...)' avec */ \ /* l'argument : */ \ /* */ \ /* EpsilonAxes=0 ==> INTE(...) */ \ /* EpsilonAxes=0.5 ==> ARRI(...) */ \ /* */ \ /* accessible a tous les '$K's et en particulier a 'v $xci/stereogra.01$K'... */ DEFV(Common,DEFV(Logical,SINT(Iautostereogramme_____renormaliser_l_autostereogramme_et_la_trame,FAUX))); /* Introduit le 20110610095403, la valeur par defaut garantissant la compatibilite */ /* anterieure... */ DEFV(Common,DEFV(FonctionP,POINTERp(Iautostereogramme(imageR ,trameR ,trameA ,facteur_multiplicatif,champ_de_cote ,periode_horizontale_a_forcer_dans_la_trame ,periode_horizontale_intrinseque_de_la_trame ,autoriser_les_permutations_horizontales_de_la_trame ,interpoler_la_trame ,repartir_les_points_de_la_trame ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=trameA mise en relief par 'champ_de_cote'. */ DEFV(Argument,DEFV(image,trameR)); /* Image Resultat donnant la trame de codage stereoscopique a la fin du processus. */ DEFV(Argument,DEFV(image,trameA)); /* Premiere image Argument definissant la trame de codage stereoscopique. */ DEFV(Argument,DEFV(Float,facteur_multiplicatif)); DEFV(Argument,DEFV(image,champ_de_cote)); /* Seconde image Argument definissant le champ de cote multiplie par le facteur... */ DEFV(Argument,DEFV(Float,periode_horizontale_a_forcer_dans_la_trame)); /* Periode horizontale a forcer dans la texture 'trameA' et definie dans [0,1]. Elle donne */ /* donc aussi le pourcentage utile de chaque ligne de la trame... */ DEFV(Argument,DEFV(Float,periode_horizontale_intrinseque_de_la_trame)); /* Periode horizontale intrinseque de la texture 'trameA' et definie dans [0,1]. */ /* */ /* ATTENTION, on notera le point suivant pour une 'trameA' Argument strictement periodique */ /* de 'periode_horizontale_intrinseque_de_la_trame' egale a 'pi'. Pour cette trame */ /* particuliere, il y a lors equivalence entre les deux appels suivants : */ /* */ /* periode_horizontale_a_forcer_dans_la_trame = pi */ /* periode_horizontale_intrinseque_de_la_trame = 1 */ /* */ /* et : */ /* */ /* periode_horizontale_a_forcer_dans_la_trame = 1 */ /* periode_horizontale_intrinseque_de_la_trame = pi */ /* */ /* Cette equivalence n'est plus vraie si la periodicite n'est qu'approchee (ce qui est le */ /* cas des trames de type '$xiio/BAND_RDN.11.?1' puisqu'elles ont subi un filtrage par */ /* '$xci/filtre.01$X' apres avoir ete periodisee...). */ DEFV(Argument,DEFV(Logical,autoriser_les_permutations_horizontales_de_la_trame)); /* Cet indicateur permet d'autoriser ('VRAI') les permutations horizontales de points dans */ /* la trame ou les interdire ('FAUX'). Ce phenomene assez frequent se rencontre par exemple */ /* dans le cas suivant : */ /* */ /* champ_de_cote(X+0,Y) = grande valeur */ /* champ_de_cote(X+1,Y) = faible valeur */ /* */ /* Dans ces conditions on risque d'avoir : */ /* */ /* decalage_horizontal(X+0,Y) >> decalage_horizontal(X+1,Y) */ /* */ /* soit : */ /* */ /* decalage de la trame */ /* ------------------------- */ /* | ----------------------- | */ /* || || */ /* \/ || */ /* || */ /* X+0 X+1 || */ /* ----------------------------------------- */ /* | | | | | | | */ /* |BBBB|AAAA| |AAAA| |BBBB| */ /* | | | | | | | */ /* ----------------------------------------- */ /* /\ || */ /* || || */ /* | -------- | */ /* ---------- */ /* */ /* et donc une permutation de l'ordre de deux points de la texture... */ DEFV(Argument,DEFV(Logical,interpoler_la_trame)); /* Lors du decalage de la trame, cet indicateur permet d'interpoler cette derniere ('VRAI') */ /* ou pas ('FAUX'). */ DEFV(Argument,DEFV(Logical,repartir_les_points_de_la_trame)); /* Lors du decalage de la trame, cet indicateur permet de repartir les points par une */ /* procedure d'interpolation ('VRAI') ou bien de les deplacer individuellement comme des */ /* entites insecables ('FAUX'). */ /* */ /* On notera le 20110607172658 que cette option semble sans effet pour 'v $xiirv/IMPO.21', */ /* mais par contre pour 'trameA' generee par 'v $xci/random.01$K' cela est bien visible... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ GENERATION_D_UN_AUTOSTEREOGRAMME(Int,NEUT,load_point,NEUT); RETI(imageR); Eblock #undef DECALAGE_DE_X EFonctionP BFonctionP #define DECALAGE_DE_X(niveau) \ F__lDENORMALISE_OX(MUL2(facteur_multiplicatif,niveau)) \ /* Fonction de transformation d'un niveau en un decalage horizontal. */ \ /* */ \ /* On notera le 20110602133555 que '_lDENORMALISE_OX(...)' utilise 'FLIN(...)' qui est */ \ /* parametrable via la variable 'v $xiii/Images$STR DENORMALISE_AXES_____epsilon'. Ainsi, */ \ /* il est possible de choisir, par exemple, entre 'INTE(...)' et 'ARRI(...)' avec */ \ /* l'argument : */ \ /* */ \ /* EpsilonAxes=0 ==> INTE(...) */ \ /* EpsilonAxes=0.5 ==> ARRI(...) */ \ /* */ \ /* accessible a tous les '$K's et en particulier a 'v $xci/stereogra.01$K'... */ DEFV(Common,DEFV(Logical,SINT(IFautostereogramme_____renormaliser_l_autostereogramme_et_la_trame,FAUX))); /* Introduit le 20110610095403, la valeur par defaut garantissant la compatibilite */ /* anterieure... */ DEFV(Common,DEFV(FonctionP,POINTERp(IFautostereogramme(imageR ,trameR ,trameA ,facteur_multiplicatif,champ_de_cote ,periode_horizontale_a_forcer_dans_la_trame ,periode_horizontale_intrinseque_de_la_trame ,autoriser_les_permutations_horizontales_de_la_trame ,interpoler_la_trame ,repartir_les_points_de_la_trame ) ) ) ) /* Fonction introduite le 20110601184115... */ /* */ /* Je note qu'a la date du 20110605133832 il n'est pas tres utile que 'champ_de_cote' soit */ /* de type 'imageF'. En effet, de toutes facons, la trame est decalee avec des pas multiples */ /* d'un pixel (et donc entiers...). Voir 'v $xiii/quad_image$FON 20110603145409' a ce sujet. */ /* La fonction 'IFautostereogramme(...)' ne sert donc pas a grand chose a cette date... */ DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR=trameA mise en relief par 'champ_de_cote'. */ DEFV(Argument,DEFV(image,trameR)); /* Image Resultat donnant la trame de codage stereoscopique a la fin du processus. */ DEFV(Argument,DEFV(image,trameA)); /* Premiere image Argument definissant la trame de codage stereoscopique. */ DEFV(Argument,DEFV(Float,facteur_multiplicatif)); DEFV(Argument,DEFV(imageF,champ_de_cote)); /* Seconde image Argument definissant le champ de cote multiplie par le facteur... */ DEFV(Argument,DEFV(Float,periode_horizontale_a_forcer_dans_la_trame)); /* Periode horizontale a forcer dans la texture 'trameA' et definie dans [0,1]. Elle donne */ /* donc aussi le pourcentage utile de chaque ligne de la trame... */ DEFV(Argument,DEFV(Float,periode_horizontale_intrinseque_de_la_trame)); /* Periode horizontale intrinseque de la texture 'trameA' et definie dans [0,1]. */ /* */ /* ATTENTION, on notera le point suivant pour une 'trameA' Argument strictement periodique */ /* de 'periode_horizontale_intrinseque_de_la_trame' egale a 'pi'. Pour cette trame */ /* particuliere, il y a lors equivalence entre les deux appels suivants : */ /* */ /* periode_horizontale_a_forcer_dans_la_trame = pi */ /* periode_horizontale_intrinseque_de_la_trame = 1 */ /* */ /* et : */ /* */ /* periode_horizontale_a_forcer_dans_la_trame = 1 */ /* periode_horizontale_intrinseque_de_la_trame = pi */ /* */ /* Cette equivalence n'est plus vraie si la periodicite n'est qu'approchee (ce qui est le */ /* cas des trames de type '$xiio/BAND_RDN.11.?1' puisqu'elles ont subi un filtrage par */ /* '$xci/filtre.01$X' apres avoir ete periodisee...). */ DEFV(Argument,DEFV(Logical,autoriser_les_permutations_horizontales_de_la_trame)); /* Cet indicateur permet d'autoriser ('VRAI') les permutations horizontales de points dans */ /* la trame ou les interdire ('FAUX'). Ce phenomene assez frequent se rencontre par exemple */ /* dans le cas suivant : */ /* */ /* champ_de_cote(X+0,Y) = grande valeur */ /* champ_de_cote(X+1,Y) = faible valeur */ /* */ /* Dans ces conditions on risque d'avoir : */ /* */ /* decalage_horizontal(X+0,Y) >> decalage_horizontal(X+1,Y) */ /* */ /* soit : */ /* */ /* decalage de la trame */ /* ------------------------- */ /* | ----------------------- | */ /* || || */ /* \/ || */ /* || */ /* X+0 X+1 || */ /* ----------------------------------------- */ /* | | | | | | | */ /* |BBBB|AAAA| |AAAA| |BBBB| */ /* | | | | | | | */ /* ----------------------------------------- */ /* /\ || */ /* || || */ /* | -------- | */ /* ---------- */ /* */ /* et donc une permutation de l'ordre de deux points de la texture... */ DEFV(Argument,DEFV(Logical,interpoler_la_trame)); /* Lors du decalage de la trame, cet indicateur permet d'interpoler cette derniere ('VRAI') */ /* ou pas ('FAUX'). */ DEFV(Argument,DEFV(Logical,repartir_les_points_de_la_trame)); /* Lors du decalage de la trame, cet indicateur permet de repartir les points par une */ /* procedure d'interpolation ('VRAI') ou bien de les deplacer individuellement comme des */ /* entites insecables ('FAUX'). */ /* */ /* On notera le 20110607172658 que cette option semble sans effet pour 'v $xiirv/IMPO.21', */ /* mais par contre pour 'trameA' generee par 'v $xci/random.01$K' cela est bien visible... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ GENERATION_D_UN_AUTOSTEREOGRAMME(Float,INTE,loadF_point,______NORMALISE_NIVEAU); RETI(imageR); Eblock #undef DECALAGE_DE_X EFonctionP #undef GENERATION_D_UN_AUTOSTEREOGRAMME _______________________________________________________________________________________________________________________________________