Sommaire


Introduction

Cette partie de notre site est dédiée au traitement d'images. Après une introduction brève des méthodes utilisées, nous allons présenter le programme Qlisp. Des exemples concrets termineront ce chapitre.

En analyse d'images, on distingue deux théories différentes : la morphologie mathématique et le traitement de signaux.

Nous pensons qu'un grand atout pour le contrôle industriel est la non-linéarité des transformations morphologiques : à partir de l'image de départ on élimine, par chaque étape du traitement, l'information inutile en ne gardant que la partie d'intérêt.

Dans d'autres domaines, comme l'amélioration visuelle d'images, la description de contours ou la compression, le traitement de signaux est incontestablement mieux adapté.

Les exemples à la fin de cette section vous montreront des applications typiques de la morphologie mathématique et du traitement de signaux. Mais d'abord, nous aimerions vous présenter l'outil que nous utilisons dans ce cadre.

Début


Analyse d'images avec Qlisp

La première version de Qlisp fut programmée en 1991 sur la station de traitement d'images Q570 de Cambridge Instruments en combinant la bibliothèque des transformations de la Q570 avec l'interpréteur Lisp. La thèse "Morphologie Mathématique Appliquée au Contrôle Industriel de Pièces Coulées", soutenue à l'ENSMP par T. Jochems, décrit la conception et l'application de cette version.

La croissance rapide de la puissance des ordinateurs est à la base de la deuxième version : les transformations réalisées électroniquement sur la Q570 ont été remplacées par des transformations codées en C. Programmé sur une station Alpha de DEC, Qlisp sert désormais d'outil pédagogique pour l'enseignement de la visionique à l'Ecole d'Ingénieurs IMERIR/Perpignan.

Depuis, le système accroît continuellement et possède aujourd'hui les possibilités suivantes :

Début


Utilisation industrielle

Dans le cadre industriel, les routines d'analyse d'images sont souvent utilisées dans un environnement informatique spécifique qui assure la stabilité et la cohérence de l'application. C'est la raison pour laquelle nous avons séparé Qlisp en deux parties distinctes :

L'avantage de cette approche est que l'on peut développer et tester des applications d'abord avec l'interpréteur Lisp. Cela diminue sensiblement la durée de cette étape. Le prototype résultant se laisse ensuite intégrer dans l'application industrielle.

Voici la liste des transformations qui sont à votre disposition, le code source étant intégré dans la version téléchargeable :

Fichier

Fonctions

intern.cpp

extern void imainit();
extern int  newimage(int x,int y,int w,int h,int depth);
extern void freeimage(int id);
extern void binset(int id,int val);
extern void greyset(int id,int val);
extern void colset(int id,int val);
extern void convert(int ima_in,int ima_out);
extern void frames(int x,int y,int w,int h);
extern void iframe(int x,int y,int w,int h);
extern void mframe(int x,int y,int w,int h);

base.cpp

extern int  binrpix(int id,int x,int y);
extern int  greyrpix(int id,int x,int y);
extern int  colrpix(int id,int x,int y);
extern void binwpix(int id,int x,int y,int val);
extern void greywpix(int id,int x,int y,int val);
extern void colwpix(int id,int x,int y,int val);
extern void binwline(int id,int x1,int y1,int x2,int y2,int val);
extern void greywline(int id,int x1,int y1,int x2,int y2,int al);
extern void colwline(int id,int x1,int y1,int x2,int y2,int val);
extern void binbord(int binout,int val,int x,int y,int w,int h);
extern void greybord(int ginout,int val,int x,int y,int w,int h);
extern void colbord(int cinout,int val,int x,int y,int w,int h);
extern void bincopy(int bin,int bout);
extern void greycopy(int gin,int gout);
extern void colcopy(int gin,int gout);
extern void binshift(int bin,int bout,int dx,int dy);
extern void greyshift(int gin,int gout,int dx,int dy);
extern void colshift(int cin,int cout,int dx,int dy);
extern void binzoom(int bin,int bout,float zx,float zy);
extern void greyzoom(int gin,int gout,float zx,float zy);
extern void colzoom(int cin,int cout,float zx,float zy);
extern void greyzoombil(int gin,int gout,float zx,float zy);
extern void colzoombil(int cin,int cout,float zx,float zy);
extern void binrot90(int bin,int bout,int dir);
extern void greyrot90(int gin,int gout,int dir);
extern void colrot90(int cin,int cout,int dir);
extern void binrot(int bin,int bout,float angle);
extern void greyrot(int gin,int gout,float angle);
extern void colrot(int cin,int cout,float angle);
extern void greyrotbil(int gin,int gout,float angle);
extern void colrotbil(int cin,int cout,float angle);
extern void greyadd(int gin,int ginout,int type);
extern void greyaddl(int gin,int ginout,int type);
extern void greysub(int gin,int ginout,int type);
extern void greysubl(int gin,int ginout,int type);
extern void coladd(int cin,int cinout,int type);
extern void coladdl(int cin,int cinout,int type);
extern void colsub(int cin,int cinout,int type);
extern void colsubl(int cin,int cinout,int type);
extern void greymultl(int gin,int ginout,int fact,int type);
extern void greydiv(int gin,int ginout,int fact,int type);
extern void colmultl(int cin,int cinout,int fact,int type);
extern void coldiv(int cin,int cinout,int fact,int type);
extern void binsup(int bin,int binout);
extern void bininf(int bin,int binout);
extern void greysup(int gin,int ginout);
extern void greyinf(int gin,int ginout);
extern void colsup(int cin,int cinout);
extern void colinf(int cin,int cinout);
extern void greymask(int gin,int bin,int ginout,int type);
extern void colmask(int cin,int bin,int cinout,int type);
extern void greycombine(float c1,int gin,float c2,int ginout);
extern void colcombine(float c1,int cin,float c2,int cinout);

trans.cpp

extern void bingrey(int bin,int gout);
extern void greybin(int gin,int bout);
extern void thresh(int gin,int bout,int lo,int hi);
extern int  fpoint(int bin,int *x,int *y);
extern void bininvert(int binout);
extern void greyinvert(int ginout);
extern void colinvert(int cinout);
extern void bininfnbh(int bin,int tmp,int bout,int se);
extern void binsupnbh(int bin,int tmp,int bout,int se);
extern void greysupnbh(int gin,int gout,int se);
extern void greyinfnbh(int gin,int gout,int se);
extern void greylindilation(int gin,int gout,float angle,int size);
extern void greylinerosion(int gin,int gout,float angle,int size);
extern void anamorph(int ginout,uchar *lut);
extern void bitmap(int gin,int bout,int ds);
extern void distance(int inout,int outside);
extern void getsample(gin,...);
extern void median(int gin,int gout,int size);

queue.cpp

extern void qinit();
extern int  label(int gout,int gmask,uint gmax);
extern void binbuild(int ginout,int gmask);
extern void greybuild(int ginout,int gmask);
extern void watershed(int ginout,int mask);
extern void thinqueue();

measure.cpp

extern void greymeas(int id,int *min,int *max,double *mean);
extern int  binsum(int bin);
extern int  greysum(int gin);
extern void histogram(int gin,int *pi);
extern void f_fpoint(int label,int *buffer);
extern void f_mpoint(int label,int *buffer);
extern void f_rect(int label,int *buffer);
extern void f_area(int label,int *buffer);
extern void f_volume(int label,int ima,int *buffer);
extern void f_grey(int label,int ima,int *buffer);

signal.cpp

extern void convh(int gin,int gout,...);
extern void conv(int gin,int gout,...);
extern void rech(int gin,int gout,...);
extern void fcenter(int gout);
extern void butter(int gout,int d,int n);
extern void conveuler(int gin,int ain,int reel,int imag,float k);
extern void convbackeuler(int reel,int imag,int gout,int aout,float k);
extern void multdiv(int gin,int ain,int reel,int imag,int what,float k);
extern void ft(int gin,int ain,int gout,int aout,int dir,float fact);
extern void fft(int reel,int imag,int dir);
extern void real(int gin,int ain,int gout,int mode);
extern void imaginary(int gin,int ain,int gout,int mode);

io.cpp

extern void loadcamera(char *name);
extern void freecamera();
extern bool cameraok();
extern char*(*camerror)();
extern bool (*caminit)(char *args);
extern void (*camfree)(void);
extern bool (*camsnap)(int camera,char *options);
extern bool (*camreadheader)(int *x,int *y,int *w,int *h,...);
extern bool (*camreaddata)(uchar *data);
extern bool (*camlut) (uchar lut[256]);
extern void loadfilter(char *name);
extern void freefilter();
extern bool filterok();
extern char*(*filtererror)();
extern bool (*filterfopen)(char *name,bool write);
extern void (*filterfclose)();
extern bool (*filterreadheader)(int *x,int *y,int *w,int *h,...);
extern bool (*filterreaddata)(uchar* data);
extern bool (*filterwriteheader)(int x,int y,int w,int h,...);
extern bool (*filterwritedata)(uchar* data);

color.cpp

extern void colgrey(int col, int red, int green, int blue);
extern void greycol(int red, int green, int blue, int col);
extern void rgbihs(int rgb,int ihs);
extern void ihsrgb(int ihs,int rgb);
extern void intensity(int rgb,int grey);

Début


Aptitude pédagogique

Nous utilisons Qlisp pour enseigner l'analyse d'images. C'est son architecture hiérarchique, expliquée dans la figure suivante, qui appuie fortement son aptitude pour la formation :

pyramide

Dans la couche de base, les fonctions sont codées en C en raison de la rapidité de ce langage. Il n'y a aucun intérêt pédagogique à faire coder ces fonctions par des débutants en analyse d'images, le temps nécessité étant trop élevé.

Dans la couche Lisp, on peut combiner les fonctions de base pour obtenir de nouvelles méthodes plus complexes et plus puissantes. Cette propriété de Qlisp est bien adaptée pour la morphologie mathématique : une érosion de taille n, par exemple, se calcule en appliquant n fois l'érosion de la taille 1 (décomposition de l'élément structurant) ; une ouverture présente une érosion suivie d'une dilatation avec l'élément structurant transposé. Le tableau suivant montre le codage de trois nouvelles transformations. Le codage est facilité par le caractère fonctionnel de Lisp :

Fonction

Codage en Lisp

dilatation géodésique

(defun gdsdilation(ima mask se size)
  (dotimes(i size ima)
    (setq ima (inf
      (dilation ima se 1)
      mask))))

ouverture morphologique

(defun opening(ima se size)
  (dilation
    (erosion ima se size)
    (transpose se) size))

gradient

(defun gradient(ima &key (se se-c) (size 1))
  (sub
    (dilation ima se size)
    (erosion ima se size)))

Les participants des cours travaillent sur la couche Lisp et mettent ainsi en pratique la théorie. Dans le système actuel, plus de 100 transformations sont définies en Lisp.

Dans la couche "Applications", on peut finalement résoudre des problèmes réels et complexes en utilisant, et la bibliothèque de base, et les transformations codées en Lisp. Dans le chapitre suivant, nous en montrerons trois exemples qui sont aussi traités dans nos cours.

Début


Exemples

Dans ce chapitre, nous illustrerons les différentes approches de l'analyse d'images par des exemples. Tous les traitements sont calculés avec le système Qlisp.


Extraction de lignes

Cet exemple montre la détection de lignes dans un métal. Il a été traité à l'ENSMP par A. Tuzikov pour la société belge OCAS.

L'image (1) montre de la tôle de métal (25x25 mm) sur laquelle on a tracé des lignes noires. L'intérêt est la détection automatique de ces lignes après avoir déformé la pièce par une presse. Les données ainsi obtenues servent à optimiser l'outil de déformation.

original

ouverture

image binaire

1) original

2) ouverture

3) seuillage

filtrage binaire

résultat

4) filtrage binaire

5) résultat

Le traitement commence par un filtrage du bruit (2). Un "chapeau haut de forme" élimine ensuite l'effet d'un éclairage hétérogène. Un seuillage consécutif donne l'image (3). Un filtrage binaire du bruit (4) et un "squelette par zone d'influence" termine le traitement, le résultat est visualisé dans l'image (5).

L'exemple montre bien la philosophie du filtrage morphologique : on supprime de plus en plus d'informations (bruit, niveaux de gris, taille) en ne gardant que le résultat souhaité.

Début


Restauration d'une image floue

Cet exemple montre une application du traitement de signaux. L'image (1) présente l'image de départ acquise par une caméra défectueuse. Il s'agit d'un défaut dans l'amplificateur du signal vidéo. Bien que nous ayons simulé ce défaut, il pourrait s'agir d'un problème réel, voir Apollo ou Hubble...

original

réponse impulsionnelle

1) original

2) caractéristique

fft

résultat

3) spectre

4) résultat

Pour corriger le défaut, on a besoin de sa description. Dans notre cas, nous avons acquis l'image (2) avec un seul point central éclairé. L'image représente donc la réponse impulsionnelle de la caméra défectueuse. Il reste de calculer le spectre (3) de l'image (1), le spectre de la réponse impulsionnelle et de diviser ces représentations fréquentielles. La transformation de Fourier inverse donne l'image (4) qui n'est plus floue, le défaut est corrigé. Le traitement de signaux est gourmand en temps de calcul : 85ms pour cet exemple.

Début


Reconnaissance de filigranes

Cet exemple montre la reconnaissance de filigranes. Il a été étudié par un groupe de 4 élèves dans le cadre d'un projet de l'école d'ingénieurs IMERIR.

original

prétraitement

1) original

2) contraste amplifié

echantillon

résultat

3) échantillon

4) résultat

L'image (1) montre le filigrane acquise par une caméra noir et blanc. La première étape consiste à améliorer et à stabiliser le contraste de l'image. On utilise le "chapeau haut de forme" et "l'imposition d'histogrammes". Dans le résultat (2), on recherche ensuite un échantillon (3) qui montre une partie caractéristique du filigrane auparavant stocké dans une base de données. Le résultat (4) montre que l'échantillon est détecté 4 fois dans l'image de départ. La reconnaissance de l'échantillon est effectuée par une corrélation accélérée entre l'image (2) et (3), le temps de traitement est 25ms pour le processus complet.

Début


Tester Qlisp

Peut-être avez-vous maintenant envie d'apprendre plus sur l'analyse d'images et ses transformations. Dans ce cas, vous pouvez télécharger Qlisp. Des nombreux exemples vous montreront des applications industrielles concrètes. Et vous pouvez tester les méthodes sur vos propres images.


Présentation      Début      Télécharger