Image numérique et tableau : est-ce identique ?

Posted by fmn on juillet 30, 2009 at 1:14 .

Ouvrons un livre de traitement d'image (par exemple Morphological Image Analysis). Il est logique que l'ouvrage débute sur les définitions des notions manipulées par la suite. Une image est souvent définie  une correspondance entre un sous-ensemble D de \mathbb{Z}^2 vers un nombre (0 ou 1 dans le cas d'une image binaire par exemple). Le sous-ensemble D est le domaine de définition de l’image, définie ainsi sur une trame rectangulaire. Les coordonnées de D sont donc des entiers (négatifs ou positifs).

Passons à la pratique et consultons maintenant la documentation d’une librairie de traitement d’images (par exemple ImageJ) : une image n’est rien d’autre qu’un tableau à deux dimensions  dont les coordonnées appartiennent  au domaine [(0, 0), (w-1), (h-1)], où w et h sont les dimensions de l’image.

La différence essentielle entre ces deux cas porte sur le domaine de définition. Mathématiquement, les coordonnées des pixels peuvent être négatives; pratiquement (i.e. dans les librairies), elles ne le peuvent pas. Examinons,  les conséquences de cette limitation en calculant un produit de convolution sous Octave (ou Matlab). Pour plus de clarté, le produit est calculé sur des signaux 1D :

octave> a = [1 2 3 4 5]
octave> b = [1 0 -1]
octave> conv(a, b)
  ans = 1 2 2 2 24 -5
octave> conv(b, a)
  ans = 1 2 2 2 24 -5

La commutativité du produit de convolution est respectée puisque conv(a, b) = conv(b, a), c'est une bonne chose. Mais il apparait quelques difficultés. Quel est exactement le signal a défini par a=[1 0 –1] ? C’est  un (assez grossier) filtre dérivateur qui peut permettre de détecter les contours dans une image. Mais quelle est l’origine de ce signal ? Est-elle sur le 0 ? Sur le –1 ? Rien n’est certain car Octave/Matlab considère que les signaux, les images sont des tableaux. Il s’agit pourtant d’une information capitale. Si l’origine est sur le 0, alors il n’y a pas de décalage entre un contour et la détection qui en sera réalisée. Par exemple, si un contour est présent à la coordonnées x, la réponse du filtre sera maximale en x. Cependant si l’origine du filtre est sur le coefficient –1 (ou 1), la réponse sera maximale en x+1 (ou x-1), un décalage sera donc observé.

La convention d’utilisation des librairies veut en général que l’origine du filtre soit au centre de la réponse impulsionnelle. Mais cela reste une convention. Cette information n’est stockée nulle part, sinon dans la documentation des fonctions qui manipulent les signaux ou les images.  Dans la pratique, il est pourtant nécessaire de manipuler des signaux avec des origines décalées. C’est pourquoi les concepteurs de Matlab précisent ainsi pour la fonction conv (produit de convolution) :

C = conv(...,'shape') returns a subsection of the two-dimensional convolution, as specified by the shape parameter: full Returns the full two-dimensional convolution (default). same Returns the central part of the convolution of the same size as A. valid Returns only those parts of the convolution that are computed without the zero-padded edges. Using this option, C has size [ma-mb+1,na-nb+1] when length(c) is max(length(a)-max(0,length(b)-1),0)

Il existe ainsi des options de la fonction permettant de trouver les bons résultats. Mais l’utilisation de ces options n’est pas claire. Comme la manipulation des décalages est portée par la fonction conv et non par la structure de donnée choisie, des erreurs sont fréquentes. Je me rappelle lorsque je produisais beaucoup de code (pendant ma thèse) avoir rencontré quelques bugs assez difficiles à résoudre à cause de cette imprécision. Il est quasiment obligatoire de d’annoter son code avec des commentaires. Et si l’on oublie cette information : bug !

Il serait pourtant tellement plus clair d’avoir une structure de données qui permette d’avoir des indices négatifs pour les signaux et les images. Pourquoi les librairies ne les proposent-elles pas ? Il y aurait évidemment un surcout de temps de calcul (une translation pour chaque accès à un pixel de l’image), mais le nombre d’erreurs évitées serait appréciable. C'est pourquoi des langages de programmation de haut niveau sont généralement employés : pour ne pas avoir a gérer les détails.

FMN.

2 Comments

Trackbacks / Pingbacks

Leave a Reply