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