/* filtres-tp.c - Edouard Thiel - 12/01/2001 Compilation : cc filtres-tp.c bsutil.c -o filtres-tp \ `~/helium/helium-cfg --cflags --libs` -lm Usage : filtres-tp [image-in.pgm] */ #include #include #include "bsutil.h" /* Variables globales */ He_node *princ, *panel1, *text_load, *canvas, *panel2, *mess; int c_rouge; BsMap *gbm1 = NULL, *gbm2 = NULL, *gbm3 = NULL, *gbm4 = NULL; XImage *gxi = NULL; int sobel_ok = FALSE; /*-------------------------- A L G O R I T H M E S --------------------------*/ /* * Fixe l'épaisseur du bord de bm à e, puis affecte les pixels qui sont dans * le bord de l'image, à la valeur de leur pixel miroir dans l'image. * * Exemple : e = 2 k j i j k l k j * g f e f g h g f * (les pixels de A B C D c b A B C D c b * l'intérieur de E F G H ---> g f E F G H g f * l'image sont I J K L k j I J K L k j * en majuscule) g f e f g h g f * c b a b c d c b */ void BordMiroir (BsMap *bm, int e) { /* A COMPLETER */ } /* * Filtre moyen de bm1 dans bm2 sur un voisinage L*L */ void FiltreMoyen (BsMap *bm1, BsMap *bm2, int L) { /* A COMPLETER */ } /* * Tri à bulle (optimisé par dernière permutation). */ void tri_bulle (int *v, int n) { int i, j, tmp, dp = 0; /* dp est l'indice de la dernière permutation */ while (dp < n) { j = n; for (i = n-2; i >= dp; i--) if (v[i] > v[i+1]) { j = i+1; tmp = v[j]; v[j] = v[i]; v[i] = tmp; } dp = j; } } /* * Filtre médian de bm1 dans bm2 sur un voisinage L*L */ void FiltreMedian (BsMap *bm1, BsMap *bm2, int L) { /* A COMPLETER */ } /* * Filtre de Nagao de bm1 dans bm2 */ void FiltreNagao (BsMap *bm1, BsMap *bm2) { /* A COMPLETER */ } /* * Filtre linéaire de bm1 dans bm2 */ #define FILTREMAX 11 typedef struct { int taille; /* voisinage centré taille*taille */ double coef[FILTREMAX][FILTREMAX]; /* accès : coef[y][x] */ } Filtre; void FiltreLineaire (BsMap *bm1, BsMap *bm2, Filtre *f) { /* A COMPLETER */ } /* * Filtre de Sobel en X de bm1 dans bm2 */ void FiltreSobelX (BsMap *bm1, BsMap *bm2) { /* A COMPLETER */ } /* * Filtre de Sobel en Y de bm1 dans bm2 */ void FiltreSobelY (BsMap *bm1, BsMap *bm2) { /* A COMPLETER */ } /* * Calcul du module du gradient à partir des images de Sobel en X et en Y * dans sobM */ void ModuleSobel (BsMap *sobX, BsMap *sobY, BsMap *sobM) { /* A COMPLETER */ } /* * Cherche le min et le max dans bm, puis fait une expansion de * dynamique des niveaux de gris de [min..max] à [0..255] dans bm. */ void Normaliser (BsMap *bm) { /* A COMPLETER */ } /*---------------------------- I N T E R F A C E ----------------------------*/ void init_couleurs () { c_rouge = HeAllocRgb (255, 0, 0, he_black); } void voir_image (BsMap *bm) { int l; /* On adapte la taille à l'image */ HeSetX (canvas, 0); HeSetWidth (canvas, bm ? bm->xsiz : 50); HeSetHeight (canvas, bm ? bm->ysiz : 50); HeJustify (panel2, canvas, HE_TOP); HeSetWidth (panel2, HeGetExtWidth(canvas)); HeFit (princ); HeExpand (panel2, NULL, HE_RIGHT); l = HeGetWidth (princ) - HeGetExtWidth(canvas); if (l > 0) HeSetX (canvas, l/2); HeSetMessageLabel (mess, bm ? bm->title : ""); /* On met à jour gxi et on provoque un réaffichage */ FreeXImage (gxi); gxi = NewXImageFromBsMap (bm, LUT_VGA_GREY); HePostRepaint (canvas); } void canvas_repaint_proc (He_node *hn, Window win) { if (gxi == NULL) HeDrawBg (canvas, he_black); else PaintXImage (gxi, win); } /* * Lors d'un clic de la souris dans le canvas, affiche le vecteur gradient du * point cliqué dans la couleur c_rouge. Les images du gradient en X et Y, * calculées avec Sobel, sont mémorisées dans les images globales gbm3 et gbm4. */ void canvas_event_proc (He_node *hn, He_event *hev) { if (!sobel_ok) return; /* A COMPLETER */ } void algos_proc (He_node *hn) { char *nom = HeGetButtonLabel (hn); if (gbm1 == NULL) return; SetTitleBsMap (gbm2, nom); if (strcmp (nom, "Moy3") == 0) { FiltreMoyen (gbm1, gbm2, 3); } else if (strcmp (nom, "Moy5") == 0) { FiltreMoyen (gbm1, gbm2, 5); } else if (strcmp (nom, "Moy7") == 0) { FiltreMoyen (gbm1, gbm2, 7); } else if (strcmp (nom, "Med3") == 0) { FiltreMedian (gbm1, gbm2, 3); } else if (strcmp (nom, "Med5") == 0) { FiltreMedian (gbm1, gbm2, 5); } else if (strcmp (nom, "Med7") == 0) { FiltreMedian (gbm1, gbm2, 7); } else if (strcmp (nom, "Nagao") == 0) { FiltreNagao (gbm1, gbm2); } else if (strcmp (nom, "Sobel X") == 0) { FiltreSobelX (gbm1, gbm2); Normaliser (gbm2); } else if (strcmp (nom, "Sobel Y") == 0) { FiltreSobelY (gbm1, gbm2); Normaliser (gbm2); } else if (strcmp (nom, "Sobel Mod") == 0) { FiltreSobelX (gbm1, gbm3); FiltreSobelY (gbm1, gbm4); ModuleSobel (gbm3, gbm4, gbm2); Normaliser (gbm2); SetTitleBsMap (gbm2, "Cliquer pour voir le gradient"); sobel_ok = TRUE; } voir_image (gbm2); } void quit_proc (He_node *hn) { HeQuit(0); } void load_proc (He_node *hn) { char *nom = HeGetTextValue (text_load); FreeBsMap(gbm1); gbm1 = NULL; FreeBsMap(gbm2); gbm2 = NULL; FreeBsMap(gbm3); gbm3 = NULL; FreeBsMap(gbm4); gbm4 = NULL; sobel_ok = FALSE; gbm1 = ReadBsMapFromPGM (nom, 0); if (gbm1 == NULL) { HeSimpleDialog ( HE_DIALOG_BELL, HE_DIALOG_TITLE, "Attention", HE_DIALOG_MESSAGE, "Erreur de lecture du fichier", HE_DIALOG_QUOTED, nom, HE_DIALOG_BUTTOK, "Ok", 0); } else { gbm2 = NewBsMap (gbm1->ysiz, gbm1->xsiz, 0); gbm3 = NewBsMap (gbm1->ysiz, gbm1->xsiz, 0); gbm4 = NewBsMap (gbm1->ysiz, gbm1->xsiz, 0); if (gbm2 == NULL || gbm3 == NULL || gbm4 == NULL) HeQuit(1); } voir_image (gbm1); } void reaffi_proc (He_node *hn) { voir_image (gbm1); } /*---------------------------- P R I N C I P A L ----------------------------*/ int main (int argc, char **argv) { int code_sortie; HeInit (&argc, &argv); init_couleurs (); princ = HeCreateFrame(); HeSetFrameLabel (princ, "Filtres"); panel1 = HeCreatePanel (princ); text_load = HeCreateText (panel1); HeSetTextVisibleLen (text_load, 35); HeSetTextCompletion (text_load, TRUE); HeSetTextNotifyProc (text_load, load_proc); HeSetPanelLayout (panel1, HE_LINE_FEED); HeCreateButtonP (panel1, "Charger", load_proc, NULL); HeCreateButtonP (panel1, "Reafficher", reaffi_proc, NULL); HeCreateButtonP (panel1, "Quit", quit_proc, NULL); HeSetPanelLayout (panel1, HE_LINE_FEED); HeCreateButtonP (panel1, "Moy3", algos_proc, NULL); HeCreateButtonP (panel1, "Moy5", algos_proc, NULL); HeCreateButtonP (panel1, "Moy7", algos_proc, NULL); HeCreateButtonP (panel1, "Med3", algos_proc, NULL); HeCreateButtonP (panel1, "Med5", algos_proc, NULL); HeCreateButtonP (panel1, "Med7", algos_proc, NULL); HeSetPanelLayout (panel1, HE_LINE_FEED); HeCreateButtonP (panel1, "Nagao", algos_proc, NULL); HeCreateButtonP (panel1, "Sobel X", algos_proc, NULL); HeCreateButtonP (panel1, "Sobel Y", algos_proc, NULL); HeCreateButtonP (panel1, "Sobel Mod", algos_proc, NULL); HeSetPanelLayout (panel1, HE_LINE_FEED); HeFit(panel1); canvas = HeCreateCanvas (princ); HeSetCanvasRepaintProc (canvas, canvas_repaint_proc); HeSetCanvasEventProc (canvas, canvas_event_proc); HeJustify (canvas, panel1, HE_TOP); HeMoveY (canvas, 5); panel2 = HeCreatePanel (princ); mess = HeCreateMessage (panel2); HeFit (panel2); HeJustify (panel2, canvas, HE_TOP); HeFit (princ); if (argc > 1) { HeSetTextValue (text_load, argv[1]); load_proc (text_load); } else voir_image (NULL); code_sortie = HeMainLoop (princ); FreeBsMap (gbm1); FreeBsMap (gbm2); FreeBsMap (gbm3); FreeBsMap (gbm4); FreeXImage (gxi); return code_sortie; }