48

Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

Rapport de Soutenanceprojet : OsCaR

SAHIR So�ane RAFIDISON Tanjona SUTTER Michaël

MAAREK Nicolas

Mai 2007

1

Page 2: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

Table des matières

1 Introduction 4

2 Première Soutenance 52.1 Interface Graphique : GTK . . . . . . . . . . . . . . . . . . . . . 5

2.1.1 Introduction à GTK . . . . . . . . . . . . . . . . . . . . . 52.1.2 GTK : C ou Caml ? Il faut choisir. . . . . . . . . . . . . . . 62.1.3 Exemple commenté . . . . . . . . . . . . . . . . . . . . . . 7

2.2 Communication entre C et Objective CAML . . . . . . . . . . . 102.2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 102.2.2 Comment ça marche ? . . . . . . . . . . . . . . . . . . . . 10

2.3 Gestion de �chier . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.3.1 Chargement de l'image . . . . . . . . . . . . . . . . . . . . 152.3.2 Sauvergarde de l'image . . . . . . . . . . . . . . . . . . . 16

2.4 Pré-traitement . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.4.1 Transformation en noir et blanc . . . . . . . . . . . . . . . 172.4.2 Elimination du bruit . . . . . . . . . . . . . . . . . . . . . 172.4.3 Rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.5 Site WEB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.5.1 Languages utilisés . . . . . . . . . . . . . . . . . . . . . . 212.5.2 HTML et PHP . . . . . . . . . . . . . . . . . . . . . . . . 212.5.3 Contenu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.5.4 Graphisme . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3 Deuxième Soutenance 233.1 Interface graphique - So�ane . . . . . . . . . . . . . . . . . . . . 233.2 Passage de la Matrice C en Caml - Tanjona . . . . . . . . . . . . 233.3 Segmentation - Michael . . . . . . . . . . . . . . . . . . . . . . . 25

3.3.1 Détection des blocs . . . . . . . . . . . . . . . . . . . . . . 253.3.2 Détection des lignes . . . . . . . . . . . . . . . . . . . . . 273.3.3 Détection des caractères . . . . . . . . . . . . . . . . . . . 28

3.4 Modi�cation de l'image - So�ane . . . . . . . . . . . . . . . . . . 293.4.1 Modi�cation de la matrice . . . . . . . . . . . . . . . . . . 293.4.2 Le format PPM : Portable PixMap . . . . . . . . . . . . . 303.4.3 Manipulation de �chier en Caml . . . . . . . . . . . . . . 31

3.5 Mise en page du texte - Nicolas . . . . . . . . . . . . . . . . . . . 333.6 Site WEB - Michael . . . . . . . . . . . . . . . . . . . . . . . . . 34

4 Troisième Soutenance 354.1 Interface graphique - So�ane . . . . . . . . . . . . . . . . . . . . 35

4.1.1 Mise à jour - Editeur de texte . . . . . . . . . . . . . . . . 354.1.2 Mise à jour - Visualisateur d'image . . . . . . . . . . . . . 374.1.3 Mise à jour - Un correcteur orthographique . . . . . . . . 38

4.2 Les balises en HTML - Nicolas . . . . . . . . . . . . . . . . . . . 404.2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 404.2.2 Traitement par bloc . . . . . . . . . . . . . . . . . . . . . 40

4.3 Extraction des caractères depuis la feuille de référence - Michaël 414.4 Réseau de neurones - Michaël et Tanjona . . . . . . . . . . . . . 42

4.4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 42

EPITA 2 InfoSpé A2

Page 3: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4.4.2 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . 424.4.3 Reconnaissance des caractéres . . . . . . . . . . . . . . . . 424.4.4 Type utilisé . . . . . . . . . . . . . . . . . . . . . . . . . . 424.4.5 L'apprentisssage . . . . . . . . . . . . . . . . . . . . . . . 434.4.6 Problème avec l'apprentissage . . . . . . . . . . . . . . . . 44

4.5 Libération de la mémoire et séparation des �chiers - Michaël etTanjona . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.6 Site WEB - Michaël . . . . . . . . . . . . . . . . . . . . . . . . . 454.6.1 Travail réalisé précedemment . . . . . . . . . . . . . . . . 454.6.2 Graphisme . . . . . . . . . . . . . . . . . . . . . . . . . . 464.6.3 Travail réalisé pour la dernière soutenance . . . . . . . . . 46

5 Conclusion 48

EPITA 3 InfoSpé A2

Page 4: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

1 Introduction

Ce projet a pour but la réalisation d'un O.C.R (programme de reconnais-sance de caractère). Le projet est divisé en trois soutenances distinctes. Le projetest réalisé pour NetBSD. Voici les membres qui compose ce projet :

� RAFIDISON Tanjona (Tanjojo) - Chef de projet� SAHIR So�ane (FienSoP)� SUTTER Michaël (MikMik)� MAAREK Nicolas (Orochimachu1992)

Ce dernier rapport de soutenance a pour but de présenter les di�érentes partiesabordées durant ce projet ainsi que de résumer tout notre travail en y apportantles nouveautés issues du troisième rendu.

Pour ce projet nous avons décidé de nous mettre ensemble car nous avonsdéjà pas mal travaillé ensemble les di�érents projets depuis le debut de l'année.Le groupe de projet est constitué de Tanjona, chef de projet, Michaël, So�ane,et Nicolas. Nous sommes dans la même classe, ce qui nous facilita les réunionsde travail. Nous avons par ailleurs décidé de nommer le projet OSCAR.

EPITA 4 InfoSpé A2

Page 5: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2 Première Soutenance

2.1 Interface Graphique : GTK

2.1.1 Introduction à GTK

D'où vient GTK?

GTK+ (The GIMP Tool Kit) est une librairie permettant de créer des in-terfaces graphiques conçut à l'origine pour le projet GIMP (The GNU ImageManipulation Program) et aujourd'hui étendu à tout type d'application et no-tament celui du projet GNU : GNOME Desktop que l'on connaît tous sous lenom "d'interface graphique" des systèmes Unix en général.

L'avantage de cette librairie est d'une part sa gratuité (di�usée en opensource sous licence LGPL), et d'autre part son utilisation multi langage (C,C++, Perl, Python, Caml etc.) et multi plateforme (Windows, Linux, BSD,Beos, etc.). Pour plus d'informations, le site o�ciel est disponible à l'adresse :http ://www.gtk.org

Notions de bases

La création d'interface graphique sous GTK+ consiste à créer et manipu-ler des objets graphiques de GTK+. Ces objets sont appelés � Widgets �. UnWidget est une structure proposant des fonctions et propriétés permettant lamanipulation de ces objets.

Bien que nous sommes dans un langage procédural, le terme � objet � està prendre au sens littéral car GTK+ introduit la notion d'héritage. Les objetsgraphiques héritent des membres d'un widget de base : GtkWidget.

La gestion des événements est e�ectuée dans une boucle événementielle parl'interception de � signaux �. Un click sur un bouton par exemple, déclencheraun signal intercepté par la boucle événementielle qui exécutera la fonction cor-respondante. On appelle � fonction callback � une fonction associée à un signal.

EPITA 5 InfoSpé A2

Page 6: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2.1.2 GTK : C ou Caml ? Il faut choisir. . .

Le projet OsCaR OCR est un projet dans lequel la manipulation d'imagesoccupe une place très importante. Il est, pour ainsi dire, hors de question derester sous le Terminal pour gérer le programme.

La partie programmation étant imposée pour une grande partie en Caml,nous nous sommes confrontés au choix inévitable du langage avec lequel nousdevions réaliser notre interface graphique. . .

D'une part, l'utilisation d'un langage familier comme le langage C est trèsattractive. Cependant la peur d'avoir un travail trop important à réaliser concer-nant l'interactivité entre les langages C et Caml pour le reste du développementd'OsCar nous a un peu plus in�uencé dans notre choix. . .

Après avoir peser le pour et le contre et étudier les avantages et les inconve-niants que les deux langages pouvaient o�rir, notre choix fût celui conseillé engrande partie par le corps professoral de l'école, à savoir M. Burelle.

La raison qui nous a poussé à choisir le Caml pour GTK est principalementdûe au fait que de façon globale, le projet est codé à 75% en Caml. . .Nous avions ainsi préféré être prévoyant et non fénéant car coder en C nousaurait beaucoup plus facilité la tache : nous n'aurions pas été confrontés au pro-blème du réapprentissage et de l'utilisation d'O-Caml dans un premier temps.

La bibliothèque GTK pour O-Caml est LablGtk. Il en existe deux versions.Celle qui est utilisée pour OsCaR est bien entendu la dernière version.

Caml n'étant pas un langage qui soit utilisé de façon massive par les déve-loppeurs du monde entier, nous avons dû prendre sur nous même pour pouvoirtrouver des exemples concrets sur l'utilisation de GTK en Caml.

Ainsi, le seul tutorial sur lequel nous sommes tombés fût celui nous permet-tant de créer un semblant de Menu et un bouton nous permettant d'écrire surle Terminal. . .

Cependant, ce simple tutorial nous a permis de comprendre l'essentiel dansun premier temps. C'est pour celà que nous avons jugé important de le retrans-crire dans la partie suivante de ce rapport.

EPITA 6 InfoSpé A2

Page 7: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2.1.3 Exemple commenté

Premiers pas...

La documentation se faisant très rare sur LablGTK, et ce notement en cequi concerne les tutoriaux, nous avons dû faire preuve de perséverence dans nosrecherches. . .

En e�et, le plus di�cile n'était pas de s'accoutumer avec la synthaxe d'unlangage pratiquement oublié pour coder une interface graphique mais au contraire,il fallait surtout comprendre comment GTK fonctionne de manière générale.

Pour ce fait, nos premières études ce sont plus axées sur le principe de GTK.Tous les langage de programmtion avec lesquels nous pouvions comprendre unpeu plus nous intéressaient. Le C étant le "porte-parole" o�ciel de GTK, nousavons donc dû nous plonger dans du GTK en C pour mieux approcher le GTKavec Objective CAML.

Notions de Widget

Avant de commencer l'étude de la création d'interface graphique grâce àGtk+, il faut savoir que les objets graphiques de Gtk+ sont appelés des widgets(Window Gadget). Un widget est en fait une structure dé�nissant les propriétésd'un objet associé à une large panoplie de fonctions permettant de manipulerces objets.

Ici, le terme "objet" est à prendre au sens littéral, mais aussi au sens Pro-grammation Orientée Objet (POO). En e�et, bien que GTK+ soit écrit en C, ilintroduit la notion d'héritage et les widgets de Gtk+ suivent une hiérarchie biendé�nie. Ainsi tous les objets graphiques héritent des propriétés et des fonctionsd'un widget de base qui s'appelle GtkWidget.

Ainsi le widget permettant d'a�cher une fenêtre (GtkWindow) a bien sûrses propres fonctions, mais grâce à l'héritage il béné�cie aussi des fonctions desautres widgets dont il dérive.

L'application minimale

Voici la petite application donnée en exemple sur le site des tutoriaux deCaml :

http://www.ocaml-tutorial.org/introduction_to_gtk

Nous avions trouver intéressant de présenter cet exemple du fait de sa simplicitéà comprendre les bases de Gtk en Objective CAML.

A�n de ne pas polluer le bout de code, nous commenterons cette partie etles di�érentes fonctions utilisées.

open GMain

open GdkKeysyms

let main () =

let window = GWindow.window ~width:320 ~height:240

~title:"Ma première application" () in

EPITA 7 InfoSpé A2

Page 8: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

let vbox = GPack.vbox ~packing:window#add () in

window#connect#destroy ~callback:Main.quit;

(* Menu bar *)

let menubar = GMenu.menu_bar ~packing:vbox#pack () in

let factory = new GMenu.factory menubar in

let accel_group = factory#accel_group in

let file_menu = factory#add_submenu "File" in

(* File menu *)

let factory = new GMenu.factory file_menu ~accel_group in

factory#add_item "Quit" ~key:_Q ~callback: Main.quit;

(* Button. *)

let button = GButton.button ~label:"Push me!"

~packing:vbox#add () in

button#connect#clicked ~callback: (fun () -> prerr_endline "Ouch!");

(* Display the windows and enter Gtk+ main loop *)

window#add_accel_group accel_group;

window#show ();

Main.main ()

;;

main ()

-----------------------------------------------------------------------

Analysons ce programme lignes par lignes.

open GMain

open GdkKeysyms

GMain est le module qui fournit beaucoup de fonctions utiles comme lafonction Gtk main loop. GdkKeysyms fournit quant à lui les dé�nitions d'entréesclavier comme par exemple la combinaison Ctrl + Q.

let main () =

let window = GWindow.window ~width:320 ~height:240

~title:"Ma première application" () in

let vbox = GPack.vbox ~packing:window#add () in

window#connect#destroy ~callback:Main.quit;

Tout d'abord, nous devons créer la première fenêtre qui va accueillir tousles composants de l'interface. Tous les programmes Gtk sont basés sur cettepremière fenêtre que l'on appelle "toplevel window". Nous nous devons de re-marquer trois choses :

1. GWindow.window est une fonction déjà toute implémentée qui nous créaitnotre fenêtre.

EPITA 8 InfoSpé A2

Page 9: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2. La bibliothèque Lablgtk utilise de façon intensive les label (ce sont desarguments optionels et nominatifs).

3. Les parenthèses qui semblent être inutiles () (unit) passées à la fonctionGWindow.window. En réalité, elle ne sont pas inutiles, c'est la seul fa-çon d'indiquer à Objective CAML qu'une fonction contient le bon nombred'arguments du fait que certains sont optionels.

Une vbox un Widget non visible dans l'application et permettant d'accueillird'autres Widegets. Le "v" permet de nous indiquer qu'il s'agit d'une "couche"verticale. L'argument packing nous indique que la vbox sera inserée dans lafenêtre initiale créée précédement.

window#connect#destroy ~callback:Main.quit;

est un exemple d'application d'un signal à une fonction. Dans notre cas, il s'agitdu signal destroy qui est émis par notre fenêtre window lorsqu'on essaye de lafermer en cliquant sur la petite croix en hait à droie. Ce signal appele la fonctionMain.quit ().

Après avoir crée notre fenêtre de base, intéressons-nous au Menus. Pour cela,nous créeons un objet GMenu.menu_bar que nous intégrons à notre vbox grâceau label

~packing:vbox#pack :

(* Menu bar *)

let menubar = GMenu.menu_bar ~packing:vbox#pack () in

let factory = new GMenu.factory menubar in

let accel_group = factory#accel_group in

let file_menu = factory#add_submenu "Fichier" in

(* File menu *)

let factory = new GMenu.factory file_menu ~accel_group in

factory#add_item "Quitter" ~key:_Q ~callback: Main.quit;

Notre menu maintenant crée, il serait assez intéressant de faire une applica-tion avec un bouton. . .Comme pour la barre de menu, on intègre le bouton dansla vbox.

On remarque aussi le signal clicked relié par le label callback à une ofnctionanonyme. Ici, la fonction écrit tout simplement la chaine de caractère "Ouch !"sur la sortie standard.

(* Button. *)

let button = GButton.button ~label:"Push me!"

~packing:vbox#add () in

button#connect#clicked ~callback: (fun () -> prerr_endline "Ouch!");

window#add_accel_group accel_group;

Et en�n, pour �nir, les deux appels à des fonctions plus qu'importantes.Chaque Widget Gtk doit être a�ché en appelant la methode show. De toute

EPITA 9 InfoSpé A2

Page 10: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

façon, Lablgtk a�che automatiquement tous les Widgets à l'excéption des to-plevel windows. Par précaution et par besoin, on a besoin d'appeler explici-tement windowshow ().

Main.main () est ce qu'on pourrait appeler la boucle principale de Gtk,celle qui lance et qui intercèpte les évenement.

window#show ();

Main.main ()

2.2 Communication entre C et Objective CAML

2.2.1 Introduction

Comme dit précédement, une partie d'OsCaR est à coder en C, à savoir larotation de l'image, le bruit de l'image ou encore le chargement de l'image etc. . .

Cepandant, l'interface graphique étant faite en Caml et ces di�érentes fonc-tions faites en C vont devoir communiquer entre elles. La question qui restaità se poser était de savoir si c'était les parties en C qui devaient appeler lesfonctions en Caml ou l'inverse. Étant donné le nombre de fonctions en C et lenombre de fonctions en Caml, nous avons opté pour la version : Caml appelantles fonctions C.

Il reste maintenant à savoir comment procéder. . .

2.2.2 Comment ça marche ?

La communication entre parties, d'un même programme, écrites en C et enObjective CAML s'e�ectue en créant un exécutable (ou une nouvelle boucled'interaction) contenant ces deux parties. Celles-ci ont pu être compilées sépa-rément. Ce sera donc à l'édition de liens d'établir le lien entre les noms ObjectiveCAML et les noms C, puis de créer l'exécutable. Pour cela le programme Objec-tive CAML contiendra des déclarations externes assurant cette correspondance.

---------------------------------------------------------------

/* PARTIE C */

---------------------------------------------------------------

value f_c(value x,

value y,

value z)

{

return (Val_long(Long_val(x) + Long_val(y) + Long_val(z)));

}

---------------------------------------------------------------

/* PARTIE OBJECTIVE CAML */

---------------------------------------------------------------

external f : int -> int -> int -> int = "f_c" (* appel *)

let r = f 2 3 4;; (* retour *)

On peut voir chaque partie comme contenant du code et des instructionscorrespondant aux dé�nitions de fonctions et de calcul d'expressions pour Ob-jective CAML. L'appel de la fonction f sur trois entiers d'Objective CAML

EPITA 10 InfoSpé A2

Page 11: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

entraîne le calcul de la fonction f_c de C. Le corps de la fonction convertit lestrois entiers Objective CAML en entiers C, calcule leur somme et retourne lerésultat converti en entier Objective CAML.

Nous présentons ci-dessous les premiers éléments d'interfaçage entre Objec-tive CAML et C : les déclarations externes, les contraintes sur les dé�nitions defonctions C appelables à partir d'Objective CAML ainsi que les options d'éditionde liens. Puis nous donnons un exemple d'utilisation des entrées-sorties.

Déclérations externes

La déclaration externe de fonctions en Objective CAML a pour but d'e�ec-tuer la correspondance entre une déclaration de fonction C et un nom ObjectiveCAML, tout en indiquant le type de celle-ci. La syntaxe est la suivante :

external nom_caml : type = "nom_C"

Cette déclaration indique que l'appel en Objective CAML de la fonctionnom_caml déclenchera l'appel à la fonction C nom_C avec ses arguments.L'exemple précédent déclare ainsi la fonction f dont l'appel correspondra à l'exé-cution de la fonction f_c.

Il est possible de déclarer une fonction externe dans une interface (i.e. dansun �chier .mli), soit en la déclarant explicitement externe, soit comme une va-leur usuelle :

external nom_caml : type = "nom_C"

val nom_caml : type

Dans le second cas, l'appel à la fonction C passe au préalable par le méca-nisme général des fonctions Objective CAML. C'est un peu moins e�cace maiscache la nature de l'implantation de la fonction.

Déclarations des fonctions C

Les fonctions C appelables à partir d'Objective CAML doivent posséder lenombre d'arguments décrit dans la déclaration externe. Ces arguments sont detype value qui est, en C, le type des valeurs d'Objective CAML. Comme celles-ci ont une représentation uniforme, un seul type C permet de coder toutes lesvaleurs Objective CAML.

Le tout premier exemple, donné plus haut, est conforme à ces contraintes.La fonction f_c, liée à la fonction Objective CAML de type int -> int -> int

-> int est bien une fonction à trois paramètres de type value qui retourne unrésultat de type value.

Le mécanisme d'évaluation de l'interprète de code-octet d'Objective CAMLdi�ère selon le nombre d'arguments. Si le nombre d'arguments est inférieur ouégal à cinq, les arguments sont empilés dans la pile d'exécution de la machine. Si

EPITA 11 InfoSpé A2

Page 12: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

le nombre d'arguments est supérieur à cinq, c'est un tableau contenant tous lesarguments qui est empilé ainsi que la taille de ce tableau. Comme les fonctionsC peuvent être appelées à partir de la machine abstraite, il est nécessaire dedistinguer ces deux cas. Par contre l'appel de fonction à partir du compilateurnatif empile bien tous ses arguments. Ceux-ci pourront donc être passés direc-tement à la fonction C.

Même si la norme Epita nous l'interdit, n'oublions pas que le langage C o�rela possibilité de fournir à nos fonctions plus de 5 arguments. Il convient dans cecas d'écrire deux fonctions C : l'une pour le code-octet et l'autre pour le codenatif. La syntaxe des déclarations externes est donc étendue pour permettre uneseule déclaration de fonction Objective CAML pour deux fonctions C :

external nom_caml : type = "nom_C_byte_code" "nom_C_natif "

La fonction nom_C_byte_code prend deux arguments : un tableau de va-leurs de type value (i.e. un pointeur de type *value) et un entier indiquant lataille de ce tableau.

Exemple

Rien de mieux qu'un exemple explicite avec quelques commentaires pourmieux comprendre à quoi nous venons juste de faire allusions dans les para-graphes plus hauts.

Le programme C suivant dé�nit deux fonctions di�érentes pour l'addition desix entiers : plus_native et plus_bytecode qui seront utilisées respectivement parle compilateur natif et le compilateur de code-octet. Il est nécessaire d'inclurele �chier mlvalues.h contenant les dé�nitions des types C des valeurs ObjectiveCAML et les macros de conversion.

#include <stdio.h>

#include <caml/mlvalues.h>

value plus_native(value x1, value x2,

value x3, value x4,

value x5, value x6)

{

printf("<< PLUS NATIF >>\n");

fflush(stdout);

return Val_long (Long_val(x1) + Long_val(x2) + Long_val(x3)

+ Long_val(x4) + Long_val(x5) + Long_val(x6));

}

value plus_bytecode(value *tab_val,

int nb_val)

{

int i;

long res;

EPITA 12 InfoSpé A2

Page 13: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

printf("<< PLUS BYTECODE >> : ");

fflush(stdout);

for (i = 0, res = 0; i < nb_val; i++)

res += Long_val(tab_val[i]);

return (Val_long(res));

}

Le programme O-CAML suivant utilise ces fonctions C.

external plus : int -> int -> int -> int -> int -> int -> int

= "plus_bytecode" "plus_native";;

print_int (plus 1 2 3 4 5 6);;

print_newline ();;

Cependant, pour ne pas à avoir à coder sans cesse deux fonctions en C, nousavons trouvé une remarque assez intéressante.

La façon la plus simple pour ne pas avoir à écrire deux fois une même fonctionest d'utiliser la primitive native dans le code de la primitive pour le code-octetsuivant le schéma :

value prim_nat(value x1, ..., value xn)

{ ... }

value prim_bc(value *tab,

int n)

{

return prim_nat(tab[0], tab[1], ..., tab[n-1]);

}

Entrées/Sorties des deux mondes

Les fonctions C et Objective CAML ne partagent pas leurs bu�ers de �chiers.Intéressons nous à l'exemple suivant pour mieux comprendre de quoi il s'agit.

#include <stdio.h>

#include <caml/mlvalues.h>

value hello_world(value v)

{

printf("Hello World !!");

fflush(stdout);

return (v);

}

On note que les écritures sur la sortie standard doivent être forcées (�ush)si l'on souhaite qu'elles apparaissent dans le bon ordre.

# external caml_hello_world : unit -> unit = "hello_world";;

external caml_hello_world : unit -> unit = "hello_world"

EPITA 13 InfoSpé A2

Page 14: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

# print_string "<< ";

caml_hello_world ();

print_string " >>\n";

flush stdout;;

Hello World !!<< >> - : unit = ()

Cet a�chage n'est pas satisfaisant. Il faut réécrire le programme ObjectiveCAML de la manière suivante :

# print_string "<< ";

flush stdout;

caml_hello_world ();

print_string " >>\n";

flush stdout;;

<< Hello World !! >> - : unit = ()

Le vidage des tampons qui suit systématiquement un ordre d'écriture permetde conserver l'ordre d'a�chage entre les deux mondes.

EPITA 14 InfoSpé A2

Page 15: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2.3 Gestion de �chier

2.3.1 Chargement de l'image

Nous traitons que le format BMP. C'est un format un assez lourd mais il estsimple d'utilisation et on trouve de nombreux site qui explique le contenu des�chiers BMP.le format BMP est constitué de la maniére suivante :

� La signature (sur 2 octets), indiquant qu'il s'agit d'un �chier BMP à l'aidedes deux caractères

� La taille totale du �chier en octets (codée sur 4 octets)� Un champ réservé (sur 4 octets)� L'o�set de l'image (sur 4 octets), en français décalage, c'est-à-dire l'adresserelative du début des informations concernant l'image par rapport au dé-but du �chier

� La taille de l'entête de l'image en octets (codée sur 4 octets). Les valeurshexadécimales suivantes sont possibles suivant le type de format BMP.

� La largeur de l'image (sur 4 octets), c'est-à-dire le nombre de pixels hori-zontalement (en anglais width)

� La hauteur de l'image (sur 4 octets), c'est-à-dire le nombre de pixels ver-ticalement (en anglais height)

� Le nombre de plans (sur 2 octets). Cette valeur vaut toujours 1� La profondeur de codage de la couleur(sur 2 octets), c'est-à-dire le nombrede bits utilisés pour coder la couleur. Cette valeur peut-être égale à 1, 4,8, 16, 24 ou 32

� La méthode de compression (sur 4 octets). Cette valeur vaut 0 lorsquel'image n'est pas compressée, ou bien 1, 2 ou 3 suivant le type de com-pression utilisé

� La taille totale de l'image en octets (sur 4 octets).� La résolution horizontale (sur 4 octets), c'est-à-dire le nombre de pixelspar mètre horizontalement

� La résolution verticale (sur 4 octets), c'est-à-dire le nombre de pixels parmètre verticalement

� Le nombre de couleurs de la palette (sur 4 octets)� Le nombre de couleurs importantes de la palette (sur 4 octets). Ce champpeut être égal à 0 lorsque chaque couleur a son importance.

Pour gérer ces informations on utilise une structure adéquate avec les champsmise à la bonne taille(en octets) a�n que les octets lus correspondent au mieux.Tous les champs de la structure sont en non signés a�n que les valeurs ne soitpas lus comme des valeurs négatifs.La première lecture de l'image consiste à récupérer les informations primordialespour construire la matrice de pixel tel que l'o�set et les dimensions du tableaude pixel. Pour traiter l'image il faut dans un premier temps charger les pixelsde l'image dans une matrice. Un pixel ne comporte que 3 octets d'information,l'intensité rouge, bleu et vert. La lecture des pixels s'e�ectue par ligne à l'aidede fread. Pour le format BMP on doit compléter les lignes de pixels par des zéroa�n que le nombre de pixel par ligne soit modulo 4 ainsi la boucle de lecture ducorps de l'image utilise un fseek du nombre de pixel sauter si la largeur n'estpas modulo 4.

for (i = height - 1; i >= 0; i--)

EPITA 15 InfoSpé A2

Page 16: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

{

fread(tab[i], sizeof (s_pixel), width, file);

if (dec)

fseek(file, dec, SEEK_CUR);

}

Cette méthode nous permet d'économiser de nombreux appel de la fonctionfread ainsi rendre la lecture d'une image plus rapide. Tous les autres formatsd'image peuvent être utiliser car si le format BMP n'est pas détecté on utilise lafonction convert de la librairie Imagemagick à l'aide d'un execvp (utiliser dansun processus cloné auparavant). Cette fonction nous permet de convertir la pluspart des formats d'image vers le format BMP.

2.3.2 Sauvergarde de l'image

A�n de pouvoir présenter l'image suite aux di�érents traitements nous avonsbesoin de sauver l'image. On recopie la même en-tête récupérer lors de la lectureensuite il reste plus qu'a copier le corps de l'image. Pour cela il su�t de procéderde même façon que pour la lecture sauf que si la largeur du tableau de pixeln'est pas modulo 4, on écrit le nombre de zéro nécessaire. L'écriture se fait parligne suivie du complément de zéro si besoin est.La boucle d'écriture :

for (i = header->height; i > 0; i--)

{

fwrite(tab[i - 1], sizeof (s_pixel), (header->width), file);

if (dec)

fwrite(temp, sizeof (char), dec, file);

}

EPITA 16 InfoSpé A2

Page 17: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2.4 Pré-traitement

Dans cette partie, L'image subit plusieurs transformation. La première trans-formation est la saturation des couleurs, de manière à avoir uniquement du noiret du blanc. Le second traitement est l'élimination du bruit, grâce à un �ltre. Cesdeux premiers traitements ont été réalisés par Michaël. Le dernier traitementconcerne la rotation de l'image, en cas de léger décalage lors de la numérisation.La rotation a été attribué à Tanjona.

2.4.1 Transformation en noir et blanc

Avant tous traitement, il faut transformer l'image en noir et blanc. Celasigni�e qu'il n'y aura que du blanc ou du noir sur l'image, ce qui nous permettrade récupérer plus facilement les caractères.Le principe est le suivant :On prend une valeur de seuil, et on sature le résultat en fonction de l'intensité,calculée grâce à la formule suivante :luminosité = 0.299 * rouge + 0.587 * vert + 0.114 * bleuSi la luminosité est supérieur, alors on met chacune des composantes du pixelà 255, sinon on met ces dernières à 0. On parcourt l'image et on applique cetteméthode sur chaque pixel de l'image. La di�culté a été de choisir une valeur deseuil, car sur les images en 75dpi, si le seuil est trop bas, on perd beaucoup tropde données. Les OCR ne sont donc pas optimisés pour les image de 75dpi, et sontplutot utilisé avec des images de 300dpi. J'ai donc choisit comme valeur de seuilla valeur 140, car elle o�rait un bon compromis, et o�rait une fonctionnementoptimal pour les images en 300dpi.

2.4.2 Elimination du bruit

La première chose dont je me suis occupé a été de me renseigner sur le sujet.J'ai d'abord lu des documents parlant du bruit dans les images, des di�érentesméthode utilisés, ainsi que leurs di�érents usages et e�cacités. Après quelquesdocumentation, j'avais trouvé trois méthodes di�érentes pour éliminer le bruit,les �ltres gaussien, médian et séléctif. Ces di�érents �ltres ont pour but d'éli-miner les pixels isolés détériorant l'image.A�n de trouver le �ltre le mieux adapter à notre projet, j'ai implementer cha-cun de ces modèles, et les ai tester. Après di�érents tests, j'ai décidé d'utiliser le�ltre gaussien. En e�et ce type de �ltre me paraissait avoir de meilleurs rendussur les pages testées.

Le �ltre gaussien

La première méthode, consiste à appliquer une matrice de convolution 3 *3, 5 * 5 (ou plus mais impaire) sur chaque pixel de l'image. Ayant choisis cetype de �ltre, j'ai choisis une matrice 3 * 3, qui permet de rendre le �ltre plusperformant. En e�et plus la matrice est grande, plus les pertes d'informationssont importantes. Chaque composante de couleur du pixel est modi�é en fonctiondu �ltre utilisé et des pixels envirronants. Cette méthode se base sur le fait queles pixels d'une image sont en interraction les uns avec les autres. On appliquedonc la matrice sur le pixel, en sommant les produits des composantes coloréesdes pixels voisins avec la valeur de la matrice correspondante. On divise ensuite

EPITA 17 InfoSpé A2

Page 18: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

le résultat par la somme des valeurs de la matrice.Voici la matrice de convolution généralement utilisé pour ce �ltre :

1 2 12 4 21 2 1

La somme des valeurs de la matrice est ici égale à seize, donc on divisera parseize.Le principe de ce modèle est le suivant :On parcours l'image pixel par pixel, en appliquant le masque sur chaque pixelset sur ses voisins. On garde le résultat dans une variable pour chacune des com-posantes du pixel (rouge, vert, bleu). Une fois le masque parcouru, on divise lasomme des resultat obtenue sur chaque pixel voisins par la somme des valeursdu masque, c'est-à-dire seize pour la matrice utilisé. On remplace ensuite lescomposantes du pixel par celles obtenues lors du parcours.

Le �ltre median

Cette méthode consiste à appliquer une matrice de convolution 3 * 3, surchaque pixel de l'image, comme le précédent.A la di�érence qu'on utilise lamatrice suivante :

1 1 11 1 11 1 1

On remplace ensuite la valeur du pixel par la valeur médiane des pixelsvoisins, après application du masque. Le principe de ce modèle est le suivant :On parcours l'image pixel par pixel, en appliquant le masque sur chaque pixelset sur ses voisins. On applique la formule suivante sur chacun des pixels voisins :luminosité = 0.299 * rouge + 0.587 * vert + 0.114 * bleuOn garde les résultats dans un tableau pour chaque pixel. Une fois le masqueparcouru, on classe les valeurs du tableau, et on prend la valeur médiane. Onremplace ensuite les composantes du pixel par celles du pixels correspondant.Le problème est que ce �ltre rend l'image trop �ou, est fait disparaitre le texte.

Le �ltre selectif

Cette méthode consiste à appliquer une matrice de convolution 3 * 3, surchaque pixel de l'image, comme les précédent.A la di�érence que la matrice ap-pliquée est calculée pour chacun des pixels. On remplace ensuite les composantesdu pixel par la somme des composantes des pixels voisins, après application dumasque. Le principe de ce modèle est le suivant :On parcours l'image pixel par pixel, en appliquant le masque sur chaque pixelset sur ses voisins. On calcule la di�érence entre les composantes du pixel courantet de ces voisins. On somme les resultats, et on divise par la somme des valeursdu �ltre calculé.Les coe�cients sont calculés comme suit :

EPITA 18 InfoSpé A2

Page 19: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

h(m,n) =

(1

d(i,j,i+m,j+n)∑1

d(i,j,i+m,j+n)

)

Voici la boucle qui garde les nouvelles composantes du pixel courant :

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

if ((coord[0] - 1 + i >= 0) && (coord[0] - 1 + i < height)

&& (coord[0] - 1 + j >= 0) && (coord[0] - 1 + j < width))

{

res[0] += (src[coord[0] - 1 + i][coord[1] - 1 + j].r) * red[j][i];

res[1] += (src[coord[0] - 1 + i][coord[1] - 1 + j].g) * green[j][i];

res[2] += (src[coord[0] - 1 + i][coord[1] - 1 + j].b) * blue[j][i];

}

En théorie, ce �ltre est le meilleur, puisqu'il est censé conserver au mieux lescontours grâce au �ltre calculé à chaque fois,mais son problème est qu'il n'estpas fait pour les images avec beaucoup de détérioration du au bruit.

EPITA 19 InfoSpé A2

Page 20: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2.4.3 Rotation

Détection de l'angle

Cela represente la partie la plus dure de la rotation. Pour determiner l'anglede rotation, On utilise le procédé de la transformée de Hough. La transforméede Hough est une technique de reconnaissance de formes (inventée en 1962 parPaul Hough) utilisée dans le traitement d'images numériques. Ici, nous utili-serons sont applications la plus simple. Elle permet de reconnaitre les lignesd'une image, mais des modi�cations peuvent être apportées pour reconnaitren'importe quelle forme.Dans la transformée de Hough, dite aussi transforméestandard de Hough ou SHT, chaque ligne est un vecteur de coordonnées para-métriques :

� ρ : lanormeduvecteurθ : l′angle

En transformant toutes lignes possibles qui relient un point à un autre, c'est àdire en calculant la valeur de ρpourchaqueθ, onobtientunesinosodeuniqueappeleespacedeHough.Silescourbesassociesdeuxpointssecoupent, l′endroitoellessecoupentdansl′espacedeHoughcorrespondauxparamtresd′unedroitequireliecesdeuxpoints.ConsidronsunpixelP (x, y)denotrematricedepixel.CepointPappartienttouteslesdroitesdontl′quationest, encoordonnespolaires :ρ = cos(θ)× (x) + sin(θ)× (y)

L'équation dépend du paramètre θ.Ilyadoncuneinfinitdedroitespossibles.SoitQunautrepointslectionn.Grcelui, nousobtenonsuneseconderelationquipermetdenetrouverqu′unseulcouple(ρ, θ)pourlesquelsPetQsontsurladroite.ainsienselectionanttouslespixelsnoireselonunecertainetoleranceapreseffacementdubruit, onutiliseunematriceavecρenordonneetθenabsice.ρvariantde0jusqualadiagonaledelamatriceetθde0jusqu180.Pourtouslespointsselectionnsonincrementechaquecasequiverifielaformuleavecx, ydupointetthetaquivarieentre0et180.Ainsionrecuprel′angledanslacasequicontientlavaleurmaximumcarc′estlacaseauquelcorrespondleplusdintersectiondepoint.

Rotation de l'image

Une fois l'angle obtenu, on applique une matrice de rotation 2D inverse caron cherche le point sur lequelle on se situait avant la rotation, la rotation s'e�ec-tue par rapport au centre de l'image (le pixel de coordonné width/2, height/2).Etant en 2D, la matrice de rotation est simple à appliquer :

� rotinv[0][0] = cos(teta * M_PI / 180);

rotinv[1][1] = cos(teta * M_PI / 180);

rotinv[0][1] = sin(teta *M_PI / 180);

rotinv[0][1] = -sin(teta *M_PI / 180);

x = rotinv[0][0] * (i - width/2) + rotinv[0][1] * (j - (width/2));

y = rotinv[1][0] * (i - width/2)+ rotinv[1][1] * (j - (width/2));

On obtient les anciennes coordonné, il ne reste que de copier le pixel.

new[j][i].r = tab[y1][x1].r;

new[j][i].b = tab[y1][x1].b;

new[j][i].g = tab[y1][x1].g;

avec x1 et y1 sont les valeur de x arrondi à l'inferieur. Tous les points sont copiésdans une nouvelle matrice qui est retourné dans un nouveau tableau de pixel

EPITA 20 InfoSpé A2

Page 21: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

2.5 Site WEB

Pour le bon déroulement d'un projet, un site WEB est nécéssaire. Le projetOSCAR devait donc en avoir un. Michaël s'en est occupé. Il nous fallait unsite WEB sobre qui donnerait une image sérieuse au projet. Pour augmenterla renommée du projet, le site existe en version française ainsi qu'en versionanglaise. L'adresse du site web est la suivante : http ://oscarocr.free.fr/

2.5.1 Languages utilisés

Pour réaliser le site WEB, trois principaux language ont été utilisés, ainsique d'autres moins important pour le graphisme.

2.5.2 HTML et PHP

Pour le contenu du site, des balises HTML et PHP ont été utilisées. Chaquepages du site a donc pour extension *.php et peut uniquement être éxécutée parle serveur. Pour visualiser le site pendant sa réalisation, il faut donc un logicielpermettant de simuler un serveur, comme le logiciel EasyPHP que j'ai utilisé.La plus grande partie du contenu et en HTML, mais certaines fonction PHPutiles ont été crée, comme le compteur de visiteur ou la présentation du siteWEB incluant le menu ou encore la bannière grâce à "include".

<?php

include("header.php");

?>

Le compteur de visite utilise la gestion de cookies. Le principe est le suivant :à chaque connexion, on crée un cookie nommé "counter". Si le cookie n'existepas, cela signi�e que l'on vient juste d'arriver sur le site, on incrémente donc lavariable contenu dans le �chier "count.txt". Ensuite, on a�che la variable à lasuite du message de bienvenue.

<?php

$file = "count.txt";

$fd = fopen($file, "r");

$res = fread($fd, filesize($file));

fclose($fd);

if (!isset($_COOKIE['counter']))

{

$fd = fopen($file, "w");

$res++;

fwrite($fd, $res);

fclose($fd);

setcookie("counter", "ok");

}

?>

CSS, JAVA et FLASH

Pour le graphisme du site, le language CSS à été utilisé. Pour le position-nement des données, les couleurs, les polices et tout autre aspect graphique du

EPITA 21 InfoSpé A2

Page 22: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

site WEB.Les languages JAVA et FLASH ont été utilisés à divers endroit, tel que la ban-nière ou la page de membres.

2.5.3 Contenu

Le menu contient des liens vers les pages de présentation du projet, de télé-chargements, de présentation des membres ou de liens extèrieures. Les pages deprésentation du projet contiennent une introduction, une chronologie, un his-torique, ansi que les problèmes rencontrés et les solutions. Les liens contenusdans la rubrique "liens" du menu renvoient vers les logiciels utilisés, les biblio-thèques nécéssaires, ansi que d'autres liens comme des liens vers des sites quinous ont été utiles pour le projet. Les pages de téléchargements contiennent lesdocuments relatifs au projet, comme les rapports de soutenances, le sujet, ainsique le projet donné à chaque soutenances.

2.5.4 Graphisme

Les teintes des pages sont assez sobres, a�n de donner un coté professionnelau projet. Le blanc, le gris, le bleu et le noir sont les principales couleurs utilisés.Le menu est un tableau d'image, réalisées grâce a photoshop. Le menu est bleuet gris, avec un e�et brossé ainsi qu'un dégradé, pour donner un aspect métaliséau site WEB.La taille du site est en 800 * 600, comme le demande la charte de developpe-ment HTML. Chaque pages possèdent un fond d'écran identique, réalisé avecphotoshop, constitué de caractères entremélés pour être en accord avec l'espritdu projet, la reconnaissance de caractères.La bannière du site WEB à été réalisé en FLASH, et représente le mot OSCARqui se transforme en caractères ASCII. Le logo du site est constitué du motOSCAR, avec les lettres placées de manière pyramidale.La page de présentation des membres contient une fenètre dynamique, réaliséeen JAVA, qui réagit en fonction de la souris. En déplaçant la souris, on se dé-place dans la fenètre, et en cliquant sur les photos des membres, on obtient unedéscription de chacun, inscrit sous les photos.:/Documents and Settings/une case en moins/Mes documents/Mes images/site.JPG

EPITA 22 InfoSpé A2

Page 23: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3 Deuxième Soutenance

3.1 Interface graphique - So�ane

La soutenance précédente nous avions présenté une interface graphique a�-chant une image que l'on pouver Scroller cependant, aucune intéraction entrel'interface graphique et la conversion de l'image initiale n'avait été faite.

Etant donné que nous avions réussi à faire toutes les étapes de pré-traitementde l'image, il ne nous restait plus qu'à mettre en commun ce que nous avions faitd'une part en C et en Caml avec l'interface graphique. Ainsi, pour cette soute-nance, nous avions pour but de n'avoir qu'un seul exécutable pour le lancementdu projet, à savoir l'interface graphique.

Pour cela, nous avons dû indiquer à Caml que nous voulions chercher desfocntions déclarées dans d'autre �chier ml. Nous avons trouver interéssant d'enparler dans le rapport car nous avons eu un peu de mal à linker les �chier entreeux.

La compilation doit se faire comme cela :

$ ocamlc -i mon_module.ml > mon_module.mli

$ ocamlc -c mon_module.mli mon_module.ml main.ml

L'option -i permet de lister les prototypes de chaques fonctions et procé-dures sur la sortie standard et donc, une redirection est nécessaire pour créer le�chier.mli.

La deuxieme commande de compilation doit être exécuter avec les �chiersdans cet ordre bien précis.

3.2 Passage de la Matrice C en Caml - Tanjona

La détection des blocs, lignes, caractères doit être e�ectué sous Caml or toutle projet a été conçu en langage C pour le moment. Maintenant il faut reliertoute la partie Caml avec la partie C ce qui se résume à récupérer la matricede pixel sous Caml. Pour cela on utilise les fonctions pour communiquer avec leCaml.

Les fonctions C qui prennent en paramètres des valeurs caml doivent utiliserune fonction pour identi�er la valeur, les variable et paramètre caml sont detype value.

Dans un premier temps il faut déclarer des variables pour Caml et leurallouer l'espace mémoire nécessaire.

L'avantage des variables Caml est qu'on a pas besoin de les typées elle sontdirectement de type polymorphe. Ainsi je peux mettre tout ce que je veux dedanssans me soucier du type.

Ensuite il faut remplir correctement les champs des variables caml. Il existeplusieurs fonctions pour remplir une variable Caml

Caml_initialize (value var, value valeur); /* équivalent à var = valeur */

Store_field (value var, int champ, value valeur); /* équivalent à var [champ] = valeur */

Et en�n la fonction qui permet de retourner une valeur Caml

EPITA 23 InfoSpé A2

Page 24: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

CAMLreturn(var);

Nous avons besoin d'une fonction qui prend en paramètre le nom de l'image atraité (de type value car cette fonction sera utiliser depuis le Caml). Elle devraitretourner une valeur de type image :

Type = image

{

int dim_x;

int dim_x;

int array array mat;

}

Le problème est que notre matrice est une matrice de pixel et non une matriced'entier. Il est plus simple de convertir une matrice d'entier qu'une matrice quicontient trois valeurs dans chaque case. Donc il a fallu rajouter une fonction quiconverti la matrice de pixel en matrice d'entier. La matrice ne contient que des1 ou 0 ce qui correspond à du noir ou blanc.

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

{

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

{

if ((tab[j][i].r < 160) || (tab[j][i].g < 160) || (tab[j][i].b < 160))

new[j][i] = 0;

else

new[j][i] = 1;

}

}

160 etant le seuil limite pour considérer que le pixel est noir.Maintenant il ne reste plus qu'à convertir chaque case en valeur caml grâce à lafonction

Val_int(int valeur);

Finalement on e�ectue un parcours de la matrice pour tout convertir touten allouant le tableau caml :

res = caml_alloc(mat->size_x, 0);

for (i = 0; i < mat->size_x; i++)

{

aux = caml_alloc(2 * mat->size_y, Double_array_tag) ;

Field(res, i) = aux;

for (j = 0; j < mat->size_y; j++)

Store_field(aux, j, Val_int(mat->mat[j][i]));

}

EPITA 24 InfoSpé A2

Page 25: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3.3 Segmentation - Michael

Dans cette partie, il y a trois détections à faire. La première est la détectiondes blocs de la pages, c'est-à-dire les di�érents paragraphes du texte, le titre, lasignature. . .

La seconde est la détection des lignes, qui revient à repérer les lignes dans lesparagraphes. En�n, la dernière est la détection des caractères, qui est nécéssairepour la suite du projet, puisqu'il faut avoir découpé les caractères pour pouvoirles reconnaître.

Dans chacune des fonctions, la variable m correspond à la matrice de pixels,et les types utilisés sont les suivants :

type lchar =

{

mutable i : int;

mutable j : int;

mutable h : int;

mutable w : int;

}

type line =

{

mutable x : int;

mutable y : int;

mutable height : int;

mutable width : int;

mutable lchar : lchar list;

}

type bloc =

{

mutable bx : int;

mutable by : int;

mutable hgt : int;

mutable wdt : int;

mutable lline : line list;

}

3.3.1 Détection des blocs

Avant tout, il nous faut détecter les di�érents blocs dans le texte (para-graphes, titre...).Pour cela, on utilise deux fonctions (parc_bloc suivi de parc_bloc_v).

La méthode de parc_bloc est la suivante :

On parcourt la matrice de pixels horizontalement, c'est-à-dire de gauche àdroite et de haut en bas (comme lorsqu'on lit un texte). Pendant ce parcours, onfait deux choses, on cherche les coordonnées du bloc et on cherche la premièreligne du bloc, en regardant si on a un pixel noir sur la ligne de pixels parcourue.

EPITA 25 InfoSpé A2

Page 26: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

Si on a un pixel noir, on met à jour les coordonnées du bloc si besoin, et on ditque c'est une ligne, grâce au booléen is_line.

if m.(x).(y) == 0 then

begin

if !bloc.bx > x then !bloc.bx <- x else

if !bloc.hgt < x then !bloc.hgt <- x;

if !bloc.by > y then !bloc.by <- y else

if !bloc.wdt < y then !bloc.wdt <- y;

is_line := true;

end

Ensuite, une fois qu'on arrive à la �n de la ligne de pixels parcourue (quand lavariable de boucle est égale à la largeur de la matrice de pixels), on incrémentela variable line_hgt (correspondant à la hauteur de la ligne) si on a un pixelnoir sur la ligne (le booléen is_line est à vrai), sinon on a une ligne de pixelsblanc et on incrémente la variable space_nb (correspondant au nombre de lignesblanches entre deux lignes). On dit alors que le bloc se termine lorsque la variablespace_nb est supérieure à un certain seuil (car dans un paragraphe, l'espaceentre deux lignes est presque toujours inférieur à la hauteur de chaque lignesdu paragraphe), ou alors lorsqu'on arrive à la �n du texte, c'est-à-dire quand lavariable de boucle est égale à la hauteur de la matrice de pixels. On met alorsle bloc en tête de liste de la liste de blocs. A la �n, quand on a obtenu tous lesblocs du texte (quand on arrive à la �n du parcours, et que la variable de boucleest égale à la hauteur de la matrice de pixels), on inverse la liste de blocs (car onavait ajouté en tête a�n d'éviter d'avoir recours à la concaténation de liste quiest plus coûteuse en temps d'exécution) puis on appel la fonction parc_bloc_vsur la liste de bloc qui permet de séparer deux colonnes de paragraphes dans letexte, dont je parlerai juste après.

(* list : liste de blocs *)

list := List.rev !list;

parc_bloc_v m list;

La méthode de parc_bloc_v est la suivante :On parcourt la matrice de pixels verticalement (en utilisant les coordonnéesdu bloc comme limite de variables de boucle), c'est-à-dire de haut en bas et degauche à droite. Lors de ce parcours, on fait deux choses, on cherche les nouvellescoordonnées du bloc et on cherche la hauteur de la ligne, qui nous servira deseuil pour la séparation des blocs.

(* char_hgt : hauteur de la ligne

h : bloc parcouru *)

let search_line m char_hgt h =

let is_char = ref true in

let x = ref h.bx in

while !is_char && !x <= h.hgt do

is_char := false;

for y = h.by to h.wdt do

if m.(!x).(y) == 0 then

EPITA 26 InfoSpé A2

Page 27: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

is_char := true;

done;

if !is_char then

char_hgt := !char_hgt + 1;

x := !x + 1;

done;

Une fois la hauteur de la ligne obtenue, on recommence le parcours en cherchantla séparation des bloc (c'est-à-dire la première colonne de pixels blanc, car dansun paragraphe, on aura jamais de colonnes de pixels blanc, du fait que les motsne sont jamais de la même taille, et donc pas alignés). Lorsqu'on a trouvé cetteséparation, on regarde si cet espace est supérieur à la hauteur de la premièreligne a�n de ne pas découper les paragraphes contenant une ligne unique (car lesséparations entre les mots seraient comptées à tort comme séparation de bloc). Sil'espace est supérieur, alors on remplace le bloc parcouru par les deux nouveauxblocs trouvés. A la �n du parcours (quand la variable de boucle est égale à lalargeur du bloc), on e�ectue un appel récursif de la fonction parc_bloc_v surle reste de la liste de bloc.

3.3.2 Détection des lignes

Une fois tous les blocs détectés, on s'occupe de rassembler les lignes dechacun des blocs dans une liste, a�n de savoir à quel bloc appartient la ligne dé-tectée. Pour détecter les lignes du texte, on appel donc la fonction parc_line surla liste de blocs obtenue grâce aux fonctions citées précédemment. Voici la mé-thode utilisée pour détecter les lignes de chacun des éléments de la liste de blocs :

On parcourt la matrice de pixels horizontalement (en utilisant les coordon-nées du bloc comme limite de variables de boucle), c'est-à-dire de gauche àdroite et de haut en bas (comme lorsqu'on lit un texte). Dès qu'on trouve unpixel noir, on met à jour les coordonnées de la ligne si besoin, on met le boo-léen is_line à vrai (car on à trouvé une ligne), et on met le booléen pull à vrai(booléen qui sert plus tard lors de l'ajout dans la liste). A la �n du parcours dela ligne de pixels (lorsque la variable de boucle est égale à la largeur du bloc),on ajoute la ligne en tête de liste uniquement si le booléen pull est à vrai, etque l'on est sur une ligne blanche (le booléen is_line est alors à faux) ou qu'onest à la �n du bloc (la variable de boucle est égale à la hauteur du bloc). Unefois le parcours terminé (lorsque la variable de boucle est égale à la hauteur dubloc), on inverse la liste de la même manière que précédemment, on e�ectue ladétection des caractères sur chaque ligne du bloc grâce à la fonction parc_charappelée sur la liste de lignes obtenue, puis on e�ectue un appel récursif de lafonction parc_line sur le reste de la liste de blocs passée en paramètre.

(* t : reste de la liste *)

bloc.lline <- List.rev bloc.lline;

parc_char m bloc.lline;

parc_line m t;

EPITA 27 InfoSpé A2

Page 28: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3.3.3 Détection des caractères

Lorsqu'on a les lignes de chacun des blocs, on détecte les caractères de cha-cune des lignes. Cela est fait grâce à la fonction parc_char, qui prend en para-mètre la matrice de pixels et la liste de lignes d'un bloc. La fonction est en faitappelée lors de la détection des lignes, comme dit précédemment. La méthodeutilisée pour la détection des caractères est la suivante :

On parcour la matrice de pixels verticalement (en utilisant les coordonnéesde la ligne comme limite de variable de boucle), c'est-à-dire de haut en bas etde gauche à droite. Pendant ce parcours, on regarde si on a un pixel noir. Si ona un pixel noir, alors on a un caractère (on met donc ses coordonnées à jour sinécessaire), puis on met les booléen is_char et pull à vrai (booléens qui vontservir lors de l'ajout en tête dans la liste). Une fois le parcours de la colonneterminé (quand la variable de boucle est égale à la hauteur de la ligne), onajoute le caractère en tête de liste seulement si le booléen pull est à vrai, et sion est sur une colonne de pixels blancs (le booléen is_char est à faux) ou quel'on est à la �n de la ligne (quand la variable de boucle est égale à la largeur dela ligne).

line.lchar <- {i = char.i; j = char.j; h = char.h; w = char.w}

:: line.lchar;

A la �n du parcours (quand la variable de boucle est égale à la largeur de laligne), on inverse la liste de caractères comme précédemment, puis on e�ectueun appel récursif de la fonction parc_char sur le reste de la liste de lignes.

EPITA 28 InfoSpé A2

Page 29: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3.4 Modi�cation de l'image - So�ane

Une fois l'image initiale traitée, à savoir l'élimination du bruit, le passage ennoir et blanc et la rotation é�ectuée, il fallait que nous puissions voir en imagele résultat après la segmentation. . .Quoi de mieux que de mettre en évidence lesblocs, les lignes et les caractères sur une nouvelle image.

3.4.1 Modi�cation de la matrice

Pour modi�er la matrice de pixel en vue de la présentation en soutenance(tracer des lignes autour des blocs, lignes et caractères), il fallait faire une fonc-tion qui modi�erait le contenu de la matrice tout autour des éléments (blocs,lignes et caractères). Pour cela, on véri�e que les éléments ne sont pas dansles bords de la matrice (car on ne peut pas tracer toutes les lignes autour del'élément si pour cela on doit sortir des limites de la matrice). Puis on choisitune valeur pour remplacer la couleur du pixel concerné, et ainsi avoir des lignesautour des éléments (car la matrice d'origine ne contient que du noir ou dublanc).

Nous avons décider de faire le contour des blocs en rouge, celui des lignes envert et celui des caractères en bleu.

Etant donné que nous avont maintenant en notre posséssion toutes les co-ordonnées de chaque composante, il ne nous reste plus qu'à faire un vulgaireparcours de liste pour changer la valeur des lignes les entourant dans la matrice.

Grâce à la procédure encompass prenant en argument un type image etune liste de blocs, on va pouvoir contourner les blocs et grâce à des appels ré-cursifs sur les fonctions permettant de faire la même chose sur les lignes et lescaractères alors on encadrera toutes nos composantes.

let rec encompass mat list = match list with

h :: t ->

begin

for j = h.by - 1 to h.wdt + 1 do

mat.mat.(h.bx -1).(j) <- 2;

done;

for i = h.bx - 1 to h.hgt + 1 do

mat.mat.(i).(h.by - 1) <- 2;

done;

for j = h.by - 1 to h.wdt + 1 do

mat.mat.(h.hgt + 1).(j) <- 2;

done;

for i = h.bx - 1 to h.hgt + 1 do

mat.mat.(i).(h.wdt + 1) <- 2;

done;

encom_line mat h.lline;

encompass mat t;

end;

| [] -> ()

EPITA 29 InfoSpé A2

Page 30: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3.4.2 Le format PPM : Portable PixMap

Le Portable PixMap �le format (PPM), le Portable GrayMap �leformatr (PGM) et le Portable BitMap �le format (PBM) sont des formatsde �chier graphique utilisés pour les échanges. Ils proposent des fonctionnalitéstrès basiques et sont utilisé pour convertir les �chiers de type pixmap, graymapet bitmap entre di�érentes plates-formes. Plusieurs applications désignent cetensemble de trois format comme le format PNM (Portable aNyMap).

Ici nous l'avons utilisé a�n de créer rapidement une image visionable à partird'une matrice binaire censée représenter l'image traitée et prète à être analyséepour subir la segmentation.

Avant de rentrer dans les détails, voyons plutôt comment ce format est re-présenté et comment l'utiliser. . .C'est un format très facil à utiliser car il s'utilise de cette façon :

� Un numéro "magique" servant à décrir quel type de PNM on utilise. Icion utilise le PPM et donc notre numéro magique sera "P6"

� Un espacement qui peut être : ' ', 'EOF', 'TAB' en général

� La largeur de l'image exprimé en caractère ASCII en décimal

� Un espacement

� La longueur de l'image exprimé en caractère ASCII en décimal

� Un espacement

� La valeur maximal qu'une couleur peut atteindre, on l'appelle "Maxval".Elle doit être comprise entre 0 et 65536

� Un espacement

� Un tableau de pixel de largeur et de la longueur spéci�ée précédement.Chaque pixel est représenté par un triplet : R G B dont chaque compo-sante ne doit pas excéder le Maxval

� Tout caractère entre un '' en début de ligne et le prochain 'EOF' est consi-déré comme commentaire et sera ignoré à condition qu'il soit placer avantla ligne exprimant le Maxval

EPITA 30 InfoSpé A2

Page 31: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

Exemple

Voilà un bref exemple d'un �chier PPM.

P6

# test.ppm

10 15

15

0 0 0 0 0 0 0 0 0 0

0 0 11 13 15 15 13 11 0 0

0 3 10 10 5 6 2 1 0 0 0

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 11 13 15 15 13 11 0 0

0 0 10 10 5 6 2 1 15 0 0

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 11 13 15 15 13 11 0 0

0 3 10 10 5 6 2 1 0 0 0

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 11 13 15 15 13 11 0 0

0 0 10 10 5 6 2 1 15 0 0

3.4.3 Manipulation de �chier en Caml

On savait déjà tous le faire en C mais la chose intéressante à faire était l'en-registrement de nouvelles données dans un nouveau �chier à partir de la partiecodée en Caml. En e�et, la matrice de pixel censée représenter l'image fût unepremière fois transferée de la partie C en Caml. Il aurait était stupide de lerefaire une fois dans le sens inverse. . .

L'ouverture d'un �chier se fait de deux façons di�érentes selon l'utilisationque nous voulons en faire. Cela corresponderait aux O_WRITE, O_READ ouO_RDWR en C.

Nous voulions simplement écrire dans le �chier sans le lire donc nous avonsutlisé les fonctions open_out et close_out.

L'exemple ci-dessous illustre leurs utilisations et reste dans le contexte de lacréation de notre image PPM :

let oc = open_out "image.ppm"

let init_file oc =

output_string oc "P3\n";

output_string oc "# image.ppm\n";

output_string oc (string_of_int(!matrice.dim_x));

output_string oc " ";

output_string oc (string_of_int(!matrice.dim_y));

output_string oc "\n";

output_string oc "15\n"

[...]

EPITA 31 InfoSpé A2

Page 32: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

let _ =

init_file oc;

close_out oc

La variable oc est un �le descriptor du �chier image.ppm que nous ouvronsen écriture. Ce qui signi�e que si le �chier existe il est ecrasé et si ce n'est pasle cas il sera créé.

D'autre part, l'écriture est tout aussi simple avec la fonction output_stringqui prend en argument un fd et une string.

Il ne faut surout pas oublier de fermer le �chier après avoir terminé.

Ainsi, nous arrivons à créer une image avec la mise en evidence des blocs,des lignes et des caractères.

EPITA 32 InfoSpé A2

Page 33: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3.5 Mise en page du texte - Nicolas

Nous devons garder la mise en page de l'image que l'on traite, c'est à direses sauts de ligne et ses di�érentes marques de présentation. Au préalable letraitement du bruit, la détection de paragraphes, de lignes et de caractères ontété fait et marche.

Pour la mise en page nous allons parcourir chaque bloc ou paragraphe conte-nus dans une liste et véri�er pour chacun d'entre eux les espaces de présentation.Il faudra donc se servir des coordonnées dim_x et dim_y pour comparer l'imagede base et l'image traitée, ceci nous donnera le nombre d'espaces ou le nombrede pixels. Pour les coordonnées en x nous allons calculé le nombre d'espaces dechaque bloc ou paragraphe. Et pour les coordonnées en y nous allons calculé lenombre de sauts de ligne. Donc nous aurons deux fonctions.

EPITA 33 InfoSpé A2

Page 34: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

3.6 Site WEB - Michael

Pour la seconde soutenance, j'ai continué la réalisation du site web, en ra-joutant certaines choses au contenu des pages, comme le téléchargement desdocuments de la seconde soutenance, ou l'ajout de pages non terminées lors dela première soutenance. J'ai aussi ajouté un forum pour permettre au groupede communiquer plus facilement ou encore de mettre sur le forum les problèmesrencontrés lors de la réalisation du projet. Les nouvelles pages ont bien entenduété traduites en anglais, pour rester dans l'idée prise pour la première soute-nance, qui était de faire un site web multilingue français et anglais.

EPITA 34 InfoSpé A2

Page 35: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4 Troisième Soutenance

4.1 Interface graphique - So�ane

Pour la deuxième soutenance, l'interface graphique proposait quelque nou-velles fonctionalités par rapport à celle de la première, à savoir la possibilité delancer le programme de détection des blocs, des lignes et caractères à partir d'unbouton ainsi que le fait de pouvoir ouvrir une image grace un un �le dialogue.

4.1.1 Mise à jour - Editeur de texte

La troixième soutenance a été, elle, beaucoup plus �mise à jour�. Tout d'abord,au niveau de l'éditeur de texte, les changements ont été importants : la possibi-lité de mettre en forme son texte sont maintenant disponible.

On peut voir ces changements comme des innovations minimes mais ellesprennent du temps a mettre en place. Ces commandes de mise en page ont étéimplémenté de la même façon.

� Gras� Italique

� Souligné� Jusiti�cation à gauche� Centré� Justi�cation à droite

Comme dit précedement, l'implémentation est assez rapide lorsqu'on a com-pris comment s'y prendre. . .. Voici un petit exemple :

let create_tags (buffer:GText.buffer) =

buffer#create_tag ~name:"italic" [`STYLE `ITALIC];

buffer#create_tag ~name:"bold" [`WEIGHT `BOLD];

buffer#create_tag ~name:"underline" [`UNDERLINE `SINGLE];

buffer#create_tag ~name:"center" [`JUSTIFICATION `CENTER];

buffer#create_tag ~name:"right_justify" [`JUSTIFICATION `RIGHT];

buffer#create_tag ~name:"left_justify" [`JUSTIFICATION `LEFT];

buffer#create_tag ~name:"wide_margins" [`LEFT_MARGIN 50; `RIGHT_MARGIN 50];

buffer#create_tag ~name:"wrap" [`WRAP_MODE `WORD];

()

let bold_fct (buffer:GText.buffer) =

let start,stop = buffer#selection_bounds in

buffer#apply_tag_by_name "bold" ~start ~stop;

()

La fonction create_tags prend en argument un bu�er de notre éditeur etcréait des �tags�. Ceci consiste à créer un racourci vers un élément de mise enpage.

La fonction bold_fct prend en argument un bu�er de notre éditeur et ap-plique le tag appelé bold à la sélection active dans l'éditeur grâce à la methodselection_bounds.

EPITA 35 InfoSpé A2

Page 36: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

Ainsi il su�t de créer un event lorsqu'on clique sur le boutton appropriépuis appeler une fonction du type de celle de �bold_fct�.

EPITA 36 InfoSpé A2

Page 37: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4.1.2 Mise à jour - Visualisateur d'image

Les deux premières soutenances ont montré plusieurs bouttons ayant di�é-rentes fonctionalitées de Zoom :

� Zoom +� Zoom -� Best Fit� Original Size

Cette partie fût pour moi très délicates car j'y ai passé plusieurs heures àimplémenter les zooms. Du fait que la documentation de LablGtk est très ��ou�,les erreurs de typage m'ont ainsi donc pourri la vie. . .

Cependant après l'implémentation, j'ai rencontré quelques soucis pour lesimages trop grandes : on ne peut pas les zoomer plus d'un certains nombres.J'expliquerais ce problème après avoir commendé mon code.

En réalité, il s'est avéré les zooms s'implémentaient en 4 lignes a peu près :

let zoomin imag =

let imgpix = imag#pixbuf in

let iHeight = GdkPixbuf.get_height imgpix and iWidth = GdkPixbuf.get_width imgpix in

let scaled = GdkPixbuf.create

~width:(iWidth * 4 / 3)

~height:(iHeight * 4 / 3) () in

GdkPixbuf.scale ~dest:scaled

~width:(iWidth * 4 / 3)

~height:(iHeight * 4 / 3) imgpix;

imag#set_pixbuf scaled

La fonction zoomin prend en argument une �image� qui est du typeGMisc.image.Le principe est de récupéré un pixbuf à partir de l'image et d'en récréer unnouveau rédimentioné.

Pour cela je récupère les anciennes hauteur et largeur de l'image grâce àGtkPixbuf.get_height et GtkPixbuf.get_width.

Ensuite on crée un nouveau Pixbuf a l'aide de GtkPixbuf.create pour ensuitele redimentioné grâce à la method scale de GtkPixbuf qui prend en argument lesnouvelles tailles et crée ainsi une nouvelle matrice. Le problème cité plus haut estdû justement à la création de cette nouvelle matrice : si l'image est trop grosseon pourra faire seulement 2 ou 3 zooms car après on fait un out_of_memoryaprès la création de 2 ou 3 matrices. En�n on met à jour l'a�chage avec le imag-set_pixbuf pour a�cher la nouvelle image zoomée dans notre widget image.

Cependant une perte de qualité a été remarqué lorsqu'on fait un dézoomage.La solution a été trouvé en reprenant toujours l'image initial pour faire lesopérations ainsi on ne perd jamais de qualité.

EPITA 37 InfoSpé A2

Page 38: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4.1.3 Mise à jour - Un correcteur orthographique

Qu'est ce qu'un OCR sans correcteur orthographique ?Il y a pluisieurs façon de mettre en place un correcteur orthographique :

� La Class GtkSpell� Les arbres lexicaux

GtkSpell

J'ai utilisé la Class GtkSpell pour mettre en place un correcteur orthogra-phique s'appliquant à quatres langues : Français, Anglais, Allemand et Espagnol.

Le choix de la langue se fait ainsi grace a une Combobox en bas a droitede la fenêtre d'OsCaR OCR. Voilà le code permettant de mettre en place laCombobox ainsi que le correcteur orthographique :

let languages = [ "fr_FR"; "en_US"; "es_ES"; "de_DE" ]

let report_error view msg =

let message =

"<b><big>GtkSpell error:</big></b>\n" ^ (Glib.Markup.escape_text msg) in

let dlg = GWindow.message_dialog

~message

~use_markup:true

~message_type:`ERROR ~buttons:GWindow.Buttons.close

?parent:(GWindow.toplevel view)

~destroy_with_parent:true () in

ignore (dlg#run ()) ;

dlg#destroy ()

let set_lang_cb view lang =

prerr_endline "GtkSpell.set_language" ;

try GtkSpell.set_language view lang ; true

with GtkSpell.Error (_, msg) -> report_error view msg ; false

type button_state =

{

mutable lang_id : int ;

mutable error : bool

}

let build_language_list view packing =

let (combo, _) as c = GEdit.combo_box_text ~strings:languages ~packing () in

let state = { lang_id = -1 ; error = false } in

ignore (combo#connect#changed

(fun () ->

if state.error

then state.error <- false

else

if set_lang_cb view (GEdit.text_combo_get_active c)

then state.lang_id <- combo#active

EPITA 38 InfoSpé A2

Page 39: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

else begin

state.error <- true ;

combo#set_active state.lang_id

end)) ;

c

let attach_cb view lang_list () =

try

if (GtkSpell.is_attached = false) then

GtkSpell.attach ?lang:(GEdit.text_combo_get_active lang_list) view

else

GtkSpell.detach view

with GtkSpell.Error (_, msg) -> report_error view msg

Là, ce qui nous interesse c'est la fonction attach_cb prenant en parmamètreune zone de texte (celle de notre éditeur) et une liste de langages.

On teste tout d'abord si l'éditeur est déjà en mode �correction activée�. Sice n'est pas le cas alors on lance le correcteur avec GtkSpell.attach qui prenden argument une string correspondant au code langage désiré que l'on récupèredepuis la Combobox. Sinon on désactive la �correction� avec GtkSpell.detach.

Les arbres lexicaux

Les arbres lexicaux sont comme leurs noms l'indiquent des arbres avant tout.Un dictionnaire est donc composé d'une fôret de 26 arbres lexicaux. Chaquesnoeuds possèdent 26 �ls correspondant aux lettres de l'alphabet.

Ainsi le principe est de trouver un chemin dans ces arbres. S'il en existe unalors le mot existe dans le dictionnaire. S'il n'y a pas de chemin alors le motn'existe pas.

Bien entendu un arbre lexical possède toutes les combinaisons de lettrespossibles. Pour cela si un noeud est ammené a �nir un mot alors on marque lenoeud pour lui indiquer qu'il s'agit de la �n d'un mot. Ainsi si jamais lors de larecherche du mot dans le dictionnaire le noeud correspondant à la dernière lettredu mot n'est pas marquer comme étant une �n de mot alors le mot n'existe pas.

Il devient aussi facile de rajouter des mots car il su�rait juste de marquerun noeud comme étant la �n du mot.

EPITA 39 InfoSpé A2

Page 40: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4.2 Les balises en HTML - Nicolas

4.2.1 Introduction

Le but de cette partie est de retranscrire le texte traité sous forme de pageHTML. Le langage HTML (HyperText Markup Language) est un langage trèssimple. Pour écrire notre page HTML nous allons utiliser les balises. Il existe 2types de balises : les balises par paires et les balises seules.

Les balises par paires sont les plus courantes : par exemple pour la balise<title> on fait :<title> les balises HTML </title>.

Les balises seules comme image sont de ce type <image/>.Après ces quelques rappels très simples, rentrons dans le vive du sujet.

4.2.2 Traitement par bloc

Les blocs ou paragraphes sont contenus dans une liste : pour chaque blocnous allons utilisé les balises qui nous permettra d'avoir un a�chage correct.La fonction create_bloc_page nous permet de parcourir notre liste de blocs.Pour la coder nous avons utilisé les fonctions imbriquées a�n d'optimiser et defaciliter la lecture du code. On utilise les balises les plus courantes telles que<body> et <head>.

Voici le code de cette fonction :

let create_bloc_page fd fd2 bloclist =

let nb = ref 1 in

let rec exec_create_page fd fd2 = function

[] -> ()

|b::l ->

begin

create_blocform fd fd2 b.bx b.by ("bloc"\^(string\_of\_int(!nb)));

nb := !nb + 1;

exec_create_page fd fd2 l;

end;

in exec_create_page fd fd2 bloclist;

;;

Ensuite nous avons besoin d'une fonction permettant de bien découper letexte dans la page HTLM. Cette fonction va permettre l'utilisation des balisesHTML. Attention à respecter la disposition de chaque balise dans une pageHTML. Avec une fonction permettant de gérer la police des caractères de gardernous pourrions gérer les titres par exemple. Voici en tout cas le code pour labonne gestion des balises :

let create_page bloclist =

let fd = open_out "result.html" in

let fd2 = open_out "result.css" in

output_string fd "<html>\n<head>\n";

output_string fd "<link> rel="stylesheet" media="screen" type="text/css"

href="result.css"/>\n";

create_bloc_page fd fd2 bloclist;

EPITA 40 InfoSpé A2

Page 41: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

output_string fd "</head>\n<body>\n\n";

close_out fd;

close_out fd2;

;;

La bonne gestion des balises est ainsi faite. Chaque balise se trouve ainsi àsa place et l'on retrouve clairement la con�guration d'une page HTML.

4.3 Extraction des caractères depuis la feuille de référence

- Michaël

A�n de pouvoir reconnaître les di�érents caractères grâce au reseau de neu-rones, il nous fallait des caractères de références. Pour cela, nous avons utiliséles di�érentes feuilles données par notre professeur. Ces feuilles sont composéesde cadres contenant les caractères à reconnaître classés pour chacune des policesfournies (Arial, Tahoma, ComicSansMs ...).Comme nous avions besoin d'enlever les cadres autour de chacun des carac-tères, j'ai dû coder des fonctions di�érentes de celles pour la reconnaissance decaractères sur un texte, qui avaient été codées pour la seconde soutenance. Lesfonctions sont très peu di�érentes et les nouvelles fonctions appellent certainesdes anciennes.Les changements sont les suivants :

� Ne pas prendre en compte les traces de marqueurs de la feuille de référence� Insérer les caractères dans la liste sans les cadre autour� Ne pas e�ectuer de parcours verticale des blocs sinon les caractères sontmal insérés dans le vecteur de caractères utilisé dans le réseau de neurones

Une fois les caractères détéctés, on les insère dans un vecteur contenant destypes img a�n de pouvoir les enregistrer dans des �chiers bmp séparés, et ainsiconstituer une bibliothèque de caractères de références.L'extraction des caractères de références se fait en chargeant une image de ré-férence et en appuyant sur le bouton correspondant dans le menu.

EPITA 41 InfoSpé A2

Page 42: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4.4 Réseau de neurones - Michaël et Tanjona

4.4.1 Introduction

L'étape la plus importante dans la réalisation d'un OCR est le réseau deneurones, car en plus d'être la partie la plus compliquer et la plus longue àréaliser, c'est l'étape pilier du programme, car elle permet de reconnaître lescaractères, ce qui est le but premier d'un OCR.

4.4.2 Présentation

Un réseau de neurones est un modèle de calcul s'inspirant des neurones hu-main et animal. Ils sont constitués d'une méthode d'apprentissage, superviséou non, ainsi que de plusieurs couches de neurones, dont on calcule les valeursnettes et de sorties grâce à des fonctions dites de combinaison et de transfert.Les neurones de la couche d'entrée correspondent à l'échantillon que l'on désiretester. Ceux de la couche de sorties correspondent à la valeur obtenu après cal-cul, et ceux des couches intermédiaires, dites cachées, servent aux calculs.Chacun des neurones de chacunes des couches reçoit les valeurs de sortie dechacun des neurones de la couche précédente, associé à un poids synaptiquesque l'on modi�e lors de la rétro-propagation.

4.4.3 Reconnaissance des caractéres

pour reconnaitre un caractere à partir d'une matrice de pixel, on utilise desbatonnets poser aleatoirement sur la matrice du caractére. On de�nit un nombrealéatoire de batonnet dans une con�guration �xé. Ensuite on calcule les intersec-tions avec les pixels noirs de la matrice, On reference tout les batonnet qui ontune intersection avec un pixel. On reference les intersections de chaque carace-teres qui sont dans la feuille de refence. Ce vecteur sera notre vecteur contenantles valeur théorique a retrouvé par le reseaux de neurones. Le nombre de noeudsd'entré sera le nombre de batonnets utilisés pour le reseau de neuronne.

4.4.4 Type utilisé

Pour implementer un reseau de neurones on utilise une classe "network" quicontient plusieurs couchent de classe "layer".

class layer =

object(self)

begin

val err_tab : float array

val in_tab : float array

val nb_neur : int

val net_tab : float array

val neur_tab : float array

val weights_tab : float array array

method g_err_sum : int -> float

method g_err_tab : float array

method g_nb_neur : int

EPITA 42 InfoSpé A2

Page 43: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

method g_net_tab : float array

method g_neur_tab : float array

method g_out : float array

method g_weights_tab : float array array

method s_back_err : float array -> unit

method s_err_out : float array -> unit

method s_in : flat array -> unit

method s_net : unit

method s_out : unit

method s_weights : float array array -> unit

end

La classe "layer" prend en parametres le nombre de neurone qu'il contient,le nombre de neurone de la couche qui le précede, le vecteur qui contiendras lesvaleurs net de chaque neurones de la couche, une matrice contenant les poidssynaptiques entre les neurones de la couche precedente et cette couche et en�nle tableau des valeurs net de la couche precedente. Cette classe nous permet decalculer la propagation entre la couche actuelle et precedente et de mettre a jourles poids de chaque liaisons entre la couche precedente et la couche actuelle. Laretropropagation est calculée à partir de la classe network.

class network : int -> int -> int -> 'a -> object

val mutable layers_tab : layer array

val mutable learn_rate : float

method back_couche : layer -> layer -> unit

method back_prop : unit

method g_delta : layer -> layer -> float array array

method private g_layers : float array -> bool -> unit

method learn : float array -> float array -> bool -> unit

end

4.4.5 L'apprentisssage

Pour vulgariser le principe de l'apprentissage, on parcourt les couches deneurones a�n d'ajuster les coe�cients qui ponderent les liens synaptiques. Toutd'abord on propage vers l'avant avec des poids de�nit aléatoirement. les valeursd'entrées etants de�nit par l'utilisateur. Ansi on de�nit les valeurs de la couchesuivante grâce à la relation suivante :

xni = F (

∑k poidsn

ik ∗ xn−1k )

et F de�nit parF (x) = 1

1+exp (−x)

Le neurone qui est à la Ieme position dans le vecteur de valeur x sur la couche nreçoit le retour de la foncion sigmoidale F. la fonction F prends en argument la

EPITA 43 InfoSpé A2

Page 44: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

somme des poids de k vers i fois la valeur du neurone de la couche precedente n-1 à la Kieme place. On relance cette relation jusqu'à atteindre la derniére couche.

Une fois la couche �nale atteinte on revient sur la couche de départ a�n demettre à jour la valeur d'erreur stocker dans chaque neurone. Les valeurs de lacouche �nale se calcul à part de la façon suivante :

eni = F ′(

∑k poidsn

jk ∗ xn−1k ) ∗ [T (i)− xn

i ]

e etant le vecteur d'erreur de la couche n, F' etant la derivée de F et T levecteur contenant les valeur theorique. Une fois le vecteur d'erreur mis à jouron propage l'erreur vers la couche initiale.

en−1i = F ′(

∑k poidsn−1

ik ∗ xn−1k ) ∗

∑k poidsn

ik ∗ enk

la retro-propagation s'arrete lorsqu'on a atteint la couche de départ. Unefois l'erreur mise a jour on remonte vers la couche �nale a�n de mettre a jourles poids car les poids dépendent de l'erreur. la variation du poids entre deuxiterations sont reliées par la relation suivante :

δpoidsnij = α ∗ en

i ∗ xn−1j

avec α le taux d'apprentissage(de faible magnitude et inférieur à 1.0). Une foisles poids mise à jour on peut recommencé a repropager les valeur des neuronnesvers l'avant. On s'arrete en testant une moyenne d'erreur par rapport a un seuilvoulu :∑nb

k(en

k−T (k))2

nb > seuil

avec nb etant le nombre de neurone de la derniere couche. On fait autant d'ite-ration tant que la di�erence n'atteint pas le seuil.

4.4.6 Problème avec l'apprentissage

Pour tester notre reseau de neurones, on a commencé a simuler une portelogique. On a deux entrés x1 et x2 de valeur binaires. on de�nit la sortie demandé(donner dans le vecteur des valeur theorique). Apres de nombreuse tentatives dedebuggage, la valeur �nal converge toujours vers 1. Ainsi on ne peut rien tester.Les raisons peuvent etre nombreuses : un coe�cient d'apprentisage mal reglé,des embrouilles dans les indices dans les formules ou bien tout simplement uneerreur de formules.

EPITA 44 InfoSpé A2

Page 45: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

4.5 Libération de la mémoire et séparation des �chiers -

Michaël et Tanjona

Pour la dernière soutenance, nous avons décidé de rendre notre code le pluspropre possible, en séparant les �chiers contenant trop de fonctions en plusieurs�chiers dépendant parfois les uns des autres. Nous avons désormais un �chiercontenant les di�érents type utilisés, un autre contenant les fonctions pour ladétéction des blocs, lignes et caractères, un autre contenant les fonctions pourl'extraction des caractères de références, et un dernier permettant d'enregistrerles images dans un �chiers ou encore d'entourer les blocs etc...Quand à la libération de mémoire, elle s'avérait nécéssaire, car sans cela nous nepouvions plus faire fonctionner notre OCR sur les images en 300dpi. De plus lamémoire disponible sur les machines de l'école étant très réstrainte, nous avonsdonc libéré tout ce qui nous était possible, comme la matrice de pixels en C,dont nous ne nous servions plus une fois

le prétraitement é�éctué, ou encore les di�érents vecteurs utilisés dans notreloader d'images.

4.6 Site WEB - Michaël

Pour le bon déroulement d'un projet, un site WEB est nécéssaire. Le projetOSCAR devait donc en avoir un. Michaël s'en est occupé. Il nous fallait unsite WEB sobre qui donnerait une image sérieuse au projet. Pour augmenterla renommée du projet, le site existe en version française ainsi qu'en versionanglaise. L'adresse du site web est la suivante : http ://oscarocr.free.fr/

4.6.1 Travail réalisé précedemment

Languages utilisés

Pour réaliser le site WEB, trois principaux language ont été utilisés, ainsique d'autres moins important pour le graphisme.

HTML et PHP

Pour le contenu du site, des balises HTML et PHP ont été utilisées. Chaquepages du site a donc pour extension *.php et peut uniquement être éxécutée parle serveur. Pour visualiser le site pendant sa réalisation, il faut donc un logicielpermettant de simuler un serveur, comme le logiciel EasyPHP que j'ai utilisé.La plus grande partie du contenu et en HTML, mais certaines fonction PHPutiles ont été crée, comme le compteur de visiteur ou la présentation du siteWEB incluant le menu ou encore la bannière grâce à "include".

Le compteur de visite utilise la gestion de cookies. Le principe est le suivant :à chaque connexion, on crée un cookie nommé "counter". Si le cookie n'existepas, cela signi�e que l'on vient juste d'arriver sur le site, on incrémente donc lavariable contenu dans le �chier "count.txt". Ensuite, on a�che la variable à lasuite du message de bienvenue.

CSS, JAVA et FLASH

Pour le graphisme du site, le language CSS à été utilisé. Pour le position-nement des données, les couleurs, les polices et tout autre aspect graphique du

EPITA 45 InfoSpé A2

Page 46: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

site WEB.Les languages JAVA et FLASH ont été utilisés à divers endroit, tel que la ban-nière ou la page de membres.

Contenu

Le menu contient des liens vers les pages de présentation du projet, de télé-chargements, de présentation des membres ou de liens extèrieures. Les pages deprésentation du projet contiennent une introduction, une chronologie, un his-torique, ansi que les problèmes rencontrés et les solutions. Les liens contenusdans la rubrique "liens" du menu renvoient vers les logiciels utilisés, les biblio-thèques nécéssaires, ansi que d'autres liens comme des liens vers des sites quinous ont été utiles pour le projet. Les pages de téléchargements contiennent lesdocuments relatifs au projet, comme les rapports de soutenances, le sujet, ainsique le projet donné à chaque soutenances.

4.6.2 Graphisme

Les teintes des pages sont assez sobres, a�n de donner un coté professionnelau projet. Le blanc, le gris, le bleu et le noir sont les principales couleurs utilisés.Le menu est un tableau d'image, réalisées grâce a photoshop. Le menu est bleuet gris, avec un e�et brossé ainsi qu'un dégradé, pour donner un aspect métaliséau site WEB.La taille du site est en 800 * 600, comme le demande la charte de developpe-ment HTML. Chaque pages possèdent un fond d'écran identique, réalisé avecphotoshop, constitué de caractères entremélés pour être en accord avec l'espritdu projet, la reconnaissance de caractères.La bannière du site WEB à été réalisé en FLASH, et représente le mot OSCARqui se transforme en caractères ASCII. Le logo du site est constitué du motOSCAR, avec les lettres placées de manière pyramidale.La page de présentation des membres contient une fenètre dynamique, réaliséeen JAVA, qui réagit en fonction de la souris. En déplaçant la souris, on se dé-place dans la fenètre, et en cliquant sur les photos des membres, on obtient unedéscription de chacun, inscrit sous les photos.

Pour la seconde soutenance, j'ai continué la réalisation du site web, en ra-joutant certaines choses au contenu des pages, comme le téléchargement desdocuments de la seconde soutenance, ou l'ajout de pages non terminées lors dela première soutenance. J'ai aussi ajouté un forum pour permettre au groupede communiquer plus facilement ou encore de mettre sur le forum les problèmesrencontrés lors de la réalisation du projet. Les nouvelles pages ont bien entenduété traduites en anglais, pour rester dans l'idée prise pour la première soute-nance, qui était de faire un site web multilingue français et anglais.

4.6.3 Travail réalisé pour la dernière soutenance

Pour la dernière soutenance, j'ai terminé la réalisation du site web, en ra-joutant certaines choses au contenu des pages, comme le téléchargement desdocuments de la dernière soutenance, le téléchargement du projet, ou l'ajout depages non terminées lors des autres soutenances. J'ai terminé la chronologie du

EPITA 46 InfoSpé A2

Page 47: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

projet, en faisant des tableaux récapitulatifs des taches accomplis par les di�é-rents membres, ainsi que les notes obtenus lors des soutenances intermédiaires.Les nouvelles pages ont bien entendu été traduites en anglais, pour rester dansl'idée prise par le groupe, qui était de faire un site web multilingue français etanglais.

EPITA 47 InfoSpé A2

Page 48: Rapport de Soutenance - Freeoscarocr.free.fr/docs/rapport-OSCAR-03.pdfCe dernier rapport de soutenance a pour but de présenter les di érentes parties abordées durant ce projet ainsi

OsCaR Team OsCaR OCR Rapport de Soutenance 3

5 Conclusion

Comme toute bonne chose, nous voici arrivé à la �n de ce projet. Ce fût unprojet très interéssant et très instructifs d'un point vue pédagogique et humain.Même si le rendu ne fût pas celui espéré nous en gardons un très bon souvenir.Ce projet nous a permis de nous faire découvrir un tout autre point de vuede programmation notament celui des réseaux neuronaux. Nous restons tout demême assez déçu du fait que nous n'avions pas pû atteindre nos objectifs maisnous regrettons en rien cette aventure.

EPITA 48 InfoSpé A2