Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Text aus Image extrahieren (https://www.delphipraxis.net/97269-text-aus-image-extrahieren.html)

jokerfacehro 7. Aug 2007 23:54

Re: Text aus Image extrahieren
 
hab schon einiges gefunden, komm so schlecht selber auf suchbegriffe wie "neuronales Netz" :D

ich hab jetz GOCR das sieht ziemlich gut aus und ist freeware.


OffTopic :

ich nutze die DP seit 2004 und muss sagen, mit das beste Delphiforum ;)
auch wenn ich manchma mit den Adminz in einen dicken disput gerate xD

jokerfacehro 8. Aug 2007 15:36

Re: Text aus Image extrahieren
 
so ich habe mich für gocr entschieden.

ich bin dabei es zu instaliieren, doch ist die install anlleitung ziemlich kurz gefasst.

Zitat:

Wie kompilieren?

gzip -cd gocr-0.38.tgz | tar xfv - # auspacken
# evl. Makefile veraendern
cd gocr-0.38 # Ordner wechseln
configure # Makefile anpassen
make # gcc/g++ sollte installiert sein
ich habe alles in nen ordner entpackt und mir auch die makefile datei angeschaut.
ich habe mir gcc-g++-4.2.0-20070501.tar.gz runtergeladen und entpackt
ich habe dann make aufgerufen und er meint Datei nicht gefunden :/

hat jemand ne idee was zu tun ist ?

Klaus01 8. Aug 2007 15:41

Re: Text aus Image extrahieren
 
Kannst Du mal bitte sagen welche Datei nicht gefunden wurde?

Hast Du gcc installiert?
Pfade zu gcc gesetzt?

Grüße
Klaus

inherited 8. Aug 2007 18:25

Re: Text aus Image extrahieren
 
Die Anleitung scheint für Linux gedacht zu sein, für windows gibt es die make.bat
Du musst gcc haben und die Path-Umgebungsvariable muss den pfad zu gcc enthalten.

Mackhack 8. Aug 2007 18:50

Re: Text aus Image extrahieren
 
Bei www.planet-quellcodes.de gabs mal n Wettbewerb um genau das zu machen.

Pr0g hat den gewonnen soweit ich weis. Kannst dich ja mal an ihn wenden!

jokerfacehro 8. Aug 2007 19:53

Re: Text aus Image extrahieren
 
danke für eure antworten, ich werde das ma reinziehen ;)

ich probiere gerade Dcr aus.
das ist freeware in delphi geschrieben und komplett source code dabei.
richtig geil.

der einzige nachteil:

ich muss das programm erst trainieren.
ich hab dem programm gerade 2vorgaben für buchstaben A gegeben und er hat ihn erkannt.

ich werde erstmal ein training für dcr machen und schauen wie hoch die fehlerrate ist.

ich muss sagen geiles programm, besonders da man einfach die units in das eigene programm einfügen kann.

das trainieren ist auch recht einfach nur zeitaufwendig.

ich stelle meine trainingsdatei hier rein, wenn die gute ergebnisse bringt.

jokerfacehro 8. Aug 2007 23:42

Re: Text aus Image extrahieren
 
Liste der Anhänge anzeigen (Anzahl: 2)
hey, ich hab mir gerade nen algorithmus geschrieben um die nervigen punkte heraus zu filtern aus dem image code, damit die freeware den einfacher lesen kann.

der algorithmus is nicht der beste, aber ein guter ansatz ^^

der algorithmus entfernt alleinstehende, schwarze pixel, sodass fast nur der text übrig bleibt.
das genial ist, invertiert man das bild, sodass der hintergrund schwarz und der text weiß ist, füllt er die buchstaben auf, sodass diese besser lesbar werden :D

der algorithmus selber ist verblüffend einfach:

- erst mach ich das bild in schwarz +weiß
- dann durchsuche ich das bild nach schwarzen pixeln, ist einer schwarz suche ich alle umliegenden pixel ab, wenn weniger als 2 pixel um den umliegenden schwarzen pixel schwarz sind, ist es zu mehr als 90% ein
alleinstehender pixel

dann werden die pixel weiß gemacht fertig ^^

hier der algorithmus :
Delphi-Quellcode:
const schwellwert = $00AAAAAA; //der schwellwert um zwischen s/w zu unterscheiden $00BBGGRR

procedure pixelremover;
var i,j,k:integer; //zähler variablen
    count1:integer; //zähler für die im umkreis liegenden schwarzen pixel
    blpix,blindpix:TPoint; //blpix ist der im umkreis liegende schwarze pixel
                           //blindpixel um den pixel als undefiniert zu setzen
    arround_pix:array[0..7] of TPoint;//die acht pixel die einen umgeben
begin
blindpix.X:=-1;
blindpix.Y:=-1;

for i:=0 to Image1.Picture.Width-1 do //bild in 1bit format bringen
 for j:=0 to Image1.Picture.Height-1 do
  if Image1.Canvas.Pixels[i,j]>Integer(schwellwert) then
   Image1.Canvas.Pixels[i,j]:=clWhite
  else
    Image1.Canvas.Pixels[i,j]:=clBlack;


for j:=0 to Image1.Picture.Height-1 do //bild nach schwarzen pixel absuchen
 for i:=0 to Image1.Picture.Width-1 do

  if Image1.Canvas.Pixels[i,j]=clBlack then begin //einer gefunden -> umliegende pixel definieren
   count1:=0;
   arround_pix[0].X:=i-1;//links oben
   arround_pix[0].X:=j-1;

   arround_pix[1].X:=i; //mitte oben
   arround_pix[1].Y:=j-1;

   arround_pix[2].X:=i+1;//rechts oben
   arround_pix[2].Y:=j-1;

   arround_pix[3].X:=i-1;//links mitte
   arround_pix[3].Y:=j;

   arround_pix[4].X:=i+1;//rechts mitte
   arround_pix[4].Y:=j;

   arround_pix[5].X:=i-1;//links unten
   arround_pix[5].Y:=j+1;

   arround_pix[6].X:=i;//mitte unten
   arround_pix[6].Y:=j+1;

   arround_pix[7].X:=i+1;//rechts unten
   arround_pix[7].Y:=j+1;


   if (i<1) then                       //check ob pixel definiert sind, ansonsten ausblenden
    for k:=0 to 3 do
     arround_pix[k]:=blindpix;

   if (j<1) then begin
     arround_pix[0]:=blindpix;
     arround_pix[3]:=blindpix;
     arround_pix[5]:=blindpix;
   end;

   if (i>Image1.Picture.Width) then
    for k:=5 to 7 do
     arround_pix[k]:=blindpix;

   if (j>Image1.Picture.Height) then begin
     arround_pix[2]:=blindpix;
     arround_pix[4]:=blindpix;
     arround_pix[7]:=blindpix;
   end;

  for k:=0 to 7 do                           //umliegende pixel auf farbe testen
                                              //bei schwarz count1+1
   if (arround_pix[k].X>-1)AND(arround_pix[k].Y>-1) then
    if Image1.Canvas.Pixels[arround_pix[k].X,arround_pix[k].Y]<Integer(schwellwert) then begin
     inc(count1);
     blpix:=arround_pix[k];
    end;

  if count1<2 then begin                    
   Image1.Canvas.Pixels[i,j]:=clWhite;         //pixel weiß machen
   Image1.Canvas.Pixels[blpix.X,blpix.Y]:=clWhite; // und den eventuell umliegenden schwarzen pixel auch
  end;

 end;
 Image1.Picture.SaveToFile('bsp.bmp'); //speichern ^^
end;
hier noch ein paar bilder

edit: mit alleinstehenden pixeln meine ich auch pixelgruppen die aus 2 pixeln bestehen

jokerfacehro 9. Aug 2007 01:37

Re: Text aus Image extrahieren
 
Liste der Anhänge anzeigen (Anzahl: 4)
ich hab den algorithmus jetzt weiterentwickelt, ich sitz jetz insgesamt 3 stunden dran und das ergebnis ist unglaublich schaut euch die bilder im anhang an, ihr könnt es nachtesten, indem ihr die originialbilder nehmt, sie durch meinen algorithmus jagt.

dieser algorithmus ist fast genauso einfach:

-natürlich wieder die 1bit umwandlung
-dann werden wieder schwarze pixel gesucht. es dürfen maximal 2 pixel direkt an dem pixel hängen damit es abgecheckt wird, ob es ein alleinstehendes pixelchen ist.bei der früheren version war es 1er.

-jetzt wird der pixel direkt weiß gemacht und die umliegenden schwarzen pixel werden auch nochmal gecheckt wieviel schwarze pixel sich in deren umgebung befinden.

-sind weniger als 4 pixel in der umgebung von den pixeln, werden alle bisherigen pixel weiß gemacht

hier wieder der algorithmus:

edit: änderung am quelltext
es ist total misteriös, die variable blackpix ist total nutzlos im programm, doch kommentiere ich die
zeile blackpix:=blindpix; aus kommt ein schlechteres ergebnis bei raus xD
edit2: hat sich erledit :D
Delphi-Quellcode:

type TArrPix = record        //typ zur rückgabe der schwarzen pixel in der umgebung des einen pixel
                count:integer;
                blackpixels:array[0..7] of TPoint;
             end;

const schwellwert = $00AAAAAA; //schwellwert für s/w erkennung
      //edit: /an diesen beiden konstanten rumspielen um optimale ergebnisse zu erhalten
      anzahl_max_black1 = 2;  //selektierung von pixelgruppen, je höher desto mehr pixel werden durchsucht
      anzahl_max_black2 = 3;      //überprüfung ob zum text zugehörig, je höher desto mehr pixel der
//selektierten pixelgruppen werden weiß gemacht

procedure pixelremover;
var i,j,k,l:integer;           //zählervariablen
    arround_pix:array[0..7] of TPoint;  
    get_pix,get_pix2:TArrPix;  //get_pix variable in der alle schwarzen pixel im umkreis des pixel stehen
                                //get_pix2 darin stehen alle schwarzen pixel im ukreis des pixels,
                                //welches im umkreis des ausgangspixels und schwarz ist
    get_pix_arr:array[0..7] of array[0..7] of TPoint; //darin werden alle umliegenden schwarzen pixel gespeichert
                                                      //der schwarzen pixel die im umkreis des ausgangspixels und schwarz sind
    get_white:boolean;         //boolean um zu checken ob die pixeln weiß gemalt werden sollen
begin

blindpix.X:=-1;
blindpix.Y:=-1;


 for i:=0 to Image1.Picture.Width-1 do          //1 bit konvertierung
 for j:=0 to Image1.Picture.Height-1 do
  if Image1.Canvas.Pixels[i,j]>Integer(schwellwert) then
   Image1.Canvas.Pixels[i,j]:=clWhite
  else
    Image1.Canvas.Pixels[i,j]:=clBlack;

for j:=0 to Image1.Picture.Height-1 do
 for i:=0 to Image1.Picture.Width-1 do


  if Image1.Canvas.Pixels[i,j]=clBlack then begin //check ob pixel schwarz --->
   get_pix:=get_arr_blpixels(i,j,Image1.Picture.Width,Image1.Picture.Height); //alle schwarzen pixel im umkreis des schwarzen pixels erhalten
   get_white:=true;          //standardwert für get_white setzen

   if get_pix.count<=anzahl_max_black1 then begin //check wieviel pixel im umkreis des pixels schwarz sind
   
    for k:=0 to 7 do
     if (get_pix.blackpixels[k].X>-1)AND(get_pix.blackpixels[k].Y>-1) then begin
      get_pix2:=get_arr_blpixels(get_pix.blackpixels[k].X,get_pix.blackpixels[k].Y,Image1.Picture.Width,Image1.Picture.Height);
// // abfragen wieviele und welche schwarze pixel im umkreis der schwarzen pixel des ausgangspixels sind
      for l:=0 to 7 do //alle schwarzen pixel in ein array speichern (insgesamt 64)
       get_pix_arr[k,l]:=get_pix2.blackpixels[l];
      if get_pix2.count>anzahl_max_black2 then begin  //-1 ---3 //check wieviele schwarze bits im umkreis sein müssen damit die pixel als text anerkannt werden
       get_white:=false; //sind es mehr als 3 schwarze pixel im umkreis, dann nix weißmachen
       break;
      end;
    end;
    Image1.Canvas.Pixels[i,j]:=clWhite; //den ausgangspixel weiß machen, ganz wichtig !!!!!
    if get_white then begin //alle restlichen 72 pixel weiß machen
     
     for k:=0 to 7 do begin
      Image1.Canvas.Pixels[get_pix.blackpixels[k].X,get_pix.blackpixels[k].Y]:=clWhite;
      for l:=0 to 7 do
       Image1.Canvas.Pixels[get_pix_arr[k,l].X,get_pix_arr[k,l].Y]:=clWhite;
      end;
   end;
  end;
 end;

 Image1.Picture.SaveToFile('bsp.bmp');
end;

function TForm1.get_arr_blpixels(x,y,width,height:integer):TArrPix; //funktion zum suchen der schwarzen pixel im umkreis
var count,i,j,k:integer;
    arround_pix,black_pix:array[0..7] of TPoint;
    blindpix,blackpix:TPoint;           //zum ausblenden nicht definierter pixel
begin
count:=0;
blindpix.X:=-1;
blindpix.Y:=-1;


 blackpix:=blindpix;


i:=x;
j:=y;

count:=0;
arround_pix[0].X:=i-1;//links oben
arround_pix[0].X:=j-1;

arround_pix[1].X:=i; //mitte oben
arround_pix[1].Y:=j-1;

arround_pix[2].X:=i+1;//rechts oben
arround_pix[2].Y:=j-1;

arround_pix[3].X:=i-1;//links mitte
arround_pix[3].Y:=j;

arround_pix[4].X:=i+1;//rechts mitte
arround_pix[4].Y:=j;

arround_pix[5].X:=i-1;//links unten
arround_pix[5].Y:=j+1;

arround_pix[6].X:=i;//mitte unten
arround_pix[6].Y:=j+1;

arround_pix[7].X:=i+1;//rechts unten
arround_pix[7].Y:=j+1;


   if (i<1) then
    for k:=0 to 3 do
     arround_pix[k]:=blindpix;

   if (j<1) then begin
     arround_pix[0]:=blindpix;
     arround_pix[3]:=blindpix;
     arround_pix[5]:=blindpix;
   end;

   if (i>Image1.Picture.Width) then
    for k:=5 to 7 do
     arround_pix[k]:=blindpix;

   if (j>Image1.Picture.Height) then begin
     arround_pix[2]:=blindpix;
     arround_pix[4]:=blindpix;
     arround_pix[7]:=blindpix;
   end;

  for k:=0 to 7 do
   if (arround_pix[k].X>-1)AND(arround_pix[k].Y>-1) then
    if Image1.Canvas.Pixels[arround_pix[k].X,arround_pix[k].Y]<Integer($00999999) then begin
     inc(count);
     black_pix[k]:=arround_pix[k];
    end;


  Result.count:=count;
  for k:=0 to 7 do
  Result.blackpixels[k]:=black_pix[k];
 end;
und hier wieder bilder

jokerfacehro 9. Aug 2007 01:48

Re: Text aus Image extrahieren
 
Liste der Anhänge anzeigen (Anzahl: 4)
hier kommen weitere bilder :D

edit: wenn ihr diesen algorithmus auch andersum einsetzt, also bild invertieren so dass der hintergrund schwarz und die schrift weiß ist, dann den algorithmus nehmt, verbessert mand amit die schrift, danach das bild wieder invertieren und wieder den anlgorithmus verwenden um die punkte und linien rauszubekommen ^^

edit2: kleine änderung im quelltext

es gibt nur 2 parameter zur steuerung.

1.die anzahl der nötigen umliegenden schwarzen pixel um einen als alleinstehend zu identifizieren.
2. die anzahl der nötigen umliegenden schwarzen pixel um die gesamte pixelgruppe als mitglied zum text zu identifizieren

ich mach die ma als konstanen rein, denn kann man damit besser experimentieren.

die werte die ich verwende bringen mir fast durchgehend optimale ergebnisse ^^

jokerfacehro 9. Aug 2007 03:43

Re: Text aus Image extrahieren
 
Liste der Anhänge anzeigen (Anzahl: 2)
hier ein perfektes ergebnis


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:17 Uhr.
Seite 2 von 4     12 34      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz