ender27
Messages postés7Date d'inscriptionmercredi 5 mars 2008StatutMembreDernière intervention 2 juin 2008
-
15 mars 2008 à 18:31
ender27
Messages postés7Date d'inscriptionmercredi 5 mars 2008StatutMembreDernière intervention 2 juin 2008
-
19 mars 2008 à 21:55
Bonjour à tous,
Je suis un débutant en Delphi (je posséde la version 5).
Je dois réaliser un programme de reconnaissance de caractères pour mon école.
Le problème c'est que je suis coinçé dès le démarrage.
En effet, la reconnaissance de caractères doit s'effectuer sur des images provenant d'une caméra, ce qui signifie que mon programme doit fonctionner pour tout les formats et tailles d'images, mais en plus les images seront en couleurs.
Pour le moment, grâce à tous les codes trouvé sur ce site, j'ai pu réaliser l'ouverture, l'enregistrement, le passage au niveaux de gris et en négatif.
Mon problème se situe au niveau de la binarisation de l'image en niveaux de gris. J'ai utilisé un code trouvé sur votre site, mais j'obtiens une erreur :
"Classe d'exception EInvalidGraphicOperation" et "Indice ligne hors limite"
Il semblerait qu'il y ait un soucis avec le Scanline employé, mais je n'arrive pas à corriger cette erreur.
Voici mon code :
var
Form1: TForm1;
ARect: TRect;
Bmp_Src:TBitmap;
procedure seuil(source:TBitmap;seuil:integer);
implementation
{$R *.DFM}
procedure TForm1.Button4Click(Sender: TObject); //procédure pour la fermeture du programme
begin
Close;
end;
procedure TForm1.Button3Click(Sender: TObject); //enregistrement de l'image
begin
if SavePictureDialog1.Execute then
begin
Image1.Picture.SaveToFile(SavePictureDialog1.FileName);
end;
end;
procedure TForm1.Button1Click(Sender: TObject); //ouverture d'une image
var
ImgExt : string;
Jpeg: TJpegImage;
begin
if OpenPictureDialog1.Execute then
begin
//le traitement se fera d'après l'extension du fichier
ImgExt := LowerCase(ExtractFileExt(OpenPictureDialog1.FileName));
//Pour une image Bitmap
if ImgExt = '.bmp' then
Image1.Picture.Bitmap.LoadFromFile(OpenPictureDialog1.FileName);
//Pour une image Jpeg if (ImgExt '.jpg') or (ImgExt '.jpeg') then
begin
Jpeg := TJpegImage.Create;
try
Jpeg.LoadFromFile(OpenPictureDialog1.FileName);
//copie de l'image du jpeg dans un bitmap
Image1.Picture.Bitmap.Assign(Jpeg);
finally
Jpeg.Free;
end;
end; {if (ImgExt '.JPG') or (ImgExt '.JPEG')}
//Pour une icone
if ImgExt = '.ico' then
Image1.Picture.Icon.LoadFromFile(OpenPictureDialog1.FileName);
//Pour une image wmf et emf
if Pos(ImgExt, GraphicFileMask(TMetaFile)) <> 0 then
Image1.Picture.Metafile.LoadFromFile(OpenPictureDialog1.FileName);
//afficher le nom du fichier dans un espace restreint
Label1.Caption := MinimizeName(OpenPictureDialog1.FileName,
Label1.Canvas,
Label1.Width);
//Récupère la hauteur et la largeur de l'image et les affiche dans deux labels
Label2.Caption:=IntToStr(Image1.Picture.Bitmap.Width)+' pixels';
Label3.Caption:=IntToStr(Image1.Picture.Bitmap.Height)+' pixels';
end;
end;
procedure seuil(source:TBitmap;seuil:integer);
var
rw,i,j,k,l:integer;
p:pbytearray;
begin
source.PixelFormat:=pf32bit;
// calcul la longeur réelle de la ligne en mémoire
rw := source.Width*4;
p:=source.ScanLine[source.Height-1]; ///////le message d'erreur s'affiche ici lors de l'utilisation du debugger
for j:=0 to source.Height-1 do
for i:=0 to source.Width-1 do
begin
k:=i*4+j*rw;
// passage en niveau de gris
l:=(76*p[k+2]+150*p[k+1]+30*p[k+0]) div 256;
//suivant le seuil choisi, c'est noir ou blanc
if l<seuil then l:=0 else l:=255;
// on met à jour le bitmap
p[k+2]:=l;
p[k+1]:=l;
p[k+0]:=l;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Bmp_Src:=TBitmap.Create;
Bmp_Src.Assign(Image1.Picture.Bitmap);
Bmp_Src.PixelFormat:=pf32bit;
end;
procedure TForm1.binbuttonClick(Sender: TObject); //binarisation d'une image
begin
Image1.Picture.Bitmap.Assign(Bmp_Src);
seuil(Image1.Picture.Bitmap,TrackSeuil.Position);
end;
procedure TForm1.TrackSeuilChange(Sender: TObject); //pour la Trackbar
begin
Label4.Caption:='Seuil : '+inttostr(TrackSeuil.Position*100 div 256)+'%';
Image1.Picture.Bitmap.Assign(Bmp_Src);
seuil(Image1.Picture.Bitmap,TrackSeuil.Position);
end;
ender27
Messages postés7Date d'inscriptionmercredi 5 mars 2008StatutMembreDernière intervention 2 juin 2008 19 mars 2008 à 21:55
Bonjour à tous,
J'ai réussi à trouver la solution à mon problème à force de chercher.
En effet le scanline était mal placé, regardez ci dessous où j'aurais du le mettre des le début :
procedure seuil(source:TBitmap;seuil:integer);
var
rw,i,j,k,l:integer;
p:pbytearray;
Bitmap_temp : TBitmap;
begin
// On crée une bitmap temporaire identique à la bitmap couleur courante
// Pour pouvoir jouer sur le contraste et le seuil
Bitmap_temp := TBitmap.Create;
// affecte les proriétés de BitmapCapturee à BitmapTemp
Bitmap_temp.Assign(source);
// On met à jour le format de la bitmap courante
source.PixelFormat:=pf32bit;
// calcul la longeur réelle de la ligne en mémoire
rw := source.Width*4;
for j:=0 to Bitmap_temp.Height-1 do
begin
p:=source.ScanLine[source.Height-1]; //mettre le scanline à l'intérieur de la première boucle for
for i:=0 to Bitmap_temp.Width-1 do
begin
k:=i*4+j*rw;
// passage en niveau de gris
l:=(76*p[k+2]+150*p[k+1]+30*p[k+0]) div 256;
//suivant le seuil choisi, c'est noir ou blanc
if l<seuil then l:=0 else l:=255;
// on met à jour le bitmap
p[k+2]:=l;
p[k+1]:=l;
p[k+0]:=l;
end;
end;
// Destruction de l'image temporaire
Bitmap_Temp.Free;
end;
Mais maintenant j'ai un autre problème, la binarisation ne s'effectue pas, j'obtiens un TBitmap vide???????