tesseract ocr 5.0 Api调用,delphi源码实现--识别率超高速度快
筆者過去使用tesseract-ocr 4.0,一直被識別速度慢和識別率底的問題困擾。最近更新使用了64位的tesseract5.0 dll后識別速度大幅提升,以下是調用DLL的源碼和程序說明,供大家參考。
一:下載tesseract DLL和中文字庫
方式1,到tesseract官網下載dll和字庫,tesseract官網提供源碼和編譯好的DLL,建議直接使用編譯好的DLL,方便省時。以下是64位DLL安裝包下載地址:https://github.com/UB-Mannheim/tesseract/wiki
?要下載64位版本,筆者測試后發現32位識別率沒有64位高。
? ? ? ?中文字庫下載地址:https://github.com/tesseract-ocr/tessdata?下載后的中文簡體字庫chi_sim.traineddata和 chi_sim_vert.traineddata放到安裝包的tessdata文件夾下。
方式2,直接下載筆者提供的完整64位DLL和中文字庫及Delphi調用源碼,地址如下: https://www.gaya-soft.cn/download/
二:調用dll實例
? ? ? ? 此delphi源碼是由國外的開源項目TTesseractOCR4(https://github.com/r1me/TTesseractOCR4)基礎上完善的,原來只支持Tesseract4.0版本,筆者修改了部分源碼使之能適應5.0版本。
? ? ?源碼中tesseractocr.capi.pas單元是定義DLL接口的,是最主要的部分。testMain.pas單元的實現了4個最主要的函數,TessBaseAPICreate是得到一個API接口,TessBaseAPIInit2加載字庫,TessBaseAPISetImage2是加載一個圖像,TessBaseAPIRecognize是文字識別。
?? ?源碼下載地址:??https://www.gaya-soft.cn/download/
? ? 以下是界面設計:
?
?代碼實現如下:
unit testMain;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Imaging.jpeg, DateUtils,tesseractocr.capi, tesseractocr.leptonica;typeTForm1 = class(TForm)Panel1: TPanel;Panel2: TPanel;Memo1: TMemo;Splitter1: TSplitter;ComboBox1: TComboBox;Label1: TLabel;Image1: TImage;Label2: TLabel;edtImage: TEdit;btSelectImg: TButton;btRecognize: TButton;OpenDialog1: TOpenDialog;btInitialize: TButton;procedure btSelectImgClick(Sender: TObject);procedure btRecognizeClick(Sender: TObject);procedure FormCreate(Sender: TObject);procedure FormDestroy(Sender: TObject);procedure btInitializeClick(Sender: TObject);privateFModulePath: string;PApi: TessBaseAPI;FUtf8Text: string;FHOcrText: string;FInitOver: Boolean;function RootPath(): string;function PUTF8CharToString(Char: PUTF8Char; DeleteText: Boolean = True): string;function TessInitialize(DataPath, Language: string; Mode: TessOcrEngineMode = OEM_DEFAULT): Boolean;function SetVariable(Key: string; Value: string): Boolean;function SetImage(FileName: string): PPix; overload;function SetImage(Stream: TMemoryStream): PPix; overload;procedure RecognizeAsText();public{ Public declarations }end;varForm1: TForm1;_CancelRecognize: Boolean;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject); varBuf: array [0 .. MAX_PATH] of Char;S: string; beginSetString(S, Buf, GetModuleFileName(HInstance, Buf, SizeOf(Buf)));FModulePath := ExtractFilePath(S);if (hTesseractLib = 0) thenraise Exception.Create('Tesseract library is not loaded');//_CancelRecognize := False;// 得到一個API接口PApi := TessBaseAPICreate();FInitOver := False; end;procedure TForm1.FormDestroy(Sender: TObject); beginif Assigned(PApi) then beginTessBaseAPIEnd(PApi);TessBaseAPIDelete(PApi);end; end;function TForm1.RootPath(): string; varI: Integer; beginResult := FModulePath;for I := Length(Result) - 1 downto 1 do beginif Result[I] = '\' then beginResult := Copy(Result, 1, I);Break;end;end; end;procedure TForm1.btSelectImgClick(Sender: TObject); beginOpenDialog1.InitialDir := RootPath() + 'example\';OpenDialog1.Filter := 'Image File|*.JPG;*.PNG;*.GIF;*.BMP;*.JPEG;';if OpenDialog1.Execute() then beginedtImage.Text := OpenDialog1.FileName;Image1.Picture.LoadFromFile(edtImage.Text);end; end;function TForm1.PUTF8CharToString(Char: PUTF8Char; DeleteText: Boolean = True): string; varUtfStr: UTF8String;X: Integer; beginResult := '';if Assigned(Char) then beginX := Length(Char);SetString(UtfStr, Char, X);if DeleteText and (X > 0) thenTessDeleteText(Char);Result := string(UtfStr);end; end;// 初始化識別字庫 function TForm1.TessInitialize(DataPath, Language: string; Mode: TessOcrEngineMode = OEM_DEFAULT): Boolean; beginSetCurrentDirectory(PChar(FModulePath));//if Assigned(PApi) thenResult := TessBaseAPIInit2(PApi, PUTF8Char(UTF8Encode(DataPath)), PUTF8Char(UTF8Encode(Language)), Mode) = 0elseResult := False; end;function CancelCallback(cancel_this: Pointer; words: Integer): Boolean; cdecl; beginResult := _CancelRecognize; end;function ProgressCallback(Progress: Integer; Left, Right, Top, Bottom: Integer): Boolean; cdecl; beginResult := False; end;// 設置識別參數 function TForm1.SetVariable(Key: string; Value: string): Boolean; beginResult := TessBaseAPISetVariable(PApi, PUTF8Char(UTF8Encode(Key)), PUTF8Char(UTF8Encode(Value))); end;// 識別圖片中的文字 procedure TForm1.RecognizeAsText(); varFMonitor: ETEXT_DESC; beginFillChar(FMonitor, SizeOf(FMonitor), #0);FMonitor.cancel := @CancelCallback;FMonitor.progress_callback := @ProgressCallback;FUtf8Text := '';FHOcrText := '';//if TessBaseAPIRecognize(PApi, FMonitor) <> 0 thenExit;// 識別文字FUtf8Text := PUTF8CharToString(TessBaseAPIGetUTF8Text(PApi));FUtf8Text := StringReplace(FUtf8Text, #10, #13#10, [rfReplaceAll]);// 識別結果和位置信息FHOcrText := PUTF8CharToString(TessBaseAPIGetHOCRText(PApi, 0));FHOcrText := StringReplace(FHOcrText, #10, #13#10, [rfReplaceAll]); end;// 加載要識別的圖片文件 function TForm1.SetImage(FileName: string): PPix; beginResult := pixRead(PUTF8Char(UTF8Encode(FileName)));if Assigned(Result) thenTessBaseAPISetImage2(PApi, Result)elseResult := nil; end;// 加載要識別的內存 function TForm1.SetImage(Stream: TMemoryStream): PPix; beginStream.Position := 0;Result := pixReadMem(Stream.Memory, Stream.Size);if Assigned(Result) thenTessBaseAPISetImage2(PApi, Result)elseResult := nil; end;procedure TForm1.btInitializeClick(Sender: TObject); varLanguage: string; begincase ComboBox1.ItemIndex of3, 2:Language := 'eng';1:Language := 'chi_sim';elseLanguage := 'chi_sim+eng';end;// 加載需要很長時間,最好只執行一次TessInitialize('tessdata' + PathDelim, Language);FInitOver := True;Memo1.Text := '字庫加載完成'; end;procedure TForm1.btRecognizeClick(Sender: TObject); varStream: TMemoryStream;Bitmap: TBitmap;ImagePix: PPix;T1: TDateTime;F: Int64; beginif not FInitOver thenbtInitializeClick(Sender);//T1 := Now();//Stream := TMemoryStream.Create();tryBitmap := TBitmap.Create();tryBitmap.Assign(Image1.Picture.Graphic);// 最好把圖像轉化為標準bmp格式,tesseract加載圖片不好用,經常內存錯誤Bitmap.SaveToStream(Stream);finallyBitmap.Free();end;// 設置內存圖片,也可以直接加載內存文件ImagePix := SetImage(Stream);finallyStream.Free();end;//if Assigned(ImagePix) then begintry// 數字的情況,設置識別文字白名單if ComboBox1.ItemIndex = 3 thenSetVariable('tessedit_char_whitelist', '0123456789');// 開始識別RecognizeAsText();// 毫秒數F := MilliSecondsBetween(Now, T1);//Memo1.Text := FUtf8Text + #13#10 + //'-------------------------------HOCRText-------------------------------' + #13#10 + //FHOcrText + #13#10 + Format('%d', [F]);finallypixDestroy(ImagePix);end;end; end;end.?代碼實現中注意以下幾點:
1:加載字庫需要時間較長,代碼實現最好調用一次。
2:Tesseract API接口加載圖片文件錯誤比較多,最好是程序自己實現圖片轉化為Bitmap圖像,直接加載到內存為好。
3:圖片適當放大,識別效果更好。
4:如果只識別某些字符,比如數字,先調用SetVariable函數加載字符白名單,效果很好。
5:識別結果可以返回文字位置數據,可以更加這些數據定位文字和圖片關系。
三:DLL文件及字庫
?? ?Tesseract API主要DLL文件為liblept-5.dll 和 libtesseract-5.dll,其他的是大量的加載圖片使用的DLL,tessdata為字庫,如下圖:
?四:測試效果
一張A4圖片的識別時間1.5-3秒左右,中文識別率在96%以上。
筆者還提供PDF圖片識別,區域模板識別,請關注。
總結
以上是生活随笔為你收集整理的tesseract ocr 5.0 Api调用,delphi源码实现--识别率超高速度快的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue兼容IE8以上解决方案
- 下一篇: 操作系统安全防护