Guide d'implementation d'une routine de traitement d'image pour cantata


Sommaire

  • Exemple de routine:
  • Creer une nouvelle toolboxe avec craftsman.
  • Configurer une Toolbox pour utiliser une librairie particulie`re
  • Creation d'un objet dans une nouvelle toolbox:
  • Edition d'un objet avec composer
  • Edition de l'interface utilisateur d'un objet avec GUISE

  • Exemple de routine:

    Nous allons pas a pas cre'er une toolboxe et y ajouter une routine pour binariser par un seuillage une image en niveaux de gris. Pour simplifier on ne pourra traiter que les images a` 2 dimensions qui ont des points code's sur 1 octet.

    On propose l'algo suivant:

    Debut
       Recuperer le nom du fichier image d'entree.
       Recuperer le nom de fichier image de sortie.
       Recuperer le niveau de seuil.
       Lire et copier le fichier image d'entree en memoire.
       Verifier le type de cette image (2d + points code's sur 1 octets)
       Pour Tour les points de l'image:
       Debut
          SI la valeur du point courant est > au niveau de seuil Alors
             ce point devient blanc. 
          Sinon
             ce point devient noir. 
          Fin de Si
       Fin de Pour
       Sauvegarder la nouvelle image dans le fichier de sortie.
    Fin.

    Les parametres de cette routine sont donc:

    - le nom du fichier image a traiter (est une chaine de caracteres).
    - le nom d'un fichier image de sortie (est une chaine de caracteres).
    - la valeur du seuil. (0 <= un entier <= 255).


    Creer une nouvelle toolboxe avec craftsman.

    On creer une toolboxe avec le programme craftsman:

    info1>

    info1> craftsman &.

    info1>

    Apre`s quelques instants, la fene^tre craftsman apparai^t: la liste de gauche contient les noms de toutes les toolboxes diponibles dans l'environnements khoros (n'y figure pas les toolboxes personnelles des autres utilisateurs). Le nombre de ces toolboxes est pre'cise' en haut de cette liste (1). Si vous cliquez sur le nom d'une toolbox, vous faite apparai^tre a droite la liste des objets qu'elle contient (2). Le nombre de ces objets est e'galement indique' en haut de cette liste (3):

    Les bouton "Toolbox Operations" et "Object Operations" sont des menus qui contiennent les fonctions de gestion des toolboxes et de leurs objets.

    Remarque: Les droits associe's aux toolboxes et a leurs objets sont les droits UNIX.

    Cliquez sur "Toolbox Operations" (1) pour faire apparai^tre le menu et se'lectionner l'item "Create Toolbox" (2), en relachent le bouton gauche de la souris:

    Dans la fene^tre "Creating a New Toolbox" qui apparait, positionnez le curseur de la souris dans le champs "Toolbox name" et tapez le nom de votre toolboxe (en un seul mot), soit votre login suivie de _tb(par exmple dupondj_tb). Dans le champs "Toolbox Path" vous devez indiquer le chemin complet de votre toolboxe (/user/dupondj/dupondj_tb). Le champs "Toolbox Title" n'est pas ne'cessaire mais vous pouvez y indiquer le non complet de votre toolboxe (en plusieurs mots) et en particulier le projet dans lequel vous e^tes implique'. Veillez a ce que le bouton "Development" soit se'lectionne' dans le "Toolbox Status"

    Il ne reste plus qu'a cliquer sur le bouton "Create Toolbox" (1). Si une erreur survient c'est peut e^tre que le"Toolbox Name" est deja utilise' par une autre toolboxe ou que le chemin du "Toolbox Path" existe de'ja`.


    Configurer une Toolbox pour utiliser une librairie particulie`re

    Composer permet de ge'ne'res les makefiles de compilation d'une routine. Il le fait a partir du fichier de configuration: toolbox.def.Il faut donc indiquer dans ce fichier les librairies particulie`res que l'on souhaite utiliser. Pour e'diter ce fichier vous devez, choisir l'item "Toolbox Attributes" du menu "Toolbox Operations" de composer et dans la fene^tre "Toolbox Attributes" qui apparai^t, cliquez sur le bouton "Files" (1), puis sur le bouton "Edit" de la ligne "Toolbox Imake configuration file" (2):

    Dans notre routine de Threshold nous allons utiliser la librairie KDG qui contient une serie de fonctions pour lire, ecrire et manipuler les donnees des fichier images.

    Au niveau de la ligne 34 du fichier toolobox.def, ajoutez la ligne #include KDG_INCLUDE entre les commentaires /*-toolbox_include_toolboxes */ et /*-toolbox_include_toolboxes_end */ :

    /* -toolbox_include_toolboxes */
    #include DESIGN_INCLUDE
    #include KDG_INCLUDE
    /* -toolbox_include_toolboxes_end */

    Pareil au niveau de la ligne 100 ajoutez la ligne AddLibrary(kdg, C, $(KDG_LIBDIR)) comme ci-apres:

    /* -toolbox_libraries */
    AddLibrary(kdg, C, $(KDG_LIBDIR))
    /* -toolbox_libraries_end */

    Il faut aussi e'diter le fichier include general de votre toolboxe: revenez dans la fenetre "Toolbox Attributes" et cliquez sur le bouton "Edit" de la ligne "Toolbox include file" (3), et ajoutez dans ce fichier la ligne #include <kdg.h> comme ci-apres:

    /*-------------------------------------*
    | #include
    ---------------------------------------*/
    /* other toolbox includes go here */
    #include <design.h>
    #include <kdg.h>
    /* toplevel include for each library in this toolbox go below here */
    /* LIBRARY INCLUDES: do not delete this line */

    N'oublier pas de sauvegarder chaque fichier avant de quitter l'editeur !


    Creation d'un objet dans une nouvelle toolbox:

    Pour cre'er un nouvel objet dans une toolboxe, il suffit avec craftsman de se'lectionner votre toolboxe (1), puis dans le menu "Object Operations" de choisir l'item "Create object" (2):

    En fonction de ce que l'on veut faire on a le choix entre 5 types d'objet:

    Kroutine : si votre objet est un programme C ou C++.
    Xvroutine: pour programme C ou C++ avec interface graphique X windows.
    Pane : pour lancer une commande UNIX ou un programme par une simple interface graphique.
    Library : pour cre'er une librairie.
    Script : pour un script unix (C shell, Perl shell,...).

    Notre exemple du Threshold e'tant un programme C le type "Kroutine" convient tout a fait. Il faut donc remplir les champs comme ci-apre`s:

    Object Name : pour le nom de l'objet, c'est ce nom que l'on voit apparaitre dans la liste des objets d'une toolboxe.
    Binary Name : nom de l'exe'cutable sous UNIX.
    Icon Name : nom de votre objet sous cantata.
    Author : vous pouvez ecrire votre nom complet.
    Email Adress: votre adresse e'letronique pour que les utilisateurs de votre routine puissent vous envoyer d'e'ventuelles remarques.
    Category : nom d'un menu dans cantata (seul le menu LPSI est valide).
    Subcategory: nom d'un sous menu de "Category" (aucune restriction, mais le mieux est de vous cre'er votre popre "Subcategory" pour y placer toutes vos routines).
    Short Description...: Vous devez pre'ciser en quelques mots ce que fait votre routine. Pour le threshold, on propose: Generate binary image by thresholding input image.

    N'oublier pas de cliquer sur le bouton "YES" (2) de "Install in Cantata ?" pour acce`der a Threshold depuis cantata via le menu Category et le sous menu Subcategory. Vous pouvez alors cliquer sur "Create KROUTINE" (3). Des que l'objet est effectivement cre'e sont nom apparait dans la liste des objets de votre toolbox. Tous les items du bouton menu "Object Operations" sont maintenant accessibles: vous pouvez copier, de'placer, supprimer votre objet et en particulier changer ses attributs (comme la "subcategry").


    Edition d'un objet avec composer

    Se'lectionner "Edit Object (Composer)" du menu "Object Operations" de Composer. Cette action invoque l'e'diteur d'objet Composer sur votre objet threshold.

    Un objet comme threshold est compose' d'un ensemble de fichiers repartis dans une arboresence de re'pertoires. Composer, pre'sente ces fichiers classe's dans des listes et facilement accessible gra^ce a` son interface interactive:

    UIS: regroupes des fichiers de description d'interfaces graphiques,

    SOURCE: tous les fichiers source C,

    DOC: la documentation et l'aide online (pour une utilsation du kman),

    CONFIG: pour la compilation,

    INFO: contient la liste des bugs et

    MISC: pour les autres fichiers divers.

    Vous pouvez e'diter, renomer, supprimer (et plus encore) ces fichiers a` l'aide du menu "File Operations".


    Edition de l'interface utilisateur d'un objet avec GUISE

    Sous cantata chaque routine posse'de une icone que l'on trouve dans les menus et sous menus de la barre supe'rieure. A chaque icone est associe'e une boite de dialogue qui pre'cise les parame'tres d'entre'es/sorties de la routine.

    Tous les e'le'ments graphiques de cette boite sont spe'cifie's dans le fichier threshold.pane. Ce fichier permet a Cantata de ge'ne'rer la commande unix associe'e a' et donc de dessiner la boite de dialogue de cette routine.

    Notre routine Threshold a 3 parame`tres deux noms de fichiers et une valeur entie`re pour le niveau de seuil. Il faut donc spe'cifier dans le fichier threshold.pane ces parametres. Il y a deux facons de proceder: Soit nous e'ditons nous meme ce fichier, mais cela requie`re de connaitre les instructions UIS des interfaces graphiques khoros. Ou soit on utilise le superbe outils qu'est le GUISE pour e'diter interactivement les fichiers UIS.

    Dans la fene^tre de "Composer" cliquez sur le bouton "UIS" (rep 1), se'lecionnez le fichier "threshold.pane" (rep 2) et appelez le "guise" (rep 3) a l'aide du menu bouton "File Operations":

    La fene^tre du programme "guise" appara^t et nous montre dans une autre fene^tre le resultat de l'interpretation des instructions graphiques du fichier threshold.pane (par de'faut on trouve deux se'lecteurs de fichiers):

    Pour notre routine Threshold, il faut ajouter en entre'e le parame`tre du niveau de seuil: Selectionnez l'item "Integer" du bouton menu "Simples Variables" (rep 1) dans le "Guise":

    Un nouveau parame`tre "Integer" apparai^t alors dans la fene^tre de sortie. Cliquez (rep 1) sur ce parametre a l'aide du bouton central de la souris pour faire apparai^tre la fene^tre "Integer Selection Menuform": vous pouvez alors changer le titre "Integer" par "Upper Threshold Level" (rep 1), ce qui est plus approprier. Le dessin "e'claire" (rep 2) qui peut etre present a` la fin d'une zone de text ou d'un bouton, indique qu'il faut valider par la touche "Enter" vos modifications soient prises en compte. Vous pouvez alors observer l'effet sur la fene^tre de sortie.

    Pour respecte la contrainte ( 0<= niv <= 255) sur la valeur du niveau de seuil il suffit de mettre 0 dans le champs "Lower Bound" et 255 dans le champs "Upper Bound" (rep 3). Vous pouvez aussi changer la valeur par de'faut en mettant par exemple 128 dans le champs "Default". N'oubliez pas de valider par "Enter" pour que vos changment soient pris en compte !

    Avec ces informations, Composer ge'ne're automatiquement le code C qui recupe're les valeurs des parametres (les noms des fichiers et la valeur du seuil) de la ligne de commande unix. En faite ces valeurs seront contenues dans des variables que vous devez definir dans le champs "Variables" de chaque objets graphique: pour le seuil on propose de remplacer "int1" par "level" (rep 4). Le nom "Variables" des champs "Input" et "Output" respectivement i et o conviennent, on ne les changera donc pas.

    Dans le programme C, on acce'dera aux diffe'rent parame`tre par une variable structure'e nome' clui_info de la maniere suivante: clui_info->NomParametre_TypeParametre. Ou NomParametre est le nom du champs "Variables" et TypeParametre est un mot qui rappel la fonction du champs pointe' par clui_info (TypeParametre= [string, int, float, file, ...]. Pour Threshold on aura:

    clui_info->level_int pour le seuil, clui_info->i_file pour le nom de fichier d'entre'e et clui_info->o_file pour le nom de fichier de sortie.

    La variable structure'e clui_info sera declare'e dans le fichier threshold.h, ce fichier est acce`ssible avec le bouton SOURCE du "List Files" de Composer.

    Le champs "Desc" est utilise' pour les informations comple'mentaires concernant le parame`tre: Il est exploite' par Composer pour abriquer la doc online acce`ssible soit par le man khoros (commande kman), soit par le bouton "Help" de la boite.

    De la me^me manie`re vous changerez les "Title" des parametres "input" et "Output" des fichiers d'entre'e et de sortie et de de'placer ces champs pour les regrouper. Pour de'placer un champs dans sa fene^tre, il suffit de le se'lectionner avec le bouton gauche de la souris puis de le faire glisser a la position desire'e sans relacher le bouton de la souris. Vous pouvez e'galement le redimenssionner en se'lectionnant le champs par ses angles. On obtient la boite suivante:

    Le GUISE offre encore de nombreuse possibilite's que vous pouvez explorer. Cantata est le meilleur exemple d'interface graphique re'alise; avec le GUISE.

    Avant de quitter le "guise" n'oublier pas d'effectuer la sauvegarde du threshold.pane en cliquent sur le bouton "SAVE (Needed)".


    Ecriture du programme

    Cliquez sur le bouton "Commands" du "Composer": dans la fene^tre "Commands" qui apparai^t, puis sur "Generate Code". Ce qui a pour effet de ge'ne'rer la documentation et la structure du code source C compose' des fichiers suivants:

    threshold.h: qui contient la de'claration de la variable "clui_info" et qui devra contenir vos de'finitions globales (constantes, variables, macros, include, ...).
    threshold.c : contient la fonction main().
    usage.h : contient la fonction usage "threshold_get_args()" par le main et permet de re'cupe'rer les parame'tres (noms des fichiers et du seuil).
    Vous trouverez ces fichiers en cliquant sur le bouton "SOURCE" du "List Files" de "Composer". Il faut maintenant comple'ter le code de la fonction main en e'ditant le fichier threshold.c: selectionnez ce fichier et lancez l'editeur par l'item "Edit" du "File Operations de composer".

    Dans la fonction main(), on trouve les sections de commentaires suivantes:

    /* -main_variable_list */
    /* -main_variable_list_end */

    C'est entre ces commentaires qu'il faut declarer vos variables locales.

    /* -main_before_lib_call */
    /* -main_before_lib_call_end */

    Cette section est utilise pour initialiser vos variables, par exemple ouvrir un fichier image et verifier que sont type est adapte au traitement qui va suivre.

    /* -main_library_call */
    /* -main_library_call_end */

    et c'est dans cette section que l'on place le traitement des donnees. Si cette portions de code est importente il est preferable de la decouper par un ou plusieurs appels de fonctions (cf creation de fonctions).

    /* -main_after_lib_call */
    /* -main_after_lib_call_end */

    Enfin cette derniere section est reserve'e a la sauvegarde des donnees apres traitement. Pour le threshold on transcrit l'algo propose precedemment:

    /* -main_variable_list */
      IMAGE img;         /* pour contenir toutes les donnees d'une image */ 
      unsigned char *pt; /* pointeur pour les points de l'image*/ 
      int i;             /* indice du point courant */
    /* -main_variable_list_end */
    
    /* -main_before_lib_call */
      /* lecture de l'image et test de reussite */ 
      if ( (img = ReadImage( clui_info->i_file )) == NULL ) { 
        fprintf(stderr,"threshold: Erreur de lecture sur le fichier %s\n",clui_info->i_file); 
        exit(1);
      }
    
    /* verfication du type de l'image */ 
      if (img->depth != 8 ) {
        /* point code sur 8 bits ? */
        fprintf(stderr,"threshold: Les pixels de l'image %s doivent etre codees sur 8 bits\n", clui_info->i_file); 
        exit(1);
      }
      if (img->nplane != 1 ) {
        /* image 2D ? */
        fprintf(stderr,"threshold: L'image %s ne doit avoir qu'un seul plan (2D) et elle en a %d\n", clui_info->i_file, img->nplane);
        exit(1); 
      }
    /* -main_before_lib_call_end */
    
    /* -main_library_call */
      /* Traitement */
      pt = img->imagedata; /* fait pointer sur les donnees de l'image */
      for ( i = 0 ; i < (img->ncol * img->nlig) ;i++) {
        if (*pt > clui_info->level_int) /* test du seuilhaut */ 
          *pt = 255; /* allumer le point courant */
        else
    
          *pt = 0; /* etteindre le point courant */
        pt++; /* point suivant */ 
      }
    /* -main_library_call_end */ 
    
    /* -main_after_lib_call */
      /* sauvegarde de l'image + test de reussite */ 
      if (!WriteImage( clui_info->o_file, img )) { 
        fprintf(stderr,"threshold: Erreur d'ecriture du fichier %s",clui_info->o_file,);
        exit(1);
      }
    /* -main_after_lib_call_end */
    

    Reste a' sauvegarder ce fichier et a' effectuer la compilation: cliquez sur le bouton "Commands" de Composer. Dans la fenetre "Commands" qui apparai^t, cliquez sur le menu bouton "Make ..." et se'lectionnez l'item "make install". Ce qui a pour effet de lancer la compilation. Si une erreur survient, revener sur le fichier threshold.c pour effectuer les corrections et relancez le "make install". Si tous c'est bien passe', vous pouvez effectuer des tests sous cantata ou plus simplemt sous unix par la commande:

    threshold -i ImageEntree -o ImageSortie -level 175

    pour visualiser une image vous pouvez utiliser la commande:

    putimage -i ImageSortie (aide avec: putimage -U ou kman putimage)