我是靠谱客的博主 笑点低鞋垫,最近开发中收集的这篇文章主要介绍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;

interface

uses
    Winapi.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;

type
    TForm1 = 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);
    private
        FModulePath: 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;

var
    Form1: TForm1;
    _CancelRecognize: Boolean;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
    Buf: array [0 .. MAX_PATH] of Char;
    S: string;
begin
    SetString(S, Buf, GetModuleFileName(HInstance, Buf, SizeOf(Buf)));
    FModulePath := ExtractFilePath(S);

    if (hTesseractLib = 0) then
        raise Exception.Create('Tesseract library is not loaded');
    //
    _CancelRecognize := False;
    // 得到一个API接口
    PApi := TessBaseAPICreate();
    FInitOver := False;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
    if Assigned(PApi) then begin
        TessBaseAPIEnd(PApi);
        TessBaseAPIDelete(PApi);
    end;
end;

function TForm1.RootPath(): string;
var
    I: Integer;
begin
    Result := FModulePath;
    for I := Length(Result) - 1 downto 1 do begin
        if Result[I] = '' then begin
            Result := Copy(Result, 1, I);
            Break;
        end;
    end;
end;

procedure TForm1.btSelectImgClick(Sender: TObject);
begin
    OpenDialog1.InitialDir := RootPath() + 'example';
    OpenDialog1.Filter := 'Image File|*.JPG;*.PNG;*.GIF;*.BMP;*.JPEG;';
    if OpenDialog1.Execute() then begin
        edtImage.Text := OpenDialog1.FileName;
        Image1.Picture.LoadFromFile(edtImage.Text);
    end;
end;

function TForm1.PUTF8CharToString(Char: PUTF8Char; DeleteText: Boolean = True): string;
var
    UtfStr: UTF8String;
    X: Integer;
begin
    Result := '';

    if Assigned(Char) then begin
        X := Length(Char);
        SetString(UtfStr, Char, X);
        if DeleteText and (X > 0) then
            TessDeleteText(Char);
        Result := string(UtfStr);
    end;
end;

// 初始化识别字库
function TForm1.TessInitialize(DataPath, Language: string; Mode: TessOcrEngineMode = OEM_DEFAULT): Boolean;
begin
    SetCurrentDirectory(PChar(FModulePath));
    //
    if Assigned(PApi) then
        Result := TessBaseAPIInit2(PApi, PUTF8Char(UTF8Encode(DataPath)), PUTF8Char(UTF8Encode(Language)), Mode) = 0
    else
        Result := False;
end;

function CancelCallback(cancel_this: Pointer; words: Integer): Boolean; cdecl;
begin
    Result := _CancelRecognize;
end;

function ProgressCallback(Progress: Integer; Left, Right, Top, Bottom: Integer): Boolean; cdecl;
begin
    Result := False;
end;

// 设置识别参数
function TForm1.SetVariable(Key: string; Value: string): Boolean;
begin
    Result := TessBaseAPISetVariable(PApi, PUTF8Char(UTF8Encode(Key)), PUTF8Char(UTF8Encode(Value)));
end;

// 识别图片中的文字
procedure TForm1.RecognizeAsText();
var
    FMonitor: ETEXT_DESC;
begin
    FillChar(FMonitor, SizeOf(FMonitor), #0);
    FMonitor.cancel := @CancelCallback;
    FMonitor.progress_callback := @ProgressCallback;
    FUtf8Text := '';
    FHOcrText := '';
    //
    if TessBaseAPIRecognize(PApi, FMonitor) <> 0 then
        Exit;

    // 识别文字
    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;
begin
    Result := pixRead(PUTF8Char(UTF8Encode(FileName)));
    if Assigned(Result) then
        TessBaseAPISetImage2(PApi, Result)
    else
        Result := nil;
end;

// 加载要识别的内存
function TForm1.SetImage(Stream: TMemoryStream): PPix;
begin
    Stream.Position := 0;
    Result := pixReadMem(Stream.Memory, Stream.Size);
    if Assigned(Result) then
        TessBaseAPISetImage2(PApi, Result)
    else
        Result := nil;
end;

procedure TForm1.btInitializeClick(Sender: TObject);
var
    Language: string;
begin
    case ComboBox1.ItemIndex of
        3, 2:
            Language := 'eng';
        1:
            Language := 'chi_sim';
    else
        Language := 'chi_sim+eng';
    end;
    // 加载需要很长时间,最好只执行一次
    TessInitialize('tessdata' + PathDelim, Language);
    FInitOver := True;
    Memo1.Text := '字库加载完成';
end;

procedure TForm1.btRecognizeClick(Sender: TObject);
var
    Stream: TMemoryStream;
    Bitmap: TBitmap;
    ImagePix: PPix;
    T1: TDateTime;
    F: Int64;
begin
    if not FInitOver then
        btInitializeClick(Sender);
    //
    T1 := Now();
    //
    Stream := TMemoryStream.Create();
    try
        Bitmap := TBitmap.Create();
        try
            Bitmap.Assign(Image1.Picture.Graphic);
            // 最好把图像转化为标准bmp格式,tesseract加载图片不好用,经常内存错误
            Bitmap.SaveToStream(Stream);
        finally
            Bitmap.Free();
        end;
        // 设置内存图片,也可以直接加载内存文件
        ImagePix := SetImage(Stream);
    finally
        Stream.Free();
    end;
    //
    if Assigned(ImagePix) then begin
        try
            // 数字的情况,设置识别文字白名单
            if ComboBox1.ItemIndex = 3 then
                SetVariable('tessedit_char_whitelist', '0123456789');
            // 开始识别
            RecognizeAsText();
            // 毫秒数
            F := MilliSecondsBetween(Now, T1);
            //
            Memo1.Text := FUtf8Text + #13#10 + //
              '-------------------------------HOCRText-------------------------------' + #13#10 + //
              FHOcrText + #13#10 + Format('%d', [F]);
        finally
            pixDestroy(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源码实现--识别率超高速度快的全部内容,希望文章能够帮你解决tesseract ocr 5.0 Api调用,delphi源码实现--识别率超高速度快所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部