PaddleOCR之高性能Go语言实现OCR识别

发布时间 2023-03-24 20:09:17作者: 饶玉田

最近为了让python语言能够直接调用PaddleOCR的C++的动态链接库,针对本人已经开源的PaddleOCR项目https://gitee.com/raoyutian/paddle-ocrsharp使用的PaddleOCR的C++动态库,进行了大量代码修改,修改后PaddleOCR,导出标准C函数接口,极大地方便了其他语言直接调用并进行OCR文字识别。

__declspec(dllexport) void Initializejson(char* modelPath_det_infer, char* modelPath_cls_infer, char* modelPath_rec_infer, char* keys, char* parameterjson);
  __declspec(dllexport) char* Detect(char* imagefile);
  __declspec(dllexport) char* DetectByte(char* imagebytedata, size_t* size);
  __declspec(dllexport) char* DetectBase64(char* imagebase64);
  __declspec(dllexport) char* DetectByteData(const char* img, int nWidth, int nHeight, int nChannel);
  __declspec(dllexport) void FreeEngine();

  本文将介绍python ,go ,c#几种开发语言的识别结果。

一 、pyhon:

import os
import ctypes
import Parameter
from ctypes import *
import json
from datetime import datetime
import numpy as np
paddleOCR=cdll.LoadLibrary(".\PaddleOCR.dll")#加载C++动态库
encode="gbk" 
#传入OCR模型参数
root="./"
cls_infer =root+"/inference/ch_ppocr_mobile_v2.0_cls_infer"
rec_infer = root+"/inference/ch_PP-OCRv3_rec_infer"
det_infer = root+"/inference/ch_PP-OCRv3_det_infer"
ocrkeys = root+"/inference/ppocr_keys.txt"
#OCR识别参数对象,后面序列化为json字符串
parameter=Parameter.Parameter()
p_cls_infer=cls_infer.encode(encode)
p_rec_infer=rec_infer.encode(encode)
p_det_infer=det_infer.encode(encode)
p_ocrkeys=ocrkeys.encode(encode)
def main():
   #序列化参数为json字符串
    parameterjson= json.dumps(parameter,default=Parameter.Parameter2dict)
     #初始化OCR引擎,一次即可
    paddleOCR.Initializejson( p_det_infer,  p_cls_infer,  p_rec_infer,  p_ocrkeys, parameterjson.encode(encode))
    result=""
    paddleOCR.Detect.restype = ctypes.c_wchar_p #识别结果是宽字节编码,
    imagepath=os.path.abspath('.')+"\\image\\"
    imagefiles=os.listdir(imagepath)
    total=[]
    for image in imagefiles:
       imagefile=imagepath+image
       t1= datetime.utcnow()
       #调用OCR识别接口,调用的是文件路径接口
       result= paddleOCR.Detect(imagefile.encode(encode))
       t2=datetime.utcnow()
       c=t2-t1
       total.append(c)
       print("time:",c)
       print(result)
    print("平均时间:",   np.mean(total))
if __name__=="__main__":
    main()
    input()  

  Python直接调用C++的动态库进行OCR识别,相比python调用python的预测库进行OCR,性能提升了不少。

 

 

二、Go:

package main
import (
    "fmt"
    "syscall"
    "unsafe"
    "os"
    "bufio"
    "C"
)
// 获取字符串的长度指针
func lenPtr(s string) uintptr {
    return uintptr(len(s))
}
// 获取数字的指针
func intPtr(n int) uintptr {
    return uintptr(n)
}
// 获取字符串的指针
func strPtr(s string) uintptr {
    return uintptr(unsafe.Pointer(syscall.StringBytePtr(s)))
}
func main() {  
 dll,err:= syscall.LoadDLL("PaddleOCR.dll")
 if err!=nil {
    fmt.Println(err)
    return 
 }
 Initjson,err:=dll.FindProc("Initializejson")
 if err!=nil {
    fmt.Println(err)
    return 
 }
 detect,err:=dll.FindProc("Detect")
 if err!=nil {
    fmt.Println(err)
    return 
 }
Initjson.Call(strPtr("D:\\PaddleOCR\\deploy\\Go\\inference\\ch_PP-OCRv3_det_infer"),
strPtr("D:\\PaddleOCR\\deploy\\Go\\inference\\ch_ppocr_mobile_v2.0_cls_infer"),
strPtr("D:\\PaddleOCR\\deploy\\Go\\inference\\ch_PP-OCRv3_rec_infer"),
strPtr("D:\\PaddleOCR\\deploy\\Go\\inference\\ppocr_keys.txt"),strPtr("{}"))

 res, _, _:=detect.Call(strPtr("D:\\PaddleOCR\\deploy\\Go\\image\\test.jpg"))  
  p_result := (*C.char)(unsafe.Pointer(res))
 ocrresult:= C.GoString(p_result)
 fmt.Println(ocrresult)

 input := bufio.NewScanner(os.Stdin)
 input.Scan() 
}

  

go语言现学现卖。Go实现,主要采用CGo,syscall.LoadDLL("PaddleOCR.dll")

使用syscall.LoadDLL加载PaddleOCR.dll动态链接库。

 

 

三、C#

c#语言调用C++动态库,直接采用DllImport方法。

 

        [DllImport(PaddleOCRdllName, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        internal static extern void Initialize(string det_infer, string cls_infer, string rec_infer, string keys, OCRParameter parameter);
        [DllImport(PaddleOCRdllName, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        internal static extern void Initializejson(string det_infer, string cls_infer, string rec_infer, string keys, string parameterjson);

        [DllImport(PaddleOCRdllName, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        internal static extern IntPtr Detect(string imagefile);

        [DllImport(PaddleOCRdllName, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        internal static extern IntPtr DetectByte(byte[] imagebytedata, long size);

        [DllImport(PaddleOCRdllName, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        internal static extern IntPtr DetectBase64(string imagebase64);

        [DllImport(PaddleOCRdllName, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        internal static extern int FreeEngine();

  

 

 

开源项目地址: https://gitee.com/raoyutian/paddle-ocrsharp

更多内容,欢迎关注公众号,加入QQ群,了解更多内容。