Sunteți pe pagina 1din 82

♦ AUPELF – UREF ♦

♦ UNIVERSITE LIBANAISE ♦UNIVERSITE SAINT – JOSEPH ♦


en partenariat avec

Université de Reims – Université de Rennes – IRISA


Ecole Polytechnique Fédérale de Lausanne

DEA Modélisation et ingénierie


du logiciel scientifique

Reconnaissance de caractères manuscrits par réseau de


neurones

Réalisé Par :

Al Falou Wassim

Sous la Direction de :
Dr. El-Eter Bassam

Décembre 1998

Page 1
Remerciements

Je tiens à remercier Dr. Bassam El-Eter pour son support et ses conseils

précieux, ainsi que pour la patience et la minutie avec lesquelless il a supervisé la

rédaction de ce rapport.

Mes remerciements vont aussi à Dr. Nabil Nassif , Directeur du DEA

MODELISATION MATHEMATIQUE, aInsI qu'aux membres du jury.

Mon merci va aussi à Dr. Dennis Hamad, Dr. Noël Bonnet, et à tous les

professeurs qui enseignait dans le DEA MODELISATION.

Enfin, je tiens à remercier M. Mouhamad Obeid qui m'a permis d’utiliser son

scanner.

Page 2
Introduction

Le domaine de reconnaissance de forme est devenu aujourd’hui l’un des


grands domaines dans lesquels travaillent de plus en plus de chercheurs. Le but des
chercheurs dans ce domaine est de trouver des algorithmes pouvant résoudre sur
ordinateur les problèmes de reconnaissance de forme qui sont intuitivement résolus
par les êtres humains.

Les ordinateurs séquentiels sont très performants pour les calculs, ils peuvent
exécuter des opérations complexes plus vite que le cerveau humain. En
reconnaissance de forme, ce dernier est capable d’analyser une scène très complexe
instantanément, alors que le meilleur des algorithmes de reconnaissance de forme ne
pourrait reconnaître que des formes relativement simples.

Inspirés du fonctionnement du système nerveux, les réseaux de neurones


constituent actuellement un des outils les plus efficaces pour le traitement des
problèmes de classification (dans notre cas il s’agit de classifier des caractères
manuscrits).

Les réseaux de neurones sont massivement parallèles et ont la capacité de


mémoriser la connaissance à partir d’exemples. Leur fonctionnement ressemble à
celui d’un cerveau humain par le fait que la connaissance est acquise grâce à un
processus d’apprentissage et que les poids des connexions inter-neuronales sont
utilisés pour mémoriser cette connaissance sous une forme réduite. Ces propriétés
attractives rendent les réseaux de neurones adaptatifs au changement
d ’environnement, résistants aux bruits et tolérants aux pannes.

Les caractéristiques des problèmes qui se prêtent bien à une résolution par les
réseaux de neurones sont des problèmes pour lesquels les règles qui permettent de les
résoudre sont inconnues ou très difficiles à expliciter ou à formaliser. Il faut alors
disposer d’un ensemble de données représentatives du problème étudié (dans notre cas
ces exemples sont constitués de plusieurs caractères écrits par des personnes
différentes).

Notre projet s’inscrit donc dans le cadre de reconnaissance de forme par


réseaux de neurones. Il s’agit de classifier chaque caractère rencontré dans un texte
parmi un ensemble de caractères reconnaissables par le réseau.

Plusieurs équipes de recherche ont déjà travaillé sur le problème de


reconnaissance de texte.

Cao et al. [1] présentent un système appelé BICNN spécialisé dans la


reconnaissance automatique de chiffres arabes (0..9) manuscrits. Ils mettent en œuvre
un réseau de neurones multicouches hiérarchique et Bayésien. Le taux de réussite
atteint par cette méthode est de 99% avec une base d’apprentissage de 6400 exemples
(640 exemples de chaque chiffre).

Elnagar et al. [2] utilisent un réseau de neurones dont les entrées sont définies
par des attributs structurels pour la reconnaissance des chiffres arabes. Le taux de
réussite est de 94 %.
Page 3
Young-Sup et al. [3] mettent en œuvre un réseau de neurone RBF (Radial
Basis Function) pour la reconnaissance de chiffres arabes manuscrits. Le taux de
réussite atteint par cette méthode est de 97% avec une base d’apprentissage de 4000
exemples (400 exemples de chaque chiffre).

La liste des applications mettant en œuvre des réseaux de neurones de


différents types est encore longue. Cette technique n’est plus une nouvelle technique,
elle est déjà présente dans presque tous les domaines, surtout en diagnostique de
pannes et en filtrage d’alarmes, en contrôle, en reconnaissance de formes, en
économie et dans bien d’autres domaines. C’est pour cela qu’il nous a semblé que les
réseaux de neurones seraient bien adaptés à la reconnaissance de caractères
manuscrits.

Le chapitre 1 de ce présent rapport contient une description du problème de


reconnaissance de textes manuscrits, avec une introduction de ses différents aspects.

Au chapitre 2, nous introduisons la technique des réseaux de neurones avec


toutes ses notions de base. On y trouve une description de l’architecture générale d’un
réseau et de son mode de fonctionnement, et en particulier pour un perceptron et une
réseau multicouches. Ensuite, on y présente les différentes étapes de mise en œuvre
d’un réseau de neurones.

Le chapitre 3 présente notre application de reconnaissance de chiffres arabes et


indiens. On y présente d’abord les techniques utilisées pour la modélisation des
objets, de l’acquisition des images à l’extraction des attributs, ainsi que les méthodes
mises en œuvre pour la réalisation des étapes de prétraitement des images représentant
les chiffres. On y décrit ensuite le réseau de neurones utilisé et les méthodes de
simulation, d’apprentissage et de classification du réseau.

Page 4
Chapitre 1

Le problème de reconnaissance de l’écriture


1 Introduction
Le but de la reconnaissance de l’écriture est de transformer un texte écrit en
une représentation compréhensible par une machine et facilement reproductible par un
logiciel de traitement de texte. Cette tâche n’est pas triviale car les mots possèdent une
infinité de représentations parce que chaque personne produit une écriture qui lui est
propre, et parce qu’il existe de nombreuses polices de caractères pour l’imprimé avec
de nombreux styles (gras, italique, souligné, ombré etc.) et des mises en page
différentes et complexes. Suivant le type d’écriture qu’un système doit reconnaître
(manuscrit, cursif ou imprimé), les opérations à effectuer et les résultats peuvent
varier notablement. Notre projet s’intéresse principalement à la reconnaissance de
séquences de chiffres manuscrits.

2 Les applications
La reconnaissance de l’écriture est mieux connue sous le nom d’OCR (Optical
Character Recognition), du fait de l’emploi de procédés d’acquisition optiques.
L’OCR connaît plusieurs applications pratiques dans plusieurs domaines d’activité
parmi lesquels on peut citer :

• Les banques et les assurances pour l’authentification de chèques bancaires


(correspondance entre montants et libellé d’une part, et correspondance entre
l’identité du signataire et sa signature, d’autre part), et la vérification de clauses de
contrats pour les assurances.

• La poste pour la lecture des adresses et le tri automatique du courrier.

• Les télécommunications pour l’échange de fichiers informatiques à distance.

• La police et la sécurité pour la reconnaissance de numéros minéralogiques pour le


contrôle routier, l’authentification et l’identification de manuscrits et l’identification
du scripteur.

• Les affaires et l’industrie pour la gestion des stocks et la reconnaissance de


documents techniques.

• La bureautique pour l’indexation et l’archivage automatique de documents, et pour


la publication électronique.

• L’administration pour la reconnaissance de plans cartographiques et la lecture


automatique de documents administratifs.

Page 5
3 Les différents aspects de l’OCR
Il n’existe pas de système universel d’OCR mais plutôt des voies d’approches
dépendant du type de données traitées et bien sûr de l’application visée. Nous allons
donner, dans la suite, quelques caractéristiques des systèmes d’OCR.

3.1 Reconnaissance de l’imprimé ou du manuscrit


L’approche n’est pas la même selon qu’il s’agisse de reconnaître un imprimé
ou un manuscrit. Dans le cas de l’imprimé, les caractères sont bien alignés et souvent
bien séparés verticalement, ce qui simplifie la phase de lecture, bien que certaines
fontes présentent parfois des accolements qu’il faut défaire. De plus, le graphisme des
caractères est conforme à un style calligraphique (fonte) qui constitue un modèle pour
l’identification. Dans le cas du manuscrit, les caractères sont souvent ligaturés et leur
graphisme est inégalement proportionné. Cela nécessite l’emploi de techniques de
délimitation très spécifiques et souvent des connaissances contextuelles pour guider la
lecture.

3.2 Reconnaissance monofonte, multifonte ou omnifonte


Les notions que nous présentons ici concernent uniquement les textes
imprimés. Un système est dit monofonte s’il ne traite qu’une fonte à la fois, c’est-à-
dire que le système ne connaît l’alphabet que dans une seule fonte. L’apprentissage y
est simple puisque l’alphabet représenté est réduit. Un système est dit multifonte s’il
est capable de reconnaître un mélange de quelques fontes parmi un ensemble de
fontes préalablement apprises. Dans ce cas, le prétraitement doit réduire les écarts
entre les caractères (taille, épaisseur et inclinaison), l’apprentissage doit gérer les
ambiguïtés dues aux éventuelles ressemblance des caractères des différentes fontes, et
la reconnaissance doit identifier les subtiles différences entre ces caractères. Enfin, un
système est dit omnifonte s’il est capable de reconnaître toute fonte sans l’avoir
absolument apprise, ce qui relève actuellement du domaine de la recherche.

3.3 Reconnaissance de caractères ou analyse de documents


Dans le premier cas, la structure du texte est limitée à quelques lignes ou mots.
La lecture consiste en un simple repérage des mots dans les lignes, puis à un
découpage de chaque mot en caractères. Dans le second cas, il s’agit de données bien
structurées dont la lecture nécessite la connaissance de la typographie et la mise en
page du document (structure physique et logique du contenu). Certaines fantaisies de
présentation, comme dans certains magazines ou journaux, obligent parfois à
reconnaître d’abord quelques caractères pour s’assurer du sens de la lecture. La tâche
de lecture n’est plus ici un simple prétraitement mais une démarche experte d’analyse
d’image : localisation de régions, séparation des régions du texte des régions
graphiques et photographiques, étiquetage sémantique des zones textuelles à partir de
modèles, détermination de l’ordre de lecture et de la structure du document.

3.4 Reconnaissance en ligne ou hors ligne


La reconnaissance en ligne est une reconnaissance dynamique se déroulant
pendant l’écriture. Un léger retard, d’un mot ou d’un caractère, permet à la

Page 6
reconnaissance de ne pas empiéter sur la saisie. La réponse en continue du système
permet à l’usager de corriger et de modifier son écriture de manière directe et
instantanée. La reconnaissance hors ligne ou en différé démarre après l’acquisition du
document en entier. Ce type de reconnaissance convient pour les documents imprimés
et les manuscrits déjà rédigés. Ce mode permet l’acquisition instantanée d’un nombre
important de caractères, mais impose d’effectuer des prétraitements coûteux pour
retrouver l’ordre de la lecture.

3.5 Système avec ou sans apprentissage


Un système avec apprentissage comporte un module d’introduction des
modèles des caractères de référence. Des échantillons significatifs de l’écriture
(imprimés ou manuscrits) en nombre suffisant (des dizaines, voire des centaines
d’échantillons par caractère) sont saisis en mode manuel ou automatique. Dans le
premier cas, l’utilisateur (professeur) indique au système l’identité de chaque
échantillon permettant au système d’organiser ses classes en fonction du vocabulaire
étudié. Pour le manuscrit, l’idéal serait d’apprendre les caractères directement à partir
d’un texte, mais cela pose des problèmes évidents de segmentation. Dans le second
cas, les échantillons sont regroupés automatiquement à partir d’analyse
morphologique, sans connaissance de leur classe. Dans un système sans
apprentissage, une base de connaissance est intégrée au système et des algorithmes
d’analyse particuliers sont utilisés.

4 Saisie de l’écriture
La première étape d’un système OCR consiste à digitaliser l’écriture et à la
présenter au système sous une forme lisible avec un minimum de dégradation
possible. Cette tâche est relativement difficile à cause de la diversité des formats et de
la qualité de l’écriture et du papier. Le capteur utilisé peut ne pas être sensible aux
variations des tons et à l’épaisseur des traits, ce qui occasionne des dégradations très
perceptibles du dessin des caractères. Deux modes de saisie sont utilisés : le mode
statique pour les caractères déjà écrits et le mode dynamique pour les caractères
manuscrits à reconnaître en cours d’écriture.

4.1 Le mode statique


Il utilise essentiellement des scanners. Le scanner balaye le texte ligne par
ligne en une série plus ou moins importante de points. La résolution d’un scanner,
exprimée en nombre de points par pouce (ppp ou dpi en anglais), désigne sa capacité à
digitaliser les traits fins. En OCR, les valeurs les plus courantes vont de 200 à 600 dpi;
une résolution plus grande n’apporte rien à la précision de la digitalisation, bien au
contraire elle augmente le nombre de points à traiter et génère même du bruit (grains
du papier). Plusieurs types de scanners existent sur le marché, fournissant le choix des
images binaires, des images de niveaux de gris et des images en couleur.

4.2 Le mode continu


Il utilise une caméra vidéo. Ce mode est très utilisable dans des applications en
temps réel (tri automatique du courrier ou reconnaissance de plaques minéralogiques).

Page 7
5 Reconnaissance de caractères
Il s’agit ici de caractères isolés. Le schéma de reconnaissance de caractères
passe par les étapes classiques de traitement, à savoir le prétraitement, l’analyse,
l’apprentissage et la reconnaissance.

5.1 Techniques de prétraitement


Elles sont différentes suivant que les caractères soient donnés sous forme
d’image ou de suite de segments. Dans notre application nous restons dans la
première catégorie.

A cause de la forte granularité de l’échantillonnage et des divers problèmes


d’éclairage et de saisie, l’image du caractère peut subir des manquements ou des
empâtements. Il convient de corriger si possible ces problèmes avant toute étape
d’analyse. Par ailleurs, il n’est pas toujours utile d’utiliser tous les points de l’image
du caractère pour extraire les propriétés caractéristiques. Une étape de réduction
élimine les points redondants. Les techniques de prétraitement sont les suivantes :

5.1.1 Lissage

L’image du caractère peut être entachée de bruit dû aux artefacts de


l’acquisition et souvent à la qualité du document, conduisant soit à des absences de
points (trous) soit à des empâtements ou des excroissances et donc à une surcharge de
points. Les techniques de lissage permettent de résoudre ces problèmes.

5.1.2 Normalisation de la taille

La taille d’un caractère peut varier d’une écriture à l’autre, ce qui peut causer
une instabilité des paramètres. Une technique naturelle de prétraitement consiste à
ramener les caractères à la même taille. L’algorithme de normalisation que nous avons
utilisé est très simple et il est présenté dans le chapitre 3 de ce rapport.

5.1.3 Amincissement

Le but de l’amincissement d’un caractère est de


simplifier l’image du caractère en une image plus facile
à traiter en la réduisant par exemple à une dimension,
c’est-à-dire que l’épaisseur du caractère est réduite à un
pixel (figure ci-contre).

5.2 Techniques d’analyse


L’analyse du caractère passe par l’analyse de sa forme et l’extraction de ses
traits caractéristiques (ou attributs). Se pose donc ici un problème du choix des traits
caractéristiques auxquels on impose de distinguer des formes proches mais
différentes. Parmi ces techniques d’analyse on peut citer :

5.2.1 Calcul de corrélation

Page 8
Le principe de base de cette méthode est fondé sur l’examen d’un certain
nombre de pixels dans l’image du caractère et l’étude de leur appartenance à la forme.
Une forme est reconnue si l’ensemble de ses pixels sont présents. Plusieurs méthodes
de reconnaissance se sont inspirées de cette idée pour construire des modèles de
caractères à partir d’emplacements géométriquement caractéristiques de pixels. La
reconnaissance se fait par calcul de corrélation. Cependant, à cause de la rigidité et de
manque de robustesse de ces modèles (conçus à partir d’emplacements fixes de
pixels), ce procédé a connu quelques limites pour le manuscrit.

5.2.2 Changement de l’espace de représentation

Les traits caractéristiques ne sont pas toujours observables dans l’image du


caractère et donc l’espace euclidien rattaché à la forme est inutile. La transformation
globale de la forme par projection dans un autre espace de représentation peut en
permettre une détermination plus aisée. Parmi les transformations usuelles, notons la
transformation de Fourrier, et le calcul de moments. Les moments prennent en compte
l’organisation intérieure de la forme du caractère et un petit nombre de ces moments
sert pour décrire un caractère. Pour ces raisons, nous nous sommes intéressés à ce
genre d’attributs (cf. chapitre 3).

5.2.3 Analyse de la courbure

Le dessin du caractère comporte des courbures et des pentes très


caractéristiques dont la détection peut aider beaucoup à la reconnaissance. Ce genre
d’attributs est très utilisé dans la reconnaissance de caractères arabes et de chiffres
indiens.

5.3 L’apprentissage
Il s’agit, lors de cette étape, d’apprendre au système les propriétés pertinentes
des caractères du vocabulaire utilisé. L’idéal serait de lui apprendre autant
d’échantillons que de formes d’écriture différentes, mais cela est impossible à cause
de la trop grande variabilité de l’écriture qui conduirait à une combinatoire explosive
des modèles de représentation. La tendance consiste alors à remplacer le nombre par
une meilleure qualité des traits caractéristiques et de bonnes séparatrices des classes
d’apprentissage.

Les procédés d’apprentissage sont différents suivant qu’il s’agisse de


caractères imprimés ou manuscrits, et suivant qu’il s’agisse de reconnaître une ou
plusieurs fontes. Nous donnons dans la suite quelques exemples de procédés
d’apprentissage.

5.3.1 L’apprentissage manuel

Il est réalisé lors d’une étape préliminaire à la reconnaissance, en introduisant


un grand nombre d’échantillons de référence. L’utilisateur joue le rôle de professeur
pour indiquer le nom de chaque échantillon. Le choix des caractères de référence est
fait à la main en fonction de l’application. Le nombre d’échantillons peut varier de
quelques unités à une dizaine par caractères. Ce type d’apprentissage est appelé
apprentissage supervisé.

Page 9
5.3.2 L’apprentissage automatique

Ce deuxième type d’apprentissage consiste à doter le système d’un mécanisme


automatique lui permettant de trouver les classes de référence avec une assistance
minimale. Des échantillons sont introduits en grand nombre par l’utilisateur sans
indication de leur classe (apprentissage non supervisé). Ce type d’apprentissage est
intéressant car il permet de renseigner l’utilisateur sur les ambiguïtés entre les
caractères afin d’agir en conséquence, par exemple, en ajoutant des échantillons pour
renforcer la représentative d’une classe.

5.3.3 L’apprentissage continu

Afin de pouvoir s’adapter à un nouveau texte, le système peut compléter ou


affiner sa base d’apprentissage en rajoutant des échantillons extraits du texte étudié.
L’apprentissage se fait ainsi de manière continue, au fur et à mesure de la
reconnaissance chaque fois que le système bute sur la reconnaissance d’un nouveau
caractère. La classe du caractère non reconnu peut lui être communiqué par
l’utilisateur ou déduit directement à partir du lexique à l’aide d’une procédure de
vérification lexicale. Ce procédé d’apprentissage est intéressant à condition que
l’auto-contrôle fonctionne correctement.

5.4 Techniques de reconnaissance


Les méthodes de reconnaissance sont nombreuses. On peut citer l’approche
bayésienne, l’approche stochastique, et l’approche structurelle.

Nous nous intéressons ici à la technique de reconnaissance basée sur les


réseaux de neurones. Cette technique diffère des techniques statistiques déjà citées par
le fait que les réseaux de neurones sont massivement parallèles, et que chaque
neurone peut être simulé électroniquement, ce qui peut réaliser une implantation
électronique du système réalisé.

6 Conclusion
Nous avons présenté dans ce chapitre les différents problèmes à résoudre dans
un système de reconnaissance de l’écriture, ainsi que les techniques pouvant être
utilisées. Il s’agit premièrement d’obtenir une base de données comportant des
exemples de chaque caractère, puis de passer par une phase de prétraitement qui
comporte une normalisation de chaques caractère, puis une extraction des attributs. La
troisième phase est celle de la classification. Dans notre projet, nous avons utilisé les
réseaux de neurones pour classifier les caractères. Dans les chapitres suivants nous
présentons les réseaux des neurones et nous détaillons encore plus les différents
algorithmes de prétraitement que nous avons utilisés.

Page 10
Chapitre 2
Les réseaux des neurones
1 Introduction
Pour tout promeneur quelque peu attentif à son environnement, la nature est
source d’inspiration. Le tissage d’une toile d’araignée, la construction d’une
fourmilière, le chant d’un rossignol, sont autant de comportements naturels auxquels
nous ne prêtons qu’une modeste attention. Or, les capacités de traitement de
l’information manifestées par les êtres vivants, même les plus simples, sont
actuellement hors de portée des systèmes informatiques traditionnels : un ordinateur
ne sait pas ″voir″, ″entendre″ ou ″reconnaître des odeurs″. Contrôler le vol d’un avion
par ordinateur requiert des développements de programmes très complexes et très
coûteux. Une mouche en fait autant, et contrôle son vol grâce à un volume cérébral
microscopique.

Une approche du traitement de l’information consiste donc aujourd’hui à


étudier les organismes vivants pour comprendre l’origine et le support de leurs
capacités. Pour atteindre ce but, on retient l’hypothèse selon laquelle le comportement
adaptatif et la faculté d’acquisition des connaissances sont pris en charge, chez les
êtres vivants, par le cerveau et, plus généralement, par le système nerveux.

On espère ainsi, en mimant les structures du système nerveux et les


mécanismes de modification de ses constituants (neurones, synapses, etc.), développer
de nouveaux outils de traitement de l’information. La technique qui en découle est
appelée réseaux de neurones. Les réseaux de neurones font ainsi partie du domaine
des sciences cognitives qui cherche à développer des modèles de systèmes capables
de manifester des capacités d’apprentissage et d’adaptation à leur environnement.

On recense aujourd’hui des applications des réseaux de neurones dans des


domaines très variés : la reconnaissance de caractères manuscrits, la classification de
profilés d’aluminium, l’analyse de l’état de réseaux électriques, la robotique, la
reconnaissance de paroles, etc. Toutes ces tâches ont un point en commun : elles sont
complexes à modéliser, elles ne requièrent pas une solution unique et exacte, mais
plutôt une estimation de la réponse la plus plausible, et enfin elles opèrent sur des
données incertaines, toujours entachées de bruit.

Les systèmes experts dont les premières applications sont apparues au début
des années 80, ont tenté de résoudre ce genre de problèmes dans lesquels l’expertise
humaine est très importante et où des connaissances incertaines peuvent être
manipulées. Ces systèmes ont très vite trouvé leurs limitations à cause de leur forte
dépendance du domaine étudié et de leur inadaptation aux applications dans lesquelles
il est très difficile d’exprimer l’expertise humaine sous forme de règles de production.
Allez par exemple savoir comment fait un humain pour distinguer la lettre A de la
lettre B oubien encore savoir comment l’oreille distingue les différentes tonalités lors
de la reconnaissance de la parole !

Une approche par réseaux de neurones permet d’esquisser des réponses à ces
problèmes, en réduisant beaucoup le temps consacré par des ingénieurs à leur analyse.

Page 11
Nous aborderons dans ce chapitre un résumé sur les réseaux de neurones et
surtout les modèles des réseaux que nous utilisons dans notre application.

2 Notion de base
2.1 Le neurone biologique

Corps cellulaire

Axone

Dendrites Synapse

Le neurone est une cellule vivante, qui peut prendre des formes variables. Il contient :

• Un corps cellulaire, qui joue le rôle d’un sommateur à seuil. Il effectue une
sommation des influx nerveux par ses dendrites ; si la somme est supérieure
à un seuil donné, le neurone répond par un flux nerveux ou potentiel
d’action qui se propage le long de son axone ; si la somme est inférieure au
seuil, il reste inactif.

• Des prolongements qui reçoivent les signaux en provenance d’autres


cellules. Ce sont les dendrites.

• Un prolongement unique, appelé axone, diffuse le signal du neurone vers


d’autres cellules.

• Un élément de jonction, appelé synapse. Les synapses permettent aux


cellules de communiquer entre elles, de plus il joue un rôle dans la
modulation des signaux qui transitent le système nerveux.

2.2 Assemblage de neurones


Un neurone pris isolément, malgré la complexité du traitement qu’il effectue,
ne peut prendre en charge la totalité du contrôle d’un être vivant évolué. Sa structure
lui permet d’entrer en relation avec des milliers d’autres neurones (de 1000 à 10000
synapses selon le type du neurone), et sa seule voie de sortie, l’axone, se ramifie pour
diffuser le résultat de la décision à d’autres neurones. Par des contacts multiples, c’est
un réseau de connexions très denses qui se construit, et qui permet un échange riche
entre des centaines de neurones différents. Il est ainsi possible de mettre en évidence,
dans le système nerveux, des structures organisées, qui diffèrent selon la nature de
l’information recueillie, et selon le traitement effectué.

Page 12
Le type d’assemblage des neurones définit ce qu’on appelle l’architecture du
réseau de neurones.

2.3 L’apprentissage
L’apprentissage est le phénomène la plus intéressante d’un système nerveux
biologique. On appelle apprentissage le processus d’acquisition de connaissances sur
l’environnement. Le psychologue Hebb décrit un mécanisme «physique » de
l’apprentissage des synapses. La règle qu’il a donnée peut être énoncée de la manière
suivante : lorsqu’un axone d’une cellule A est suffisamment proche pour exciter une
cellule B et prend alors au déclenchement de B d’une manière répétée et persistante,
alors un processus de changement métabolique prend place de telle sorte que
l’efficacité de A sur le déclenchement de B est renforcée.

2.4 Démarche de modélisation


Nous en arrivons au point où il faut définir ce que sont les réseaux de
neurones. Les réseaux de neurones sont une métaphore des structures cérébrales : des
assemblages de constituants élémentaires, qui réalisent chacun un traitement simple
voire simpliste, mais dont l’ensemble fait émerger des propriétés globales dignes
d’intérêt. Chaque constituant fonctionne indépendamment des autres, de telle sorte
que l’ensemble est un système parallèle, fortement interconnecté. L’information
détenue par le réseau de neurones est distribuée à travers l’ensemble des constituants,
et non localisée dans une partie de mémoire sous la forme d’un symbole. Enfin, un
réseau de neurones ne se programme pas pour réaliser telle ou telle tâche. Il est
entraîné sur des données acquises, grâce à un mécanisme d’apprentissage qui agit sur
les constituants du réseau afin de réaliser au mieux la tâche souhaitée.

Une modélisation d’un système nerveux biologique passe donc par trois étapes :

• Un modèle d’un seul neurone.

• Une architecture qui définit l’assemblage des différents neurones du réseau.

• Un algorithme d’apprentissage du réseau.

3 Réseaux de neurones artificiels


3.1 Introduction
Un réseau de neurones est un ensemble de neurones plus ou moins connectés
qui opèrent en parallèle. On présente dans les paragraphes suivants des notions sur : le
neurone formel, les architectures d’un réseau de neurones artificiels, l’apprentissage
d’un réseau.

3.2 Le neurone formel


Le passage des observations neurophysiologiques et anatomiques au neurone
formel a été proposé par W. McCulloch et W. Pitts. Malgré la simplicité de cette
Page 13
modélisation, le neurone formel dit de «McCulloch et Pitts » reste aujourd’hui un
élément de base des réseaux de neurones artificiels.

Le neurone de McCulloch et Pitts est un dispositif binaire, qui reçoit des


stimulations par des entrées, et les pondère grâce à des valeurs réelles appelées
coefficients synaptiques, poids synaptiques ou simplement synapses. Ces coefficients
peuvent être positifs, et l’on parle alors de synapses excitatrices, ou négatifs pour des
synapses inhibitrices. Le neurone calcule ainsi une somme de ses entrées pondérées
par les coefficients, et prend une décision en la comparant à un seuil fixé : si la
somme pondérée des entrées dépasse le seuil, la sortie produite vaut +1, sinon la sortie
vaut –1. Un schéma du fonctionnement d’un neurone formel est proposé dans la
figure suivante.

x1

w1

wd Y
xd
Σ f

wD θ

xD

D
v = ∑ wi × xi +θ
i =1

Le neurone reçoit les entrées x1, x2, …, xD et calcule le potentiel v en sommant les
entrées pondérées:

Une décision est ensuite prise pour calculer la sortie s en fonction du seuil θ :

si v > θ, alors Y = +1

Sinon Y = -1.

Les variations possibles de ce modèle viendront du choix du nombre d’entrées,


de la valeur des poids, ou de la fonction de décision. Le nombre d’entrées dépend
essentiellement des problèmes abordés : en reconnaissance de formes par exemple, on
pourra avoir autant d’entrées que de pixels dans l’image, en classification de données
on aura autant d’entrées que de mesures du processus observé, etc. La fonction de
décision f est un élément du modèle qui dépend en partie du problème : si la sortie du
neurone doit délivrer une valeur binaire, il faut utiliser une fonction à échelon ; mais,
si la sortie doit être une valeur réelle, une fonction à échelon ne convient plus. Dans
ce cas on prend Y = f (v). On peut faire apparaître le seuil dans l’équation en posant
w0 = θ et x0 = +1. Alors
D
v = ∑ wi × xi +θ
i =1

Page 14
et Y = f(v).

Le schéma du neurone devient alors :


x0 = 1

ω0 = θ

wd Y
xd
Σ f

T
V=W X
wD

xD

Voici deux fonctions de décision souvent utilisées :

1 si v ≥ 0 D
• Fonction seuil : f(v) =  avec v = ∑ w i × x i .
0 sin on i =0

1
• Fonction sigmoïde : f ( v) = .
1 + e −v

3.3 Architectures des réseaux de neurones


Plusieurs architectures des réseaux existe. On peut en citer :
• Réseaux à une seule couche

Un réseau à une seule couche ne permet de séparer que des classes


linéairement séparables. On appelle classes linéairement séparables des classes qui
peuvent être correctement séparées par un hyperplan ou une fonction linéaire.

Page 15
La figure suivante illustre trois classes d’objets où chacune d’elle est linéairement
séparable des deux autres.

Classe 1

1
2

Classe 2

Classe
3

• Réseaux multicouches

Couche Couche Couche de


d'entrée cachée sortie

Page 16
Notons que le nombre de couches et le nombre de neurones par couche dépend
principalement du problème étudié et des résultats de l’expérimentation sur
différentes combinaisons des valeurs de ces paramètres..
Les réseaux de neurones à une seule couche sont limités par le fait qu’il ne peut
pas séparer des classes non linéairement séparables.
La figure suivante illustre deux classes d’objets non linéairement séparables qui
peuvent être séparées par l’association de trois hyperplans.

Classe 1
2

Foction de
Classe 2
séparation
3

Pour résoudre un tel problème on utilise les réseaux de neurones multicouches


(c.à.d. avec des couches cachées), avec des neurones de fonction d’activation non
linéaire (des sigmoïdes par exemple).
Il faut remarquer qu’un réseau à une seule couche cachée peut approximer
avec une précision arbitraire toute fonction de séparation, si le nombre de neurones de
la couche cachée est suffisant (Hornik, 1989). Cette affirmation théorique ne donne
pas de règle sur le nombre de neurones que doit posséder la couche cachée. De même,
cette affirmation suppose que l’on dispose d’une base d’apprentissages infinie ce qui
n’est jamais le cas en pratique.
3.4 L’apprentissage
L’apprentissage d’un réseau de neurones artificiels passe par les étapes suivantes :

• Acquisition des données formant la base d’apprentissage.


• Prétraitement : il consiste à localiser, segmenter et normaliser les
représentations.
• Choix des attributs : après le prétraitement on doit extraire des attributs qui
définissent les données. Ces attributs servent comme des entrées au réseau
de neurones.

Avant le traitement des données nous avons donc à effectuer le choix des objets, la
définition des attributs caractérisant les objets et la construction de la base
d’apprentissage. A la fin de cette phase on obtient un tableau de nombres à deux
entrées : les données et les attributs les caractérisant.
L’apprentissage consiste à présenter séquentiellement les exemples et à modifier
les poids synaptiques selon une équation dite équation d’apprentissage.

Page 17
4 Apprentissage et généralisation
4.1 Position d’un problème de classification par réseau de neurones
La conception d’un système de classification, qu’il soit un système de
reconnaissance de formes conventionnel ou un réseau de neurones artificiels,
nécessite les étapes suivantes :
Acquisition des données
Le choix des données initiales est très délicat car il conditionne en grande
partie l’efficacité des performances du réseau de neurones. L’acquisition des données
permet de convertir les données de leurs formes physiques (son, image, etc.) en une
forme acceptable par l’ordinateur.
Prétraitement
Il consiste à localiser, segmenter et normaliser les représentations. Par
exemple pour une image (en occurrence l’image d’un caractère), on cherchera à
supprimer le bruit et à augmenter le contraste.
Le choix des attributs
Le choix d’un vecteur d’attributs pour caractériser un objet peut se révéler
délicat. En effet, il faut faire un compromis entre la dimension du vecteur et le
contenu des informations. Un vecteur de taille trop petite conduirait à de mauvaises
performances du réseau de neurones.
Avant le traitement des données nous avons donc à effectuer le choix des
objets, la définition des attributs caractérisant les objets et la construction de la base
d’apprentissage. A la fin de cette phase on obtient un tableau de nombres à deux
entrées : les données et les attributs les caractérisant.

Les données

X1 X2 … Xd … XD
1 x11 x12 … x1d … x1D
2 x21 x22 … x2d … x2D
… … … … …
Les attributs xn1 xn2 … xnd … xnD
n
… … … … … … …
xN1 xN2 … xNd … xND
N

A la fin de ces étapes on obtient une base de connaissance qui sert comme une
base d’apprentissage.

La décision

Page 18
Ayant une nouvelle observation, il s’agit de décider à quelle classe l’affecter.
Pour que le système soit performant, il faut qu’il se comporte bien sur une base de
données autre que sa base d’apprentissage, cette base s’appelle la base de
généralisation.

4.2 Apprentissage
Comme nous l’avons précédemment dit, l’apprentissage est l’étape essentielle
dans un réseau de neurones (comme le recueil de l’expertise l’est pour un système
expert). Lors de l’apprentissage on cherche à minimiser une erreur, sur la base
d’apprentissage, entre la sortie fournie et la sortie désirée. On espère ainsi minimiser
une erreur sur un ensemble de généralisation, c’est à dire un ensemble de données
inconnues du réseau. On peut arrêter l’apprentissage :

- quand l’erreur entre la sortie du réseau et la sortie désirée ne diminue plus ou


diminue d’une façon non significative,
- après un certain nombre d’itérations fixé a priori,
- pour un problème de classification lorsque le réseau classe correctement toutes les
données.

Le problème de ces méthodes est le risque de sur-apprentissage ou d’apprentissage


″par cœur″. Malheureusement les données sont souvent entachées de bruit, un
apprentissage ″par cœur″ ne permet pas une bonne généralisation. Il est donc
préférable de tester les capacités du réseau pendant la phase d’apprentissage et
d’interrompre celle-ci lorsque l’erreur en généralisation se dégrade.

Il existe trois grandes familles d’apprentissage : l’apprentissage supervisé,


l’apprentissage non supervisé et l’apprentissage hybride qui est une combinaison des
deux premiers.
On parle d’apprentissage supervisé lorsqu’on dispose d’un ensemble de
données dont on connaît la classe d’appartenance a priori (c’est le cas de notre
problème). Il s’agit alors de chercher les surfaces de décision séparant au mieux les
classes. La base d’apprentissage est donc constituée des données et de la réponse que
l’on désire de la part du réseau. On calcul généralement une erreur entre la réponse du
réseau et la réponse désirée. On modifie les paramètres du réseau de façon à réduire
cette erreur.
On parle d’apprentissage non supervisé lorsqu’on on dispose d’une base de
données sans connaître leur classe d’appartenance. Il s’agit de découvrir la structure
sous-jacente aux données sans imposer aucun modèle.

5 Le Perceptron
5.1 Introduction
Le perceptron sert comme UN classificateur linéaire entre deux classes
exclusives C1 et C2.

Nous décrivons dans ce qui suit l’architecture, les équations et l’algorithme


d’apprentissage d’un perceptron.

Page 19
5.2 Architecture du Perceptron

x0 = 1

ω0 = θ

wd Y
xd
Σ f

T
V=W X
wD

xD

La base d’apprentissage est un ensemble constitué de N couples

(X1, T1), (X2,T2), …, (XN,TN).

Pour une donnée Xn la valeur Tn désirée est définie par :

Tn = +1 si Xn appartient à la classe C1

Tn = 0 si Xn appartient à la classe C2

5.3 Equation de propagation avant


v = x0 + w1*x1 + …+ wn * xd

y = f(v)

1
f est la fonction sigmoïde définie par : f ( v) = .
1 + e −v

5.4 Règle d’apprentissage


L’apprentissage consiste à présenter séquentiellement les exemples (Xn, Tn) et
à modifier le vecteur poids W de sorte que l’hyperplan t.W * X = V = 0 sépare le
mieux possible les exemples des deux classes.

Pour ce faire, on applique la méthode du gradient total. Cette méthode consiste


à mettre à jour le vecteur W après avoir présenté au perceptron tous les exemples de
l’ensemble d’apprentissage, et on recommence jusqu’à ce qu’un critère soit minimisé.

Page 20
La fonction de coût partiel est : En = (Tn – yn)2.

La fonction de coût total est égale à la somme : Et=E1+…+ En +… + EN.

Le gradient de la fonction est :

W(t+1) = W(t) - µ(t) * (∂En / ∂W)

L’apprentissage devient un problème de minimisation d’une fonction coût


avec les risques de minima locaux.

On a :

∂E n ∂E n ∂y ∂v
= . . .
∂w d ∂y ∂v ∂w d

Or :

∂E n
= −(Tn − y n )
∂y

et


∂y  1 
=  = y.(1 − y)
∂v  1 + e − v 

et

∂v
= xd .
∂w d

La règle d’apprentissage devient donc :

wd(t+1) = wd(t) + µ(t) * (Tn - y) . y . (1-y) . xd.

Cette règle s’écrit sous la forme vectorielle suivante :

W(t+1) = W(t) + µ(t) * (Tn - yn) . y . (1 - y) . X

Le choix de µ(t) doit être tel que 0 < µ(t) <1.

5.5 L’algorithme
1- Prendre t=0; fixer µ (entre 0 et 1) et W(t=0) (vecteur aléatoire entre 0 et 1); n=1
2- Prendre Xn (N attributs du n-ième couple).
3- Calculer V = W T ( t ).X
n
4- Calculer y = f(V)

Page 21
5- Calculer W(t + 1) = W(t) + µ(t).(Tn - y).f ' (V).X n
6- Faire n = n+1 ; t = t+1. Si N=n aller à 7 sinon aller à 2.
7- Si critère d’arrêt est vrai Stop, sinon (n=1, aller à 2).
6 Réseaux multicouches
6.1 Introduction
Le perceptron permet de traiter des problèmes simples où les classes sont
linéairement séparables. Pour résoudre un problème de classification entre plusieurs
classes non linéairement séparables, on utilise donc des réseaux multicouches. Il
n’existe pas de forme spécifique représentative des réseaux de neurones multicouches
en dehors du fait qu’ils possèdent plusieurs couches internes. En particulier le nombre
de couches et le nombre de cellules par couche cachées dépend principalement du
problème étudié.

Dans notre application, nous mettons en oeuvre un réseau de neurones


multicouche avec une seule couche cachée (qui est un classificateur universel) dont la
structure et le fonctionnement est décrit dans ce qui suit.

6.2Architecture

couche d’entrée couche cachée couche de sortie

Cette figure montre l’architecture d’un perceptron multicouches avec une


couche cachée. Le réseau est dit entièrement connecté.

Il s’agit là d’un apprentissage supervisé qui consiste à réduire progressivement


la différence entre les valeurs de sortie désirée et les valeurs des sorties du réseau.
Ceci se fait par modification progressive des poids synaptiques. Pour cela, on
propage, à partir de l’erreur constatée sur la couche de sortie, la correction apportée à

Page 22
tous les poids du réseau. Cette technique s’appelle la rétro-propagation du gradient de
l’erreur.

Pour utiliser cette méthode, il s’agit de pouvoir disposer d’une fonction


d’activation f dérivable. Dans la plupart des cas on utilise la fonction sigmoïde.

On dispose d’une base d’apprentissage (Xn, Tn) avec

Xn = (x1, … , xd, …. , xD)

Tn = (01230,1,0,...0) si l’observation Xn appartient à la classe Ck.


,...,
k −1

6.3 Equations de propagation avant


uh = wh0 + wh1. x1 + … + whd. xd + …. + whD. xD

1
sh = f(uh) = −u h
.
1+ e

vk = wk0 + wk1. s1 + … + wkh. sh + …. + wkH. sH

1
yk = f(vk) = − vk
.
1+ e

6.4 Erreur à minimiser


A la présentation d’un couple (Xn, Tn), l’erreur relative à ce couple est :

1
En = ∑
2 k
(Tnk − y nk ) 2

On a donc :

∂E n ∂E n ∂y k ∂v k
= . . = −(Tnk − y nk ).y k .(1 − y k ).s
∂Wk ∂y k ∂v k ∂Wk

∂E n ∂E ∂y ∂v ∂s ∂u
= ∑ n . k . k . h . h = ∑ − (Tnk − y k ). y k .(1 − y k ).wkh .s h .(1 − s h ). X
∂Wh k ∂y k ∂v k ∂s h ∂u h ∂Wh k

Donc les règles d’apprentissages sont :

∂E n
Wk ( t + 1) = Wk ( t ) − µ( t ).( ).
∂Wk

Page 23
∂E n
Wh ( t + 1) = Wh ( t ) − µ( t ).( )
∂Wh

Notons que :

Wk = (wk0, wk1, …, wkh, ….., wkH)

Wh = (wh0, wh1, …, whd, ….., whD)

6.5 Algorithme
1- Prendre t=0; fixer γ, wk0(0),wkh(0),wh0(0),whd(0).
2- Sélectionner un exemple (Xn,Tn) de la base d’apprentissage.
3- Propagation avant :
d =D
s h = f( ∑ w hd * x d )
d =0

h =H
y k = f( ∑ w kh * s h )
h =0
4- Apprentissage par Retro-propagation :

w hd (t + 1) = w hd (t) + µ(t).(Tnk - y k ).f ' ( v k ).s h


k =K
w kh (t + 1) = w kh (t) + µ(t) * ∑ (Tnk - y k ) * f ' ( v k ) * w kh . f ' (u h ).x d
k =1
n = n+1 ; t = t+1
5- Si N = n aller à 6, sinon aller à 2
6- Si critère d’arrêt vrai Stop, sinon (n=1, aller à 2)

Le critère d’arrêt peut être fixer expérimentalement, oubien en testant l’erreur


En.
7 Conclusion
Dans ce chapitre, nous avons introduit les réseaux de neurones. Nous avons vu
comment on peut résoudre le problème de classification par des réseaux de neurones
multicouches.

Nous expliquons dans le chapitre suivant comment on peut appliquer la théorie


des réseaux de neurones dans la domaine de reconnaissance des caractères.

Page 24
Chapitre 3
Reconnaissance de chiffres indiens et arabes :
Travail réalisé
1 Introduction
Le présent chapitre présente les différents algorithmes et méthodes mis en
oeuvre lors de la réalisation de ce projet. Pour réaliser un système de reconnaissance
de chiffres indiens, on passe par les étapes illustrées sur la figure suivante.

Prétraitement Classification
Aquisition

Dans l’étape d’acquisition on doit acquérir une base de données représentant


les différentes formes des chiffres manuscrits (arabes ou hindi). L’acquisition de cette
base se fait par l’une des méthodes suivantes :

- Acquisition des chiffres par un logiciel graphique (Paintbrush) sous forme d’images
binaires.
- Acquisition des chiffres à l’aide d’un Scanner (pour des applications en mode
statique ou off-line).
- Acquisition des chiffres par une caméra vidéo (pour des applications en temps réel).

Le prétraitement passe par trois étapes :

- Nettoyage et amincissement de l’image de chaque caractère dans la base


(nécessaire dans le cas d’acquisition par un scanner ou une caméra).
- Normalisation de la taille d’un caractère.
- Centrage de l’image.
- Extraction des attributs.

La classification se fait par un réseau de neurones multicouches, en utilisant


l’algorithme de rétro-propagation d’erreur.

Dans le cadre de ce projet nous avons implémenté en Matlab et puis en


langage C les algorithmes suivants :

- Un algorithme qui lit les images binaires stockées en format BMP.


- Un algorithme d’amincissement.
- Un algorithme de centrage.

Page 25
- Un algorithme de normalisation de la taille de l’image.
- Un algorithme d’extraction des attributs.
- L’algorithme de fonctionnement d’un perceptron pour reconnaître les
chiffres 0 et 1.
- Un algorithme de fonctionnement d’un réseau multicouches (pour la
reconnaissance des chiffres entre 0 et 9 en arabe et en indien).

Les fonctions en C (et en Matlab) qui réalisent ces algorithmes (voir Annexe B) sont :

- wmulc : elle met en oeuvre l’algorithme d’un réseau de neurone multicouches.


- wmulcd : fonction de classification d’un nouvel exemple.
- wpretr : fonction de normalisation, centrage d’un caractère.
- manu : fonction d’apprentissage.
- centrage : fonction de centrage d’un caractère.
- wattr : fonction qui calcule les attributs des images.
- decider : fonction de reconnaissance d’un chiffre unique.
- sequence : fonction de reconnaissance d’une séquence de chiffres.
- extract : fonction d’extraction d’un objet de label donné.
- imreadbmp : fonction qui lit un fichier BMP monochrome.
- app : fonction qui prend une image, fait le prétraitement nécessaire, puis
enregistre les attributs d’image X et sa classe (Target) T dans le fichier de base.
- squ : fonction d’amincissement.
-
Dans la suite de ce chapitre on détaille la présentation de ces algorithmes et de ces
fonctions.

2 Représentation des images sur un ordinateur


Nous présentons dans ce paragraphe la méthode de représentation d’une image
sur un ordinateur, ce qu’on appelle image digitale (numérique).
Deux éléments sont nécessaires pour obtenir une image digitale. Le premier
est un élément physique sensible au rayonnement électromagnétique, et qui
transforme cette énergie en un signal électrique. Le second élément a pour but
d’échantillonner et quantifier ce signal électrique et on obtient alors ce qu’on appelle
image digitale. Cette procédure a pour but donc de transformer une image analogique
(continue) en une image digitale (discrète).

Page 26
Chaque point (i, j) d’une image digitale s’appelle pixel. Les caractéristiques d’une
image digitale sont :

• Taille : NC×NL (exemple : 25×40, 100×100, etc.)


• Résolution : taille du pixel ramené à l’objet
• Profondeur : c.à.d. niveau de quantification (2 pour image monochrome, 256 pour
image en niveau de gris, etc.).

Une image sur l’ordinateur peut donc être représentée sur l’ordinateur par un
tableau 2-D x(i, j).
Dans le cas d’une image monochrome, chaque x(i, j) prend deux valeurs : 0 pour
blanc, 1 pour noir. L’espace mémoire nécessaire pour cette image (appelée aussi
image binaire) est donc : NC×NL bits.
Dans le cas d’une image en niveau de gris, x(i, j) prend les valeurs entre 0 (pour
blanc) et 255 (pour noir). Les autres valeurs représentent toutes les couleurs grises.
L’espace mémoire nécessaire pour cette image est donc : NC×NL octets.
On peut stocker les images digitales dans des fichiers sous différents formats,
parmi lesquels on peut citer les formats BMP, GIF, …etc.
Dans notre projet nous écrivons une fonction C imreadbmp qui lit une image
binaire dans un tableau 2-D.

3 Les descripteurs d’image

Les descripteurs d’image sont des paramètres (attributs) qui caractérisent les
propriétés de l’image. Au lieu de caractériser une image par ses pixels (10000
données dans le cas d’une image 100× ×100), on peut réduire ces données en
caractérisant l’image par ces descripteurs.
Différents descripteurs d’image existent, parmi lesquels on peut citer :

- les paramètres de la transformée de Fourrier 2-D.


- descripteurs de courbure.
- moments géométriques.

Puisque nous utilisons les moments géométriques, nous présentons ces


descripteurs dans ce qui suit.

Page 27
Les moments géométriques sont :

µ pq
µ 'pq =
p q
µ00 × ( + + 1)
2 2
µ pq = ∑∑ (i p - IG) × (jq - JG) × I(i, j)
i j

IG = ∑∑ i × I(i, j)
i j

JG = ∑∑ j × I(i, j)
i j

IG, JG : centre de masse


µpq : moments géométriques centrés.
µ′pq : moments géométriques normés.

4 Acquisition de l’image
Nous faisons l’acquisition de l’image par l’une des deux méthodes suivantes :

- à l’aide de la souris dans le logiciel ″Paintbrush ″.


- en utilisant un scanner.

Dans le premier cas nous écrivons pour chaque chiffre 20 exemples, donc nous
avons un total de 20×10 exemples. Chaque image d’un chiffre a une taille de 100×100
pixels.
Ces exemples se trouvent pour les chiffres hindi dans le répertoire ″aimibase ″.
Le répertoire aimibase contient les sous répertoires 0,1,2,3,4,5,6,7,8,9. Dans chacun
de ces sous répertoires, on trouve les 20 exemples d’un chiffre (par exemple 0
contient les 20 exemples 01 à 020. De même pour les chiffres arabes le répertoire est
″imbase ″.
Dans le second cas, nous écrivons les exemples sur du papier blanc, et à l’aide
d’un scanner nous obtenons des images binaires de format BMP. Les images obtenues
ont une taille de 100×100 et de résolution 500 dpi. L’Annexe A contient ces
exemples.

5 Prétraitement
Dans le prétraitement on passe par les étapes suivantes :

1- amincissement (nécessaire dans le cas de scanner).

2- Normalisation.

3- amincissement (car la normalisation épaissit le chiffre) .

4- Centrage.
Page 28
5- Extraction des attributs (c.à.d. des descripteurs de caractère).

5.1 Normalisation
La taille d’un caractère peut varier d’une écriture à l’autre, ce qui peut causer
une instabilité des paramètres (descripteurs de ce caractère). Une technique naturelle
de prétraitement consiste à ramener les caractères à la même taille.
Nous donnons dans ce paragraphe un algorithme de normalisation de la taille.

On commence par la présentation d’une méthode de variation de la taille d’une


image. Soit un objet de taille N1×M1 qu’on souhaite ramener à la taille N×M.

La technique est la suivante :

Si (i, j) est un pixel dans l’image finale (de taille N*M), le pixel correspondant
dans l’image source (de taille (N1*M1) ) est ([ (i*N1)/N ], [ (j*M1)/M ].
L’algorithme de variation de taille est donc :

1- Soit a l’image source et b l’image finale.


2- pour i = 0 à N-1
pour j = 0 à M-1
b(i, j) = a([(i*N1)/N],[(j*M1)/M])
finpour
finpour

Voici un exemple de résultat d’application de cette technique :

Page 29
Dans notre projet on cherche la dimension d’un caractère et on la normalise à
Reso*Reso ( Reso = 100 dans le cas de la base acquise par Paintbrush, Reso = 25 dans
le cas de la base acquise par scanner).
Notons que l’image résultante de cette technique de normalisation amène à
une image trop épaisse. Il faut donc une phase d’amincissement pour obtenir une
image d’épaisseur uniforme entre toutes les images de la base d’apprentissage et pour
celles des nouvelles observations.
Voici un exemple de la normalisation (variation de la taille + amincissement)
d’un caractère.

5.2 Centrage
Puisqu’un chiffre peut être de différentes tailles, rien ne l’empêche d’être
positionné n’importe où dans la fenêtre qui lui est consacrée, comme le montre la
figure ci-après :

Pour des raisons d’homogénéité entre la base d’apprentissage et les images des
chiffres que le réseau aura à reconnaître, il est nécessaire de ramener le chiffre au
centre du carré. Les descripteurs de l’image de ce chiffre seront ainsi indépendants par
translation (c.à.d. indépendants de la position du chiffre dans la figure). Voici une
méthode de centrage d’un objet.

Page 30
Premièrement on cherche le carré dans lequel on peut mettre l’objet, c.à.d. on
trouve Imin, Imax, Jmin, Jmax. On calcul alors le centre du carré (xc, yc), et enfin on
fait une translation de l’image de manière que le centre (xc, yc) soit au centre de la
fenêtre, c.à.d. on fait translater l’objet des valeurs :

 Re so − 1
Tx =   ([ ] désigne la partie entière)
 2 − xc 
 Re so − 1
Ty =  
 2 − yc 

Si x(i,j) est la matrice intensité de l’image originale, alors la translatée de x de valeur


horizontale Tx et de valeur verticale Ty est l’image a(i,j) telle que :

a(i+Ty, j+Tx) = x(i,j).

L’algorithme de centrage est donc :

1- Soit x une matrice de dimension Reso×Reso qui représente l’image originale.

La translatée a est une matrice de dimension Reso*Reso.

Jmin = Reso-1 ;

Jmax = 0 ;

Imax =Reso-1 ;

Imin = 0 ;
2- pour i = 0 à Reso-1
pour j = 1 à Reso-1
si (x(i,j) = 1) alors
si (j<Jmin) alors Jmin = j;
si (j>Jmax) alors Jmax = j;
si (i<Imin) alors Imin = i;
si (j>Imax) alors Jmax = i;
finsi
finpour

Page 31
finpour
// centre de l’objet
yc = [(Imin+Imax)/2] ;
xc = [(Jmin+Jmax)/2] ;
(pas de translation)
Tx = [(Reso-1)/(2 –xc)]
Ty = [(Reso-1)/(2 –yc)]
pour i = 0 à Reso-1
pour j = 1 à Reso-1
si (x(i,j) = 1) alors
a(i+Ty,j+Tx) = x(i,j)
finsi
finpour
finpour

a contient la matrice de l’image centrée.

Cet algorithme a été programmé en C et en Matlab. La fonction C est la suivante :

void centrage (matimage a,matimage x, int Reso) ;

x est une matrice de dimension Reso×Reso contenant l’image originale


a est une matrice de dimension Reso×Reso contenant l’image centrée
Reso est la dimension de l’image

Le code de cette fonction se trouve en Annexe B.


5.3 Amincissement

Les caractères acquis sont d’une épaisseur variable, ce qui peut produire des
instabilités dans les paramètres caractérisant un objet (chiffre par exemple). Il est donc
nécessaire de rendre le caractère d’épaisseur 1 (c.à.d. un pixel) avant d’extraire ses
attributs. Cette technique constitue l’étape d’amincissement du caractère.

Les deux critères retenus pour les méthodes d’amincissement sont les
suivants :

1- l’épaisseur du caractère aminci doit être de 1.


2- le caractère aminci doit conserver les propriétés topologiques de la forme
comme le nombre de parties, le nombre de trous et la connexité.

Nous présentons dans ce paragraphe, un algorithme d’amincissement d’un objet


binaire. Cet algorithme est un algorithme itératif. Dans cette méthode on passe
successivement par deux étapes appliquées sur chaque point de l’objet.

1ère étape :

Dans la première étape, chaque point p1 de l’objet sera mis à 0 (c.à.d. effacé) si les
quatre conditions suivantes sont satisfaites :

Page 32
a- 2 ≤ N(p1) ≤ 6 ;
b- S(p1) = 1 ;
c- p2.p4.p6 = 0 ;
d- p4.p6.p8 = 0 ;

où les pi sont égaux soit à 0 soit à 1 et :

N(p1) = nombre voisins de p1 qui sont non nuls


= p2+p3+p4+p5+p6+p7+p8+p9

Le tableau ci-après présente les 8-voisins d’un point p1.

p9 p2 p3
P8 P1 p4
p7 P6 P
5

Si p1 est d’indice (i, j), alors p9 est d’indice (i-1, j-1), p8 d’indice (i-1, j), p3 d’indice (i-
1, j+1), p8 d’indice (i, j-1), p4 d’indice (i, j+1), p7 d’indice (i+1, j-1), p6 d’indice (i+1,
j),et p5 d’indice (i+1, j+1).

S(p1) = nombre de transitions 0-1 dans la séquence p2, p3, …, p9.

Par exemple, pour le point p1 ci-après on a : N(p1) = 4 et S(p1) = 3 dans la figure


suivante.
0 0 1
1 p1 0
1 0 1

Après l’application de l’étape 1 pour chaque point dans la région binaire, on


obtient une image dans laquelle on a effacé tous les points qui vérifient les conditions
a, b, c, d. Il faut noter que dans cette étape on n’efface un point qu’après le balayage
de toute l’image.

2ème étape :

Sur l’image obtenue après l’application de l’étape 1, on applique l’étape 2, qui


consiste à supprimer tout point p1 vérifiant les 4 conditions suivantes :

a1- 2 ≤ N(p1) ≤ 6 ;
b1- S(p1) = 1 ;
c1- p2.p4.p8 = 0;
d1- p2.p6.p8 = 0 ;

Une itération dans cet algorithme consiste donc à :

1- appliquer l’étape 1 à chaque point de l’image.


2- effacer tout point vérifiant les 4 conditions a, b, c, d.

Page 33
3- appliquer l’étape 2 à l’image obtenue suite à l’étape 1.
5- effacer tout point vérifiant les 4 conditions a1, b1, c1, d1.

Cette itération de base sera appliquée itérativement jusqu’à qu’une itération


n’apporte pas de variation à l’image.
Voici la représentation algorithmique de cette méthode d’amincissement :

1- Soit x une matrice représentant l’image originale de dimension Reso×Reso.


a sera une matrice de dimension Reso×Reso.
b sera une matrice de dimension Reso×Reso.
NN = 0 ( NN représente N(p1))
S = 0 (S représente S(p1))
cond = false (cond est une variable qui sera vraie si l’algorithme est fini)
2- tant que cond = false, faire
a=x;
(étape 1)
pour i = 1 à Reso
pour j = 1 à Reso
NN=0 ; S=0 ;
Si x(i, j) =1 alors
NN = x(i-1,j) + x(i-1,j+1) + x(i,j+1) + x(i+1,j+1)
+ x(i+1,j) + x(i+1,j-1) + x(i,j-1) + x(i-1,j-1) ;
si x(i-1,j)=0 et x(i-1,j+1)=1 alors S=S+1 finsi
si x(i-1,j+1)=0 et x(i,j+1)=1 alors S=S+1 finsi
si x(i,j+1)=0 et x(i+1,j+1)=1 alors S=S+1 finsi
si x(i+1,j+1)=0 et x(i+1,j)=1 alors S=S+1 finsi
si x(i+1,j)=0 et x(i+1,j-1)=1 alors S=S+1 finsi
si x(i+1,j-1)=0 et x(i,j-1)=1 alors S=S+1 finsi
si x(i,j-1)=0 et x(i-1,j-1)=1 alors S=S+1 finsi
si x(i-1,j-1)=0 et x(i-1,j)=1 alors S=S+1 finsi
finsi
si NN ≥ 2 et NN ≤ 6 et S = 1
et x(i-1,j)*x(i,j+1)*x(i+1,j)=0 et x(i,j+1)*x(i+1,j)*x(i,j-1)=0
alors
a(i,j) = 0
finsi
finpour
fnipour
b=a;
(étape 2)
pour i = 1 à Reso
pour j = 1 à Reso
NN=0 ; S=0 ;
Si a(i,j) =1 alors
NN= a(i-1,j) + a(i-1,j+1) + a(i,j+1) + a(i+1,j+1)
+ a(i+1,j) + a(i+1,j-1) + a(i,j-1) + a(i-1,j-1) ;
si a(i-1,j)=0 et a(i-1,j+1)=1 alors S=S+1 finsi
si a(i-1,j+1)=0 et a(i,j+1)=1 alors S=S+1 finsi
si a(i,j+1)=0 et a(i+1,j+1)=1 alors S=S+1 finsi
si a(i+1,j+1)=0 et a(i+1,j)=1 alors S=S+1 finsi

Page 34
si a(i+1,j)=0 et a(i+1,j-1)=1 alors S=S+1 finsi
si a(i+1,j-1)=0 et a(i,j-1)=1 alors S=S+1 finsi
si a(i,j-1)=0 et a(i-1,j-1)=1 alors S=S+1 finsi
si a(i-1,j-1)=0 et a(i-1,j)=1 alors S=S+1 finsi
finsi
si NN ≥ 2 et NN ≤ 6 et S = 1
et a(i-1,j)*a(i,j+1)*a(i+1,j)=0 et a(i,j+1)*a(i+1,j)*a(i,j-1)=0
alors
b(i,j) = 0
finsi
finpour
fnipour
(test de changement de l’image)
cond = true ;
pour i = 1 à Reso
pour j = 1à Reso
si x(i,j) ≠ b(i,j) alors cond = false finsi
finpour
finpour
fintantque

La matrice b contient alors l’image après amincissement.

Voici des exemples illustrant l’application de cet algorithme.

Cet algorithme a été programmé en C et en Matlab. La fonction C est la suivante :

void squ (matimage y, int Reso) ;

y est une matrice de dimension Reso*Reso


Reso est la dimension de l’image.

Le code de cette fonction se trouve en Annexe B.

5.4 Extraction des attributs


Parmi les différents descripteurs d’objet, nous avons choisi les moments
géométriques, car ces moments tiennent compte de l’organisation interne du caractère,
et réduisent considérablement le nombre d’entrées au réseau.

Page 35
Soit I la matrice intensité de l’image.

Ces moments sont :

µ pq
µ 'pq =
p q
µ00 × ( + + 1)
2 2
µ pq = ∑∑ (i p - IG) × (jq - JG) × I(i, j)
i j

IG = ∑∑ i × I(i, j)
i j

JG = ∑∑ j × I(i, j)
i j

La fonction C que nous avons développée pour le calcul des {n} premiers moments
est la suivante:

void wattr(matimage y, vectattr a, int Reso)

y est une image de type matimage (c.à.d. c’est une matrice Reso*Reso)

a est un vecteur de type vectrattr (c.à.d. c’est un vecteur de dimension {n})

Reso est la résolution de la matrice y

Il faut noter que le choix du nombre d’attributs ({n} dans notre exemple) a été fixé
après expérience.

5.5 Prétraitement et obtention de la base d’apprentissage


La phase de prétraitement est donc :

Les fonctions C qui réalisent le prétraitement et l’obtention de la base


d’apprentissage sont les suivantes :

void wpretr( matimage a1, matimage x, int Reso)


void app(int & sor)

La fonction wpretr prend l’image x, calcule la dimension (N1,M1) de l’objet


x, et la normalise à la valeur Reso×Reso (en utilisant l’algorithme de normalisation
déjà présenté), puis elle centre l’objet normalisé. Le résultat de cette fonction se
trouve dans a1.
La fonction app est utilisée pour entrer une image dans la base d’apprentissage
(c.à.d. pour calculer le vecteur d’attributs correspondant enregistrer ce vecteur dans
la base avec sa classe réelle (sortie désirée)). Lorsqu’on exécute app, on donne (au
Page 36
clavier) le chemin de fichier BMP contenant l’image, la classe de l’objet est donné en
paramètre (Target) (on entre la classe du caractère puisqu’il s’agit d’un apprentissage
supervisé). Cette image est alors amincie puis traitée par la fonction wpretr puis
amincie par la fonction squ . On calcule ensuite le vecteur d’attributs à l’aide de la
fonction wattr, et ce vecteur est enregistré dans le fichier de la base d’apprentissage
avec la classe de l’image.

6 Classification
Nous avons effectué la classification de caractères à l’aide d’un réseau de
neurones multicouches (voir chapitre 2). Nous présentons dans ce paragraphe les
fonctions C et Matlab que nous avons réalisé pour effectuer l’apprentissage d’un
réseau de neurones, et celles pour la classification d’un un nouvel exemple.

6.1 La fonction de simulation d’un réseau multicouche

La fonction C que nous avons réalisé pour simuler l’apprentissage d’un réseau
de neurones multicouches en utilisant l’algorithme de retro-propagation de gradient
est la suivante :

void wmulc( vectwk0 wk0, matwkh wkh, vectwh0 wh0, matwhd whd, matbase xx,
int Iter, int K, int D, int N)

wk0 est le vecteur poids de connexion couche cachée - couche de sortie du neurone 0
de dimension K
wkh est la matrice poids de connexion couche cachée - couche de sortie du neurone h
de dimension K×H
wh0 est le vecteur poids de connexion couche d’entrée - couche cachée du neurone 0
de dimension H
whd est la matrice poids de connexion couche d’entrée - couche cachée du neurone d
de dimension H×D
xx est la matrice de la base d’apprentissage (c.à.d. de couple (Xn,Tn). Cette matrice est
de dimension N*(D+1)

Page 37
Iter est le nombre de cycles d’apprentissage
K est le nombre de classe (10 dans l’exemple des chiffres)
D est le nombre de d’entrées ({n} attributs).
N est le nombre d’exemples dans la base d’apprentissage.

L’algorithme mis en oeuvre dans cette fonction est le suivant :

1- Normaliser la base xx entre 0 et 1 (cette phase est essentielle car la fonction


sigmoïde est comprise entre 0 et 1)
La méthode de normalisation est la suivante :
Soit Base la matrice base normalisée de dimension N*D
Base(n,d) = (xx(n,d)-xmin(d))/(xmax(d) – xmin(d))
xmin(d) est le minimum des xx(n,d) pour un d donné
xmax(d) est le maximum des xx(n,d) pour un d donné
2- Target(n,k) = 1 pour un indice k égal à la classe de l’objet d’attributs Xn
0 pour les autres k
Target(n,k) correspond à l’attribut Base(n,d)
3- Application de l’algorithme de réseau de neurones multicouches (Voir chapitre 2),
pour le calcul des poids de connexion wk0, wkh, wh0, whd. L’algorithme est
appliqué sur la base Base de classe Target.

La même fonction est aussi réalisée en Matlab. Elle est de la forme :

fucnction [wk0, wkh, wh0, whd,] = wmulc(xx, Iter, K, D, N).

6.2 L’apprentissage
La fonction manu utilise la fonction wmulc pour calculer les poids de
connexions wk0, wkh, wh0, whd. Il enregistre alors ces poids dans des fichiers, pour
être utilisés dans la decision (fonction wmulcd).

7 Algorithme de reconnaissance d’une série de chiffres


Pour reconnaître une séquence de chiffres, on doit d’abord extraire chaque
chiffre de la séquence pour le classifier ensuite avec le réseau.
Puisque les chiffres d’une séquence ne sont jamais accolés les uns aux autres,
l’extraction des chiffres de la séquence est relativement simple.

On commence par un balayage vertical de l’image jusqu’à rencontrer la


première colonne non vide, alors on donne au pixel de cette colonne le label 1 ; si la
colonne suivante est aussi non vide on donne au pixel de cette colonne aussi le label 1

Page 38
et ainsi de suite jusqu’à rencontrer une colonne vide. On continue le balayage jusqu’à
rencontrer une colonne non vide ; alors on donne au pixel de cette colonne le label 2 ;
si la colonne suivante est aussi non vide on donne au pixel de cette colonne aussi le
label 2, et ainsi de suite jusqu’à rencontrer une colonne vide ; et on applique cette
procédure jusqu’à arriver à finir le balayage vertical de l’image. On aura ainsi donnée
un label à chaque chiffre de l’image.

L’écriture algorithmique de cette méthode de ″labelisation″ est la suivante :

1- Soit aa la matrice de dimensions ydim×xdim représentant l’image d’une séquence


de chiffres.

x est la matrice de dimensions ydim×xdim dans laquelle on met le label de chaque


pixel (c.à.d. à quel chiffre appartient chaque pixel).

Label = 0

2- pour j = 0 à xdim –1

cond1 = 0 ;

pour i = 0 à ydim –1

si aa(i,j) = 1 alors

cond1 =1 ; (on trouve une colonne non vide)

x(i,j) = label ;

finsi

finpour

cond2 =0 ;

pour i = 0 à ydim –1

si aa(i,j+1) = 1 alors

cond2 =1 ; (on trouve une colonne non vide)

finsi

finpour

si (cond1=0 et cond2=0) alors label = label +1 finsi

finpour

Après labelisation de chaque pixel de l’image on extrait chaque chiffre par la


fonction extract.

Page 39
La fonction C correspondante est la suivante :

void extract(matimage a, matim x, int xdim, int ydim, int label)

a est l’image extraite

x image de la séquence de dimension ydim×xdim

xdim dimension horizontale de l’image

ydim dimension verticale de l’image

label est le label de l’image a extraire de x

L’algorithme d’extraction est le suivant :

1- x est l’image de la séquence de dimension ydim×xdim

a est la matrice de l’image extraite de dimension Res×Res

Jmin = xdim -1 ; Jmax = 0 ; Imin = ydim –1 ; Imax=0 ;

2- pour i = 0 à ydim -1

pour j = 0 à xdim –1

si x(i,j) = label alors


si (j<Jmin) alors Jmin = j finsi
si (j>Jmax) alors Jmax = j finsi
si (i<Imin) alors Imin = i finsi
si (j>Imax) alors Jmax = i finsi
finsi
finpour
N1 = Imax – Imin ; M1 = Jmax – Jmin ;
pour i = Imin à Imax
pour j = Jmin à Jmax
si (x(i,j) =label alors
a(i-Imin, j-Jmin) = 1
finsi
finpour
finpour

Les phases d’une reconnaissance d’une séquence de chiffres réalisée par la


fonction sequence sont donc les suivantes :

1- Numérotage de chaque pixel (c.à.d. donner un label à chaque chiffre et ceci en


utilisant l’algorithme de labelisation déjà vu).
2- Extraction de chaque chiffre (en utilisant extract), on commence par le chiffre de
label 1, puis celui de label 2, et ainsi de suite.
3- Prétraitement de chaque chiffre extrait (Normalisation, centrage, amincissement,
extraction des attributs).

Page 40
On utilise pour cela la fonction wpretr puis la fonction squ puis la fonction wattr.
4- Classification de chaque chiffre par la fonction wmulcd (on utilise les poids de
connexion calculés par la fonction manu).
5- On répète l’étape 3- et 4- pour finir la classification de tous les chiffres.

Ce sont les étapes utilisées donc pour réaliser la reconnaissance d’une série de
chiffres.

Nous avons aussi réalisé une version de cette fonction sous Matlab.

Page 41
Chapitre 4
Résultats et étude de l’influence des
paramètres sur la performance du système
1 Introduction
Dans ce chapitre nous présentons les résultats des différents algorithmes de
prétraitement, ainsi que les influences des paramètres sur la performance du système
de reconnaissance de chiffres (c.à.d sur l’erreur commise lors de la décision). Ces
paramètres sont :

- le nombre d’exemples dans la base d’apprentissage,

- le nombre d’itérations pendant la phase d’apprentissage,

- le nombre d’attributs (moments géométriques).

2 Résultats des algorithmes de prétraitement


2.1 Résultats de l’algorithme de centrage
Voici des exemples résultant de l’application de l’algorithme de centrage :

On voit bien que cet algorithme amène le chiffre (voir figure gauche) au centre de
la figure (voir figure droite).

2.2 Résultats de l’algorithme d’amincissement


Voici des exemples des résultats de l’algorithme d’amincissement :

Page 42
Ces figures montrent l’application de l’algorithme d’amincissement sur des
exemples de la base d’apprentissage.

2.3 Résultats de normalisation


Voici des exemples résultant de l’application de l’algorithme de
normalisation :

On voit qu’après normalisation le chiffre devient épais d’où la nécessité de


d’amincissement après la phase de normalisation.

2.4 Résultats de l’algorithme final de prétraitement


Le prétraitement comporte les étapes suivantes :

Page 43
Voici des exemples de résultats de prétraitement global :

3 Influence des paramètres


3.1 Influence du nombre d’exemples dans la base d’apprentissage
Nous utilisons une base d’apprentissage et une base de test (la base de test
contient des exemples qui n’appartiennent pas à la base d’apprentissage).

Cas des chiffres hindi acquis par un scanner :

Pour une base d’apprentissage de 50 exemples (5 exemples pour chaque


chiffre) nous arrivons à un taux d’erreur de 20% sur la base d’apprentissage, et de
42% sur la base de test (généralisation).

Pour une base d’apprentissage de 100 exemples (10 exemples pour chaque
chiffre) nous arrivons à un taux d’erreur de 17% sur la base d’apprentissage, et de
34% sur la base de test (généralisation).

Pour une base d’apprentissage de 200 exemples (20 exemples pour chaque
chiffre) nous arrivons à un taux d’erreur de 15.5% sur la base d’apprentissage, et de
28% sur la base de test (généralisation).

Cas des chiffres arabes acquis par un scanner :

Pour une base d’apprentissage de 50 exemples (5 exemples pour chaque


chiffre) nous arrivons à un taux d’erreur de 22% sur la base d’apprentissage, et de
52% sur la base de test (généralisation).

Page 44
Pour une base d’apprentissage de 100 exemples (10 exemples pour chaque
chiffre) nous arrivons à un taux d’erreur de 17% sur la base d’apprentissage, et de
44% sur la base de test (généralisation).

Pour une base d’apprentissage de 300 exemples (30 exemples pour chaque
chiffre) nous arrivons à un taux d’erreur de 16% sur la base d’apprentissage, et de
36% sur la base de test (généralisation).

On voit bien que le taux d’erreur diminue lorsque le nombre d’exemples


augmente dans la base d’apprentissage.

Notons aussi que dans les différentes publications concernant la


reconnaissance de chiffres par réseau de neurones, la plus petite base d’apprentissage
contient 5000 exemples, alors que notre base contient au plus 300 exemples, ce qui
explique notre taux d’erreur relativement élevé.

3.2 Influence du nombre d’itérations sur la base d’apprentissage

Nombre Taux d’erreur Taux d’erreur


d’itérations sur la base sur la base de
d’apprentissage test
100 59 60
200 47.5 53
500 41 43
1000 31 41
2000 26 40
7000 20 32
7500 20 30
8000 20 28
10000 17 33
16000 17 33
30000 15.5 33

Base d'apprentissage de20 exemples pour chaque chiffre

70
% des exemples mals classés

60

50

40 Erreur
d'apprentissage
30
Erreur de
20
généralisation
10

0
0 10000 20000 30000 40000
Nombre d'itérations

Page 45
Une itération consiste à passer par tous les exemples de la base
d’apprentissage une seule fois. On observe que le taux d’erreur sur la base
d’apprentissage diminue toujours lorsque le nombre d’itérations augmente.

Sur la base de généralisation (base de test) ce taux passe par un minimum puis
augmente à nouveau, donc il faut arrêter l’apprentissage à un certain nombre
d’itérations déterminé expérimentalement (8000 dans le tableau ci-dessus). Ce
phénomène s’appelle apprentissage par cœur, c.à.d le réseau apprend bien les
exemples de la base d’apprentissage, et ne décide pas bien sur la base de test.

3.3 Influence du nombres d’attributs


Le nombre de moments géométriques qu’on doit utiliser pour décrire un
chiffre doit être déterminé expérimentalement, pour obtenir le plus petit nombre
possible de ces moments donnant une bonne performance du système.

Le tableau suivant montre la variation de taux d’erreur suivant le nombre de


moments géométriques sur une base d’apprentissage de 200 exemples hindi acquis
manuellement.

Nombre de moments Erreur d’apprentissage (%) Erreur de test (%)

1 85 86

2 25 26

3 10 12

4 9 12

5 8 9

6 8 8

8 8 8

13 6 8

On voit qu’on peut limiter le nombre de ces attributs à 6.

4 Performances temporelles
Il nous a semblé intéressant d’évaluer les performances temporelles de notre
système. Les mesures de temps d’exécution que nous avons effectuées excluent les
temps d’accès disque qui ne se feront pas lorsque le système opérera en situation
réelle.

Page 46
Pour la phase d’apprentissage, le temps approximatif est de 10 minutes pour
une base de 300 exemples et 8000 itérations. Ce temps ne nous intéresse pas trop car
l’apprentissage du réseau se fait une seule fois en mode off-line.

Par contre, ce qui nous intéresse vraiment, c’est le temps de décision pour de
nouveaux exemples. Pour une base de test de 500 exemples (hindi), le système met
environ 2′45″ pour classifier tous les exemples de cette base. Ce qui donne un temps
de classification (y compris le temps de prétraitement de l’image) d’environ 300 milli-
secondes par caractère.

En ce qui concerne la reconnaissance d’une suite de caractères, il faut compter


un temps supplémentaire pour la séparation des caractères. Nous obtenons un temps
total d’environ 500 milli-secondes par caractère, soit 200 milli-secondes de plus pour
la phase de séparation des caractères de la suite.

Notons que les images représentant les caractères ont été scanées en mode 500
dpi (500 points par inch), et sauvegardées en format BMP avec une taille de 100×100.
En réalité, pour un caractère de taille normale, la taille est de 12 points et une
résolution de 100 dpi suffit.. C’est-à-dire qu’il suffit de stocker le caractère dans une
image BMP 12×12 et le nombre de points non blancs sera nettement inférieure à ce
que nous avons à présent. Ce qui donnera un temps de reconnaissance total de 7 milli-
secondes par caractère. C’est-à-dire que pour une page d’un document contenant
1500 caractères, la reconnaissance de toute la page prendra environ 10 secondes,
auquel il faut ajouter le temps de séparation des lignes et des mots.

5 Conclusion
Nous trouvons que notre système donne de bonnes performances : dans le cas de
chiffres hindi acquis par un scanner, une moyenne de 72% de bonnes décisions sur
une base de test avec une petite base d’apprentissage, et 64% de bonnes décisions
dans le cas de chiffres arabes acquis par un scanner. Nous estimons que c’est une
bonne performance car notre base d’apprentissage est vraiment trop petite par rapport
à ce qu’elle devrait être (de l’ordre de 5000 exemples au lieu de 300).
Malheureusement, nous n’avons pas eu le temps de saisir par scanner suffisamment
d’exemples pour élargir la base d’apprentissage et la base de test. Ceci est causé par la
difficulté et le grand temps nécessaire pour scanner les images contenant plusieurs
chiffres et extraire les chiffres un par un pour les sauver dans des images différentes.
Ce travail se fait actuellement, mais nous ne sommes pas encore en mesure d’énoncer
les résultats pour une grande base d’apprentissage.

Néanmoins, nous pouvons conclure que les réseaux de neurones constituent un


outil puissant permettant de résoudre le problème de classification de caractères
manuscrits. Notre travail ne constitue qu’une petite part d’évaluation de cette
technique qui nous semble préférable aux techniques de pur traitement d’images.

Page 47
Annexe A : Exemples de quelques chiffres acquis par un
scanner

Page 48
Annexe B : Code de programme
// programme réalisé par wassim al falou

#include <stdio.h>

#include <iostream.h>

#include <conio.h>

#include <stdlib.h>

#include <time.h>

#include <math.h>

#include <string.h>

const NN=3000;

const DD=13;

const KK=10;

const HH=11;

const Res=100;

const xdim=500;

const ydim=100;

typedef double matbase[NN][DD+1];

typedef int matimage[Res][Res];

typedef int matim[ydim][xdim];

typedef double matwhd[HH][DD];

typedef double matwkh[KK][HH];

typedef double vectwh0[HH];

typedef double vectwk0[KK];

typedef double vecttest[DD];

typedef double vectattr[DD];

void squellete(matimage,int);

void squ(matimage,int);

void app(int&);

void imreadbmp(matim,int&,int&,int&);

Page 49
void extract(matimage,matim,int,int,int);

void wattr(matimage,vectattr,int);

void wmulc(vectwk0 wk0,matwkh wkh,vectwh0 wh0,matwhd whd,

matbase xx,int Iter,int K,int D,int N);

int wmulcd(vectwk0 wk0,matwkh wkh,vectwh0 wh0,matwhd whd,

matbase xx,vecttest test,int K,int D,int N);

void decider();

void centrage(matimage,matimage,int);

void imread(matimage,int);

void wpretr(matimage,matimage,int);

// fonction d'apprentissage

void wmulc(vectwk0 wk0,matwkh wkh,vectwh0 wh0,matwhd whd,

matbase xx,int Iter,int K,int D,int N)

int n,d,k,h,t=0;

int H;

double rmax= RAND_MAX;

H=int((D+K)/2);

matbase Base;

double xmin[DD];

for (d=0;d<DD;d++)

xmin[d]=0;

double xmax[DD];

for (d=0;d<DD;d++)

xmax[d]=0;

//calcul des min

for (d=0;d<D;d++)

xmin[d]=xx[0][d];

for (n=0;n<N;n++)

Page 50
if (xx[n][d]<xmin[d]) xmin[d]=xx[n][d];

};

//calcul des max

for (d=0;d<D;d++)

xmax[d]=xx[0][d];

for (n=0;n<N;n++)

if (xx[n][d]>xmax[d]) xmax[d]=xx[n][d];

};

//calcul de base normalisée

for (d=0;d<D;d++)

for (n=0;n<N;n++)

Base[n][d]=(xx[n][d]-xmin[d])/(xmax[d]-xmin[d]);

int Target[NN][KK];

for (n=0;n<NN;n++)

for (k=0;k<KK;k++)

Target[n][k]=0;

for (n=0;n<N;n++)

Target[n][(int)xx[n][D]]=1;

//initialistaion des poids

srand( (unsigned)time( NULL ) );

for (k=0;k<K;k++)

wk0[k]=rand()/rmax;

srand( (unsigned)time( NULL ) );

for (k=0;k<K;k++)

for (h=0;h<H;h++)

wkh[k][h]=(rand()/rmax)-0.5;

srand( (unsigned)time( NULL ) );

for (h=0;h<H;h++)

wh0[h]=rand()/rmax;

Page 51
srand( (unsigned)time( NULL ) );

for (h=0;h<H;h++)

for (d=0;d<D;d++)

whd[h][d]=(rand()/rmax)-0.5;

while (t<Iter)

double x[DD];

for (n=0;n<N;n++)

for (d=0;d<D;d++)

x[d]=Base[n][d];

//propagation avant

double s[HH];

for (h=0;h<H;h++) s[h]=0;

for (h=0;h<H;h++)

s[h]=wh0[h];

for (d=0;d<D;d++)

s[h]=s[h]+whd[h][d]*x[d];

s[h]=1/(1+exp(-s[h]));

double y[KK];

for (k=0;k<K;k++) y[k]=0;

for (k=0;k<K;k++)

y[k]=wk0[k];

for (h=0;h<H;h++)

y[k]=y[k]+wkh[k][h]*s[h];

y[k]=1/(1+exp(-y[k]));

Page 52
//retropropagation

for (k=0;k<K;k++)

wk0[k]=wk0[k]+0.1*(Target[n][k]-y[k])*y[k]*(1-y[k]);

for (h=0;h<H;h++)

wkh[k][h]=wkh[k][h]+0.1*(Target[n][k]-y[k])*y[k]*(1-y[k])*s[h];

for (h=0;h<H;h++)

double som=0.;

for (k=0;k<K;k++)

som=som+(Target[n][k]-y[k])*y[k]*(1-y[k])*wkh[k][h];

wh0[h]=wh0[h]+0.1*s[h]*(1-s[h])*som;

for (d=0;d<D;d++)

whd[h][d]=whd[h][d]+0.1*s[h]*(1-s[h])*som*x[d];

}//end for n

t=t+1;

}// end while

int wmulcd(vectwk0 wk0,matwkh wkh,vectwh0 wh0,matwhd whd,

matbase xx,vecttest test,int K,int D,int N)

int n,d,k,h;

int H;

H=int((D+K)/2);

double xmin[DD];

for (d=0;d<DD;d++)

Page 53
xmin[d]=0;

double xmax[DD];

for (d=0;d<DD;d++)

xmax[d]=0;

//calcul des min

for (d=0;d<D;d++)

xmin[d]=xx[0][d];

for (n=0;n<N;n++)

if (xx[n][d]<xmin[d]) xmin[d]=xx[n][d];

};

//calcul des max

for (d=0;d<D;d++)

xmax[d]=xx[0][d];

for (n=0;n<N;n++)

if (xx[n][d]>xmax[d]) xmax[d]=xx[n][d];

};

for (d=0;d<D;d++)

test[d]=(test[d]-xmin[d])/(xmax[d]-xmin[d]);

double s[HH];

for (h=0;h<H;h++) s[h]=0;

for (h=0;h<H;h++)

s[h]=wh0[h];

for (d=0;d<D;d++)

s[h]=s[h]+whd[h][d]*test[d];

s[h]=1/(1+exp(-s[h]));

double y[KK];

Page 54
for (k=0;k<K;k++) y[k]=0;

for (k=0;k<K;k++)

y[k]=wk0[k];

for (h=0;h<H;h++)

y[k]=y[k]+wkh[k][h]*s[h];

y[k]=1/(1+exp(-y[k]));

double ymax=y[0];int kmax=0;

for (k=0;k<K;k++)

if (y[k]>ymax)

ymax=y[k];

kmax=k;

};

return kmax;

void manu(int Iter)

vectwk0 wk0;matwkh wkh;vectwh0 wh0;matwhd whd;

FILE * stream,*st1,*st2,*st3,*st4;

double a[14];int N=0;int d;int k;

int D=13;int K=10;int h;int H=11;

double xx[3000][14];

stream=fopen("c:\\matlab\\bin\\dea\\scfr100","rb");

st1=fopen("c:\\matlab\\bin\\dea\\scfrwk0","w+b");

st2=fopen("c:\\matlab\\bin\\dea\\scfrwkh","w+b");

st3=fopen("c:\\matlab\\bin\\dea\\scfrwh0","w+b");

st4=fopen("c:\\matlab\\bin\\dea\\scfrwhd","w+b");

do

Page 55
{

fread(&a,sizeof(double),14,stream);

for (d=0;d<=13;d++) xx[N][d]= a[d];

N=N+1;

while (!feof(stream));

wmulc(wk0,wkh,wh0,whd,xx,Iter,K,D,N-1);

for (k=0;k<K;k++)

fwrite(&wk0[k],sizeof(double),1,st1);

for (k=0;k<K;k++)

for (h=0;h<H;h++)

fwrite(&wkh[k][h],sizeof(double),1,st2);

for (k=0;k<K;k++)

for (h=0;h<H;h++)

cout<<wkh[k][h]<<" ";

cout<<endl;

for (h=0;h<H;h++)

fwrite(&wh0[h],sizeof(double),1,st3);

for (h=0;h<H;h++)

for (d=0;d<D;d++)

fwrite(&whd[h][d],sizeof(double),1,st4);

fclose(stream);

fclose(st1);

fclose(st2);

fclose(st3);

fclose(st4);

void wpretr(matimage a1,matimage x,int Reso)

Page 56
{

int Jmin=Reso-1,Jmax=0,Imin=Reso-1,Imax=0;

int i,j;

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

a1[i][j]=0;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

if (x[i][j]==1)

if (j<Jmin) Jmin=j;

if (j>Jmax) Jmax=j;

if (i<Imin) Imin=i;

if (i>Imax) Imax=i;

};

int N1=Imax-Imin;

int M1=Jmax-Jmin;

matimage a;

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

a[i][j]=0;

for (i=Imin;i<=Imax;i++)

for (j=Jmin;j<=Jmax;j++)

if (x[i][j]==1) a[i-Imin][j-Jmin]=1;

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

a1[i][j]=a[int((i*N1)/(Res-1))][int((j*M1)/(Res-1))];

matimage b;

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

Page 57
b[i][j]=a1[i][j];

centrage(a1,b,Reso);

};

void centrage(matimage a,matimage x,int Reso)

int i,j;

int Jmin=Reso-1,Jmax=0,Imin=Reso-1,Imax=0;

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

a[i][j]=0;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

if (x[i][j]==1)

if (j<Jmin) Jmin=j;

if (j>Jmax) Jmax=j;

if (i<Imin) Imin=i;

if (i>Imax) Imax=i;

};

int yc,xc,Tx,Ty;

yc=int((Imin+Imax)/2);

xc=int((Jmin+Jmax)/2);

Tx=int((Reso-1)/2-xc);

Ty=int((Reso-1)/2-yc);

int i1=0,j1=0;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

if (x[i][j]==1)

i1=i+Ty;

Page 58
j1=j+Tx;

a[i1][j1]=x[i][j];

};

void wattr(matimage y,vectattr a,int Reso)

double I[100][100];int i,j;

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

I[i][j]=double (y[i][j]);

double IG=0;double JG=0;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

IG=IG+i*I[i][j];

JG=JG+j*I[i][j];

};

// moments centres

double mu00=0,mu11=0,mu02=0,mu20=0,mu12=0,mu21=0,mu22=0,

mu03=0,mu30=0,mu13=0,mu31=0,mu23=0,mu32=0,mu33=0;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

mu00=mu00+I[i][j];

mu11=mu11+(i-IG)*(j-JG)*I[i][j];

mu02=mu02+(pow(j-JG,2))*I[i][j];

mu20=mu20+(pow(i-IG,2))*I[i][j];

mu12=mu12+(i-IG)*(pow(j-JG,2))*I[i][j];

mu21=mu21+(pow(i-IG,2))*(j-JG)*I[i][j];

mu22=mu22+(pow(i-IG,2))*(pow(j-JG,2))*I[i][j];

Page 59
mu03=mu03+(pow(j-JG,3))*I[i][j];

mu30=mu30+(pow(i-IG,3))*I[i][j];

mu13=mu13+(pow(i-IG,1))*(pow(j-JG,3))*I[i][j];

mu31=mu31+(pow(i-IG,3))*(pow(j-JG,1))*I[i][j];

mu23=mu23+(pow(i-IG,2))*(pow(j-JG,3))*I[i][j];

mu32=mu32+(pow(i-IG,3))*(pow(j-JG,2))*I[i][j];

mu33=mu33+(pow(i-IG,3))*(pow(j-JG,3))*I[i][j];

};

double mup11=mu11/pow(mu00,2);

double mup02=mu02/pow(mu00,(1.5));

double mup20=mu20/pow(mu00,(1.5));

double mup12=mu12/pow(mu00,(2.5));

double mup21=mu21/pow(mu00,(2.5));

double mup22=mu22/pow(mu00,(3));

double mup03=mu03/pow(mu00,(2.5));

double mup30=mu30/pow(mu00,(2.5));

double mup13=mu13/pow(mu00,3);

double mup31=mu31/pow(mu00,3);

double mup23=mu23/pow(mu00,(3.5));

double mup32=mu32/pow(mu00,(3.5));

double mup33=mu33/pow(mu00,(4));

a[0]=mup11;a[1]=mup02;a[2]=mup20;a[3]=mup12;a[4]=mup21;

a[5]=mup22;a[6]=mup03;a[7]=mup30;a[8]=mup13;a[9]=mup31;

a[10]=mup23;a[11]=mup32;a[12]=mup33;

void sequence(int &sor)

matim aa,x;int i,j;int Reso=100,xdim,ydim;

imreadbmp(aa,ydim,xdim,sor);

if (sor==0)

Page 60
{

int label=0;

int cond1,cond2;

for (j=0;j<xdim;j++)

for (i=0;i<ydim;i++)

x[i][j]=0;

for (j=0;j<xdim;j++)

cond1=0;

for (i=0;i<ydim;i++)

if (aa[i][j]==1)

cond1=1;

x[i][j]=label;

};

cond2=0;

for (i=0;i<ydim;i++)

if (aa[i][j+1]==1) cond2=1;

if (cond1==0 && cond2==1) label=label+1;

};

vectwk0 wk0;matwkh wkh;vectwh0 wh0;matwhd whd;

FILE * stream,*st1,*st2,*st3,*st4;

double a[14];int N=0;int d;int k;

int D=13;int K=10;int h;int H=11;

double xx[3000][14];

stream=fopen("c:\\matlab\\bin\\dea\\scfr100","rb");

st1=fopen("c:\\matlab\\bin\\dea\\scfrwk0","rb");

st2=fopen("c:\\matlab\\bin\\dea\\scfrwkh","rb");

st3=fopen("c:\\matlab\\bin\\dea\\scfrwh0","rb");

st4=fopen("c:\\matlab\\bin\\dea\\scfrwhd","rb");

Page 61
do

fread(&a,sizeof(double),14,stream);

for (d=0;d<=13;d++) xx[N][d]= a[d];

N=N+1;

while (!feof(stream));

for (k=0;k<K;k++)

fread(&wk0[k],sizeof(double),1,st1);

for (k=0;k<K;k++)

for (h=0;h<H;h++)

fread(&wkh[k][h],sizeof(double),1,st2);

for (h=0;h<H;h++)

fread(&wh0[h],sizeof(double),1,st3);

for (h=0;h<H;h++)

for (d=0;d<D;d++)

fread(&whd[h][d],sizeof(double),1,st4);

fclose(stream);

fclose(st1);

fclose(st2);

fclose(st3);

fclose(st4);

matimage a1,b;vectattr attr;int l;char str[80];

strcpy(str,"");

for (l=1;l<=label;l++)

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

a1[i][j]=0;

Page 62
b[i][j]=0;

};

extract(b,x,xdim,ydim,l);

squ(b,Reso);

wpretr(a1,b,Reso);

squ(a1,Reso);

wattr(a1,attr,Reso);

int kmax=wmulcd(wk0,wkh,wh0,whd,xx,attr,K,D,N-1);

switch(kmax)

case 0:strcat(str,"0");break;

case 1:strcat(str,"1");break;

case 2:strcat(str,"2");break;

case 3:strcat(str,"3");break;

case 4:strcat(str,"4");break;

case 5:strcat(str,"5");break;

case 6:strcat(str,"6");break;

case 7:strcat(str,"7");break;

case 8:strcat(str,"8");break;

case 9:strcat(str,"9");break;

};

};

cout<<str<<endl;

};

void extract(matimage a,matim x,int xdim,int ydim,int label)

int Jmin=xdim-1,Jmax=0,Imin=ydim-1,Imax=0;

int i,j;

for (i=0;i<Res;i++)

Page 63
for (j=0;j<Res;j++)

a[i][j]=0;

for (i=0;i<ydim;i++)

for (j=0;j<xdim;j++)

if (x[i][j]==label)

if (j<Jmin) Jmin=j;

if (j>Jmax) Jmax=j;

if (i<Imin) Imin=i;

if (i>Imax) Imax=i;

};

int N1=Imax-Imin;

int M1=Jmax-Jmin;

for (i=Imin;i<=Imax;i++)

for (j=Jmin;j<=Jmax;j++)

if (x[i][j]==label) a[i-Imin][j-Jmin]=1;

void imreadbmp(matim aa,int &Ydim,int &Xdim,int & sor)

FILE* st;char path[80];char s[80];

sor=0;

strcpy(path,"d:\\imbase\\sim100\\");

cout<<"path= ";cin>>s;

if (strcmp(s,"fin")==0) sor=1;

strcat(path,s);

strcat(path,".bmp");

if (strcmp(s,"fin")!=0)

{st=fopen(path,"rb");

unsigned char a[80];

matim bb;

Page 64
long i,j;

unsigned char b1,b2,b3,b4;

//bitmapfileheader

fread(&a,14,1,st);

//bisize

fread(&a,4,1,st);

//biwidth

fread(&Xdim,4,1,st);

//biheight

fread(&Ydim,4,1,st);

//reste

fread(&a,36,1,st);

for (i=0;i<Ydim;i++)

j=0;

do

fread(&b1,1,1,st);

fread(&b2,1,1,st);

fread(&b3,1,1,st);

fread(&b4,1,1,st);

//b1

if (j<Xdim) {aa[i][j]=!(b1 & 128);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 64);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 32);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 16);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 8);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 4);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 2);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b1 & 1);j=j+1;};

Page 65
//b2

if (j<Xdim) {aa[i][j]=!(b2 & 128);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 64);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 32);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 16);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 8);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 4);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 2);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b2 & 1);j=j+1;};

//b3

if (j<Xdim) {aa[i][j]=!(b3 & 128);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 64);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 32);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 16);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 8);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 4);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 2);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b3 & 1);j=j+1;};

//b4

if (j<Xdim) {aa[i][j]=!(b4 & 128);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 64);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 32);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 16);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 8);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 4);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 2);j=j+1;};

if (j<Xdim) {aa[i][j]=!(b4 & 1);j=j+1;};

while(j<Xdim);

};

Page 66
for (i=0;i<Ydim;i++)

for (j=0;j<Xdim;j++)

bb[i][j]=aa[i][j];

for (i=0;i<Ydim;i++)

for (j=0;j<Xdim;j++)

aa[i][j]=bb[Ydim-i-1][j];

fclose(st);

};

void app(int &sor)

int Reso;

FILE* str;

str=fopen("c:\\matlab\\bin\\dea\\scfr100","ab");

if (str==NULL)

str=fopen("c:\\matlab\\bin\\dea\\scfr100","w+b");

double T;

cout<<"entrer Target=";

cin>>T;

matim x;matimage a1,b;vectattr attr;int i,j;

imreadbmp(x,Reso,Reso,sor);

if (sor==0)

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

b[i][j]=x[i][j];

squ(b,Reso);

wpretr(a1,b,Reso);

squ(a1,Reso);

wattr(a1,attr,Reso);

Page 67
fwrite(&attr,sizeof(double),13,str);

fwrite(&T,sizeof(double),1,str);

fclose(str);

};

void squ(matimage y,int Reso)

int a[Res+2][Res+2];int b[Res+2][Res+2];int x[Res+2][Res+2];

int NN=0,S=0,i,j;Reso=Reso+2;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

x[i][j]=0;

for (i=1;i<(Reso-1);i++)

for (j=1;j<(Reso-1);j++)

x[i][j]=y[i-1][j-1];

int cond=0;

while(cond==0)

//a=x

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

a[i][j]=x[i][j];

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

NN=0;S=0;

if (x[i][j]==1)

if ((i==0)&&(j==0))

NN=x[i][j+1]+x[i+1][j+1]+x[i+1][j];

Page 68
if ((i==0)&&(j==Reso-1))

NN=x[i+1][j]+x[i+1][j-1]+x[i][j-1];

if ((i==Reso-1)&&(j==0))

NN=x[i-1][j]+x[i-1][j+1]+x[i][j+1];

if ((i==Reso-1)&&(j==Reso-1))

NN=x[i-1][j]+x[i][j-1]+x[i-1][j-1];

if ((i==0)&&(j!=Reso-1)&&(j!=0))

NN=x[i][j+1]+x[i+1][j+1]+x[i+1][j]+x[i+1][j-
1]+x[i][j-1];

if ((i==Reso-1)&&(j!=Reso-1)&&(j!=0))

NN=x[i-1][j]+x[i-1][j+1]+x[i][j+1]+x[i][j-1]+x[i-
1][j-1];

if ((j==0)&&(i!=Reso-1)&&(i!=0))

NN=x[i-1][j]+x[i-
1][j+1]+x[i][j+1]+x[i+1][j+1]+x[i+1][j];

if ((j==Reso-1)&&(i!=Reso-1)&&(i!=0))

NN=x[i-1][j]+x[i+1][j]+x[i+1][j-1]+x[i][j-1]+x[i-
1][j-1];

if ((i!=0)&&(i!=Reso-1)&&(j!=0)&&(j!=Reso-1))

NN=x[i-1][j]+x[i-
1][j+1]+x[i][j+1]+x[i+1][j+1]+x[i+1][j]+x[i+1][j-1]+x[i][j-1]+x[i-1][j-1];

if ((i!=0)&&(j!=Reso-1))

if ((x[i-1][j]==0)&&(x[i-1][j+1]==1))

S=S+1;

if ((i!=0)&&(j!=Reso-1))

if ((x[i-1][j+1]==0)&&(x[i][j+1]==1))

S=S+1;

if ((i!=Reso-1)&&(j!=Reso-1))

if ((x[i][j+1]==0)&&(x[i+1][j+1]==1))

Page 69
S=S+1;

if ((i!=Reso-1)&&(j!=Reso-1))

if ((x[i+1][j+1]==0)&&(x[i+1][j]==1))

S=S+1;

if ((i!=Reso-1)&&(j!=0))

if ((x[i+1][j]==0)&&(x[i+1][j-1]==1))

S=S+1;

if ((i!=Reso-1)&&(j!=0))

if ((x[i+1][j-1]==0)&&(x[i][j-1]==1))

S=S+1;

if ((i!=0)&&(j!=0))

if ((x[i][j-1]==0)&&(x[i-1][j-1]==1))

S=S+1;

if ((i!=0)&&(j!=0))

if ((x[i-1][j-1]==0)&&(x[i-1][j]==1))

S=S+1;

}; //end if x[i][j]==1

if ((NN>=2)&&(NN<=6)&&(S==1))

if ((i==0)&&(j!=Reso-
1)&&(j!=0)&&(x[i][j+1]*x[i+1][j]==0)&&(x[i][j+1]*x[i+1][j]*x[i][j-1]==0))

a[i][j]=0;

if ((i==0)&&(j==Reso-
1)&&(x[i+1][j]==0)&&(x[i+1][j]*x[i][j-1]==0))

a[i][j]=0;

if
((i==0)&&(j==0)&&(x[i][j+1]*x[i+1][j]==0)&&(x[i][j+1]*x[i+1][j]==0))

a[i][j]=0;

if ((j==0)&&(i==Reso-1)&&(x[i-
1][j]*x[i][j+1]==0)&&(x[i][j+1]==0))

a[i][j]=0;

Page 70
if ((i==Reso-1)&&(j==Reso-1)&&(x[i-
1][j]==0)&&(x[i][j-1]==0))

a[i][j]=0;

if ((i==Reso-1)&&(j!=Reso-1)&&(j!=0)&&(x[i-
1][j]*x[i][j+1]==0)&&(x[i][j+1]*x[i][j-1]==0))

a[i][j]=0;

if ((j==0)&&(i!=Reso-1)&&(i!=0)&&(x[i-
1][j]*x[i][j+1]*x[i+1][j]==0)&&(x[i][j+1]*x[i+1][j]==0))

a[i][j]=0;

if ((j==Reso-1)&&(i!=Reso-1)&&(i!=0)&&(x[i-
1][j]*x[i+1][j]==0)&&(x[i+1][j]*x[i][j-1]==0))

a[i][j]=0;

if ((i!=0)&&(i!=Reso-1)&&(j!=0)&&(j!=Reso-1)&&(x[i-
1][j]*x[i][j+1]*x[i+1][j]==0)&&(x[i][j+1]*x[i+1][j]*x[i][j-1]==0))

a[i][j]=0;

}; //end if NN

} // end for j

//b=a

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

b[i][j]=a[i][j];

//step 2

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

NN=0;S=0;

if (a[i][j]==1)

if ((i==0)&&(j==0))

NN=a[i][j+1]+a[i+1][j+1]+a[i+1][j];

Page 71
if ((i==0)&&(j==Reso-1))

NN=a[i+1][j]+a[i+1][j-1]+a[i][j-1];

if ((i==Reso-1)&&(j==0))

NN=a[i-1][j]+a[i-1][j+1]+a[i][j+1];

if ((i==Reso-1)&&(j==Reso-1))

NN=a[i-1][j]+a[i][j-1]+a[i-1][j-1];

if ((i==0)&&(j!=Reso-1)&&(j!=0))

NN=a[i][j+1]+a[i+1][j+1]+a[i+1][j]+a[i+1][j-
1]+a[i][j-1];

if ((i==Reso-1)&&(j!=Reso-1)&&(j!=0))

NN=a[i-1][j]+a[i-1][j+1]+a[i][j+1]+a[i][j-1]+a[i-
1][j-1];

if ((j==0)&&(i!=Reso-1)&&(i!=0))

NN=a[i-1][j]+a[i-
1][j+1]+a[i][j+1]+a[i+1][j+1]+a[i+1][j];

if ((j==Reso-1)&&(i!=Reso-1)&&(i!=0))

NN=a[i-1][j]+a[i+1][j]+a[i+1][j-1]+a[i][j-1]+a[i-
1][j-1];

if ((i!=0)&&(i!=Reso-1)&&(j!=0)&&(j!=Reso-1))

NN=a[i-1][j]+a[i-
1][j+1]+a[i][j+1]+a[i+1][j+1]+a[i+1][j]+a[i+1][j-1]+a[i][j-1]+a[i-1][j-1];

if ((i!=0)&&(j!=Reso-1))

if ((a[i-1][j]==0)&&(a[i-1][j+1]==1))

S=S+1;

if ((i!=0)&&(j!=Reso-1))

if ((a[i-1][j+1]==0)&&(a[i][j+1]==1))

S=S+1;

if ((i!=Reso-1)&&(j!=Reso-1))

if ((a[i][j+1]==0)&&(a[i+1][j+1]==1))

S=S+1;

Page 72
if ((i!=Reso-1)&&(j!=Reso-1))

if ((a[i+1][j+1]==0)&&(a[i+1][j]==1))

S=S+1;

if ((i!=Reso-1)&&(j!=0))

if ((a[i+1][j]==0)&&(a[i+1][j-1]==1))

S=S+1;

if ((i!=Reso-1)&&(j!=0))

if ((a[i+1][j-1]==0)&&(a[i][j-1]==1))

S=S+1;

if ((i!=0)&&(j!=0))

if ((a[i][j-1]==0)&&(a[i-1][j-1]==1))

S=S+1;

if ((i!=0)&&(j!=0))

if ((a[i-1][j-1]==0)&&(a[i-1][j]==1))

S=S+1;

}; //end if a[i][j]==1

if ((NN>=2)&&(NN<=6)&&(S==1))

if ((i==0)&&(j!=Reso-1)&&(j!=0)&&(a[i][j+1]*a[i][j-
1]==0)&&(a[i+1][j]*a[i][j-1]==0))

b[i][j]=0;

if ((i==0)&&(j==Reso-1)&&(a[i][j-
1]==0)&&(a[i+1][j]*a[i][j-1]==0))

b[i][j]=0;

if ((i==0)&&(j==0)&&(a[i][j+1]==0)&&(a[i+1][j]==0))

b[i][j]=0;

if ((j==0)&&(i==Reso-1)&&(a[i-1][j]==0)&&(a[i-
1][j]==0))

b[i][j]=0;

if ((i==Reso-1)&&(j==Reso-1)&&(a[i-1][j]*a[i][j-
1]==0)&&(a[i-1][j]*a[i][j-1]==0))

b[i][j]=0;

Page 73
if ((i==Reso-1)&&(j!=Reso-1)&&(j!=0)&&(a[i-
1][j]*a[i][j+1]*a[i][j-1]==0)&&(a[i-1][j]*a[i][j-1]==0))

b[i][j]=0;

if ((j==0)&&(i!=Reso-1)&&(i!=0)&&(a[i-
1][j]*a[i][j+1]==0)&&(a[i-1][j]*a[i+1][j]==0))

b[i][j]=0;

if ((j==Reso-1)&&(i!=Reso-1)&&(i!=0)&&(a[i-
1][j]*a[i][j-1]==0)&&(a[i-1][j]*a[i+1][j]*a[i][j-1]==0))

b[i][j]=0;

if ((i!=0)&&(i!=Reso-1)&&(j!=0)&&(j!=Reso-1)&&(a[i-
1][j]*a[i][j+1]*a[i][j-1]==0)&&(a[i-1][j]*a[i+1][j]*a[i][j-1]==0))

b[i][j]=0;

}; //end if NN

} // end for j

//test d'egalite

cond=1;

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

if (x[i][j]!=b[i][j])

cond=0;

//x=b

for (i=0;i<Reso;i++)

for (j=0;j<Reso;j++)

x[i][j]=b[i][j];

};//end while

for (i=0;i<Reso-2;i++)

for (j=0;j<Reso-2;j++)

y[i][j]=x[i+1][j+1];

};

void atest()

vectwk0 wk0;matwkh wkh;vectwh0 wh0;matwhd whd;

Page 74
FILE * stream,*st1,*st2,*st3,*st4;

double a[14];int N=0;int d;int k;

int D=13;int K=10;int h;int H=11;

double xx[3000][14];

vectattr attr;

int Reso;

stream=fopen("c:\\matlab\\bin\\dea\\scfr100","rb");

st1=fopen("c:\\matlab\\bin\\dea\\scfrwk0","rb");

st2=fopen("c:\\matlab\\bin\\dea\\scfrwkh","rb");

st3=fopen("c:\\matlab\\bin\\dea\\scfrwh0","rb");

st4=fopen("c:\\matlab\\bin\\dea\\scfrwhd","rb");

for (k=0;k<K;k++)

fread(&wk0[k],sizeof(double),1,st1);

for (k=0;k<K;k++)

for (h=0;h<H;h++)

fread(&wkh[k][h],sizeof(double),1,st2);

for (h=0;h<H;h++)

fread(&wh0[h],sizeof(double),1,st3);

for (h=0;h<H;h++)

for (d=0;d<D;d++)

fread(&whd[h][d],sizeof(double),1,st4);

int count=0,kmax,n;

do

fread(&a,sizeof(double),14,stream);

for (d=0;d<=13;d++)

xx[N][d]= a[d];

N=N+1;

Page 75
while (!feof(stream));

for (n=0;n<N;n++)

for (d=0;d<13;d++)

attr[d]=xx[n][d];

kmax=wmulcd(wk0,wkh,wh0,whd,xx,attr,K,D,N-1);

if ((kmax)==(int)xx[n][13]) count=count+1;

fclose(stream);

fclose(st1);

fclose(st2);

fclose(st3);

fclose(st4);

cout<<count<<"/"<<(N-1)<<"="<<((double) count*100/(N-1))<<endl;

void gtest()

vectwk0 wk0;matwkh wkh;vectwh0 wh0;matwhd whd;

FILE * stream,*st1,*st2,*st3,*st4,*strr;

double a[14];int N=0,M=0;int d;int k;

int D=13;int K=10;int h;int H=11;

double xx[3000][14];double y[3000][14];

vectattr attr;

int Reso;

stream=fopen("c:\\matlab\\bin\\dea\\scfr100","rb");

strr=fopen("c:\\matlab\\bin\\dea\\gscfr100","rb");

st1=fopen("c:\\matlab\\bin\\dea\\scfrwk0","rb");

st2=fopen("c:\\matlab\\bin\\dea\\scfrwkh","rb");

st3=fopen("c:\\matlab\\bin\\dea\\scfrwh0","rb");

Page 76
st4=fopen("c:\\matlab\\bin\\dea\\scfrwhd","rb");

for (k=0;k<K;k++)

fread(&wk0[k],sizeof(double),1,st1);

for (k=0;k<K;k++)

for (h=0;h<H;h++)

fread(&wkh[k][h],sizeof(double),1,st2);

for (h=0;h<H;h++)

fread(&wh0[h],sizeof(double),1,st3);

for (h=0;h<H;h++)

for (d=0;d<D;d++)

fread(&whd[h][d],sizeof(double),1,st4);

int count=0,kmax,n;

do

fread(&a,sizeof(double),14,stream);

for (d=0;d<=13;d++)

xx[N][d]= a[d];

N=N+1;

while (!feof(stream));

do

fread(&a,sizeof(double),14,strr);

for (d=0;d<=13;d++)

y[M][d]= a[d];

M=M+1;

while (!feof(strr));

for (n=0;n<M;n++)

Page 77
for (d=0;d<13;d++)

attr[d]=y[n][d];

kmax=wmulcd(wk0,wkh,wh0,whd,xx,attr,K,D,N-1);

if ((kmax)==(int)y[n][13]) count=count+1;

fclose(stream);

fclose(strr);

fclose(st1);

fclose(st2);

fclose(st3);

fclose(st4);

cout<<count<<"/"<<(M-1)<<"="<<((double) count*100/(M-1))<<endl;

void gapp(int &sor)

int Reso;

FILE* str;

str=fopen("c:\\matlab\\bin\\dea\\gscfr100","ab");

if (str==NULL)

str=fopen("c:\\matlab\\bin\\dea\\gscfr100","w+b");

double T;

cout<<"entrer Target=";

cin>>T;

matim x;matimage a1,b;vectattr attr;int i,j;

imreadbmp(x,Reso,Reso,sor);

if (sor==0)

for (i=0;i<Res;i++)

for (j=0;j<Res;j++)

Page 78
b[i][j]=x[i][j];

squ(b,Reso);

wpretr(a1,b,Reso);

squ(a1,Reso);

wattr(a1,attr,Reso);

fwrite(&attr,sizeof(double),13,str);

fwrite(&T,sizeof(double),1,str);

fclose(str);

};

Page 79
Table de matières

Page
- Introduction 1
- Chapitre 1 : Le problème de reconnaissance de l’écriture 3
1 Introduction 3
2 Les applications 3
3 Les différents aspects de l’OCR 4
3.1 Reconnaissance de l’imprimé ou du manuscrit 4
3.2 Reconnaissance monofonte, multifonte ou omnifonte 4
3.3 Reconnaissance de caractères ou analyse de documents 4
3.4 Reconnaissance en ligne ou hors ligne 4
3.5 Système avec ou sans apprentissage 5
4 Saisie de l’écriture 5
4.1 Le mode statique 5
4.2 Le mode continu 5
5 Reconnaissance de caractères 6
5.1 Technique de prétraitement 6
5.1.1 Lissage 6
5.1.2 Normalisation de la taille 6
5.1.3 Amincissement 6
5.2 Technique d’analyse 6
5.2.1 Calcul de corrélation 6
5.2.2 Changement de l’espace de représentation 7
5.2.3 Analyse de la courbure 7
5.3 L’apprentissage 7
5.3.1 L’apprentissage manuel 8
5.3.2 L’apprentissage automatique 8
5.3.3 L’apprentissage continu 8
5.4 Techniques de reconnaissance 8
6 Conclusion 8
- Chapitre 2 : Les réseaux des neurones 9
1 Introduction 9
2 Notion de base 10
2.1 Le neurone biologique 10
2.2 Assemblage de neurones 10
2.3 L’apprentissage 11
2.4 Démarche de modélisation 11
3 Réseaux de neurones artificiels 11
3.1 Introduction 11
3.2 Le neurone formel 12
3.3 Architectures des réseaux de neurones 13
3.4 L’apprentissage 16
4 Apprentissage et généralisation 16
4.1 Position d’un problème de classification par

Page 80
5.2 Architecture du perceptron 18
5.3 Equation de propagation avant 19
5.4 Règle d’apprentissage 19
5.5 L’apprentissage 20
6 Réseaux multicouches 20
6.1 Introduction 20
6.2 Architecture 21
6.3 Equation de propagation avant 21
6.4 Erreur à minimiser 22
6.5 Algorithme 22
7 Conclusion 23
- Chapitre 3 : Reconnaissance de chiffres indiens et arabes :
Travail réalisé 24
1 Introduction 24
2 Représentation des images sur un ordinateur 25
3 Les descripteurs d’image 26
4 Acquisition de l’image 27
5 Prétraitement 27
5.1 Normalisation 28
5.2 Centrage 29
5.3 Amincissement 31
5.4 Extraction des attributs 34
5.5 Prétraitement et obtention de la base d’apprentissage 35
6 Classification 36
6.1 La fonction de simulation d’un réseau multicouche 36
6.2 L’apprentissage 37
7 Algorithme de reconnaissance d’une série de chiffre 37
- Chapitre 4 : Résultats et étude de l’influence des paramètres
sur la performance du système 41
1 Introduction 41
2 Résultats des algorithmes de prétraitement 41
2.1 Résultats de l’algorithme de centrage 41
2.2 Résultats de l’algorithme d’amincissement 41
2.3 Résultats de normalisation 42
2.4 Résultats de l’algorithme final de prétraitement 42
3 Influence de paramètres 43
3.1 Influence du nombre d’exemples dans la base
d’apprentissage 43
3.2 Influence du nombre d’itérations sur la base
d’apprentissage 44
3.3 Influence du nombre d’attributs 45
4 Performances temporelles 45
5 Conclusion 46
- Annexe A : Exemples de quelques chiffres acquis par un scanner 47
- Annexe B : Code de programme 48
- Bibliographie 79

Page 81
Bibliographie
[1] : J. Cao, M. Ahmadi and M. Shridar, A Hierarchical Neural Network Architecture
For Handwritten Numeral Recognition (Pattern Recognition. Vol. 30, 1997 ).
[2] : A. Elnagar, F. Al-Kharousi and S. Harous, Recognition of Handwritten Numerals
using Structural Descriptors (1997 IEEE).
[3] : Young-Sup Hwang, Sung-Yang Bang, Recognition of unconstrained handwritten
numerals by a radial basis function neural network classifier (1997).
[4] : Christian Firmin et Denis Hamad, Introduction aux réseaux de neurones (1997).
[5] : Abdel Belaid et Yolande Belaid, Reconnaissance des formes (InterEditions,
1992).
[6] : J. L. Blue, G. T. Candela, P. J. Grother, R. Chellappa and L. Wilson, Evaluation
Of Pattern Classifiers For Fingerprint And OCR Applications (Pattern Recognition.
Vol. 27, 1994 ).
[7] : François Blayo et Michel Verleysen, Les réseaux de neurones artificiels (Que
Sais – Je, 1996).
[8] : R. Beale and T. Jackson, Neural Computing : An Introduction (Institue of
Physics Publishing).
[9] : Laurence Fausett, Fundamentals Of Neural Networks (Prentice Hall
International, 1994).

Page 82

S-ar putea să vă placă și