PaddlePaddle RapidOcr 使用一则
[[PaddlePaddle_Serving]]
PaddleOCR 快速开始
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7/doc/doc_ch/quickstart.md#11
安装 PaddlePaddle
如果您没有基础的Python运行环境,请参考运行环境准备。
-
您的机器安装的是CUDA9或CUDA10,请运行以下命令安装
python3 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple -
您的机器是CPU,请运行以下命令安装
# python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple # 不行 # 用 pip pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
安装PaddleOCR whl包
pip install "paddleocr>=2.0.1" -i https://mirror.baidu.com/pypi/simple # 推荐使用2.0.1+版本
paddleocr默认使用PP-OCRv4模型(--ocr_version PP-OCRv4),如需使用其他版本可通过设置参数--ocr_version,具体版本说明如下:
| 版本名称 | 版本说明 |
|---|---|
| PP-OCRv4 | 支持中、英文检测和识别,方向分类器,支持多语种识别 |
| PP-OCRv3 | 支持中、英文检测和识别,方向分类器,支持多语种识别 |
| PP-OCRv2 | 支持中英文的检测和识别,方向分类器,多语言暂未更新 |
| PP-OCR | 支持中、英文检测和识别,方向分类器,支持多语种识别 |
Python脚本调用
中英文与多语言使用
通过Python脚本使用PaddleOCR whl包,whl包会自动下载ppocr轻量级模型作为默认模型。
- 检测+方向分类器+识别全流程
from paddleocr import PaddleOCR, draw_ocr
# Paddleocr目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
ocr = PaddleOCR(use_angle_cls=True, lang="ch") # need to run only once to download and load model into memory
img_path = './imgs/11.jpg'
result = ocr.ocr(img_path, cls=True)
for idx in range(len(result)):
res = result[idx]
for line in res:
print(line)
# 显示结果
from PIL import Image
result = result[0]
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')
结果是一个list,每个item包含了文本框,文字和识别置信度
[[[28.0, 37.0], [302.0, 39.0], [302.0, 72.0], [27.0, 70.0]], ('纯臻营养护发素', 0.9658738374710083)]
RapidOcr (PaddleOCR)
apache 开源文件内容提取 - https://tika.apache.org/
官方仓库PaddleOCR - https://github.com/PaddlePaddle/PaddleOCR
[[PaddlePaddle_OCR]]
RapidOcrNcnnJvm
jni 调用
参考 RapidOcrNcnnJvm - https://github.com/RapidAI/RapidOcrNcnnJvm
- 预先编译好的动态运行库复制到run-test文件夹,根据您选择的编译类型,macOS、linux可能还需要额外配置动态库的搜索路径
- 从第1步的说明中找到模型下载地址,放到run-test/models文件夹,测试的目标图片放到run-test/images文件夹
- 用IDEA打开本项目
- Main.java为java版调用范例,main.kt为kotlin版调用范例,之后以kotlin为范例来说明
- IDEA中直接在在main方法左边点击绿色的运行图标,可以直接调试运行范例,但此时没有输入参数。
- 编辑运行参数:顶部工具栏“运行”图标左边,点开下拉菜单“Edit Configurations”
- VM options:添加
-Djava.library.path=run-test,(把run-test文件夹加到java的lib搜索路径) - Program arguments 添加命令行输入参数
run-test/models dbnet_op angle_op crnn_lite_op keys.txt run-test/test_imgs/1.jpg
命令行参数models文件夹里必须有相应的模型文件,接下来的四个文件名对应模型文件夹里的3种模型(不含扩展名)和1个keys文件,请确认文件名无误
run-test/images/1.jpg是待识别的目标图片
- 点击运行,正常的话就可以输出识别结果。
本质上是jni 调用
编译好的动态库 - https://github.com/RapidAi/RapidOcrNcnn/releases 注意是 Ncnn
看项目dll项目 源码.
入口在 https://github.com/RapidAI/RapidOcrOnnx/blob/main/src/main.cpp ;
导出的对象是 https://github.com/RapidAI/RapidOcrOnnx/blob/main/src/OcrLiteJni.cpp ?
um... 实际有哪些函数, 还得看 dll 导出的函数表.. 用IDA静态分析看看
名称 地址 序号
JNI_OnLoad 0000000180010C20 1
JNI_OnUnload 0000000180010C70 2
Java_com_benjaminwan_ocrlibrary_OcrEngine_detect 0000000180010CB0 3
Java_com_benjaminwan_ocrlibrary_OcrEngine_enableResultText 0000000180011410 4
Java_com_benjaminwan_ocrlibrary_OcrEngine_getVersion 0000000180011780 5
Java_com_benjaminwan_ocrlibrary_OcrEngine_initLogger 00000001800117A0 6
Java_com_benjaminwan_ocrlibrary_OcrEngine_initModels 00000001800117D0 7
Java_com_benjaminwan_ocrlibrary_OcrEngine_setGpuIndex 0000000180012730 8
Java_com_benjaminwan_ocrlibrary_OcrEngine_setNumThread 0000000180012740 9
DllEntryPoint 00000001807D7030 [main entry]
package com.benjaminwan.ocrlibrary
class OcrEngine() {
init {
try {
//对应的是 https://github.com/RapidAI/RapidOcrNcnn/releases/download/1.2.0/windows-jni.7z 下载的 dll库
System.loadLibrary("RapidOcrNcnn")
} catch (e: Exception) {
e.printStackTrace()
}
}
............
更多模型可以在官网 https://rapidai.github.io/RapidOCRDocs/model_list/#_1 下载(Onnx格式)
package com.benjaminwan.ocr
import com.benjaminwan.ocrlibrary.OcrEngine
fun main(args: Array<String>) {
//System.setProperty("java.library.path", "D:\\libarry\\RapidOcrNcnnJvm\\win-JNI-CPU-x64\\bin")
val jniLibDir = System.getProperty("java.library.path")
println("java.library.path=$jniLibDir")
// 对应的是 [Project_RapidOcrNcnn-1.2.0.7z](https://github.com/RapidAI/RapidOcrNcnn/releases/download/1.2.0/Project_RapidOcrNcnn-1.2.0.7z) 下载的模型 及文件
//------- init models/dir image/path -------
val modelsDir = "E:\\projects-work\\pdf-classify\\run-test\\models"
val detName = "ch_PP-OCRv3_det_infer"
val clsName = "ch_ppocr_mobile_v2.0_cls_infer"
val recName = "ch_PP-OCRv3_rec_infer"
val keysName = "ppocr_keys_v1.txt"
val imagePath = "E:\\projects-work\\pdf-classify\\run-test\\images\\1.jpg"
println("modelsDir=$modelsDir, detName=$detName, clsName=$clsName, recName=$recName, keysName=$keysName, imagePath=$imagePath")
//------- numThread -------
val numThread = if (args.size > 6) args[6].trim().toIntOrNull() ?: 4 else 4
//------- padding -------
val padding = if (args.size > 7) args[7].trim().toIntOrNull() ?: 50 else 50
//------- maxSideLen -------
val maxSideLen = if (args.size > 8) args[8].trim().toIntOrNull() ?: 1024 else 1024
//------- boxScoreThresh -------
val boxScoreThresh = if (args.size > 9) args[9].trim().toFloatOrNull() ?: 0.5f else 0.5f
//------- boxThresh -------
val boxThresh = if (args.size > 10) args[10].trim().toFloatOrNull() ?: 0.3f else 0.3f
//------- unClipRatio -------
val unClipRatio = if (args.size > 11) args[11].trim().toFloatOrNull() ?: 1.6f else 1.6f
//------- doAngle -------
val doAngleFlag = if (args.size > 12) args[12].trim().toIntOrNull() ?: 1 else 1
val doAngle = (doAngleFlag == 1)
//------- mostAngle -------
val mostAngleFlag = if (args.size > 13) args[13].trim().toIntOrNull() ?: 1 else 1
val mostAngle = (mostAngleFlag == 1)
//------- gpuIndex -------
val gpuIndex = if (args.size > 14) args[14].trim().toIntOrNull() ?: 0 else 0
println("gpuIndex=$gpuIndex")
//------- get jni version -------
val ocrEngine = OcrEngine()
val version = ocrEngine.getVersion()
println("version=$version")
//------- setNumThread -------
ocrEngine.setNumThread(numThread)
//------- init Logger -------
ocrEngine.initLogger(
isConsole = true,//jni启用命令行输出
isPartImg = true,
isResultImg = true
)
ocrEngine.enableResultText(imagePath)
ocrEngine.setGpuIndex(gpuIndex)//GPU0一般为默认GPU,参数选项:使用CPU(-1)/使用GPU0(0)/使用GPU1(1)/...
//------- init Models -------
val initModelsRet = ocrEngine.initModels(modelsDir, detName, clsName, recName, keysName)
if (!initModelsRet) {
println("Error in models initialization, please check the models/keys path!")
return
}
//------- set param -------
println("padding($padding) boxScoreThresh($boxScoreThresh) boxThresh($boxThresh) unClipRatio($unClipRatio) doAngle($doAngle) mostAngle($mostAngle)")
ocrEngine.padding = padding //图像外接白框,用于提升识别率,文字框没有正确框住所有文字时,增加此值。
ocrEngine.boxScoreThresh = boxScoreThresh //文字框置信度门限,文字框没有正确框住所有文字时,减小此值
ocrEngine.boxThresh = boxThresh //请自行试验
ocrEngine.unClipRatio = unClipRatio //单个文字框大小倍率,越大时单个文字框越大
ocrEngine.doAngle = doAngle //启用(1)/禁用(0) 文字方向检测,只有图片倒置的情况下(旋转90~270度的图片),才需要启用文字方向检测
ocrEngine.mostAngle = mostAngle //启用(1)/禁用(0) 角度投票(整张图片以最大可能文字方向来识别),当禁用文字方向检测时,此项也不起作用
//------- start detect -------
val ocrResult =
ocrEngine.detect(imagePath, maxSideLen = maxSideLen) //按图像长边进行总体缩放,放大增加识别耗时但精度更高,缩小减小耗时但精度降低,maxSideLen=0代表不缩放
//使用native方法,可以让OcrEngine成为单例
/*val ocrResult =
ocrEngine.detect(imagePath, padding, maxSideLen, boxScoreThresh, boxThresh, unClipRatio, doAngle, mostAngle)*/
//------- print result -------
println("识别结果: "+ ocrResult.toString())
return
}
RapidOcrOnnxJvm (推荐)
官方说明项目- https://github.com/RapidAI/RapidOcrOnnxJvm
dll库项目 - https://github.com/RapidAi/RapidOcrOnnx/releases
模型下载- https://github.com/RapidAI/RapidOcrOnnx/releases/tag/1.2.2
object INSTANCE {
val log = LoggerFactory.getLogger(INSTANCE::class.java)
val ocrEngine = OcrEngine()
init {
val modelsDir = System.getProperty("user.dir") + "\\run\\models_onnx"
println("加载模型目录 : "+modelsDir)
//注意 他这里需要模型后缀了, 我靠
val detName = "ch_PP-OCRv3_det_infer.onnx"
val clsName = "ch_ppocr_mobile_v2.0_cls_infer.onnx"
val recName = "ch_PP-OCRv3_rec_infer.onnx"
val keysName = "ppocr_keys_v1.txt"
val numThread = 4;
ocrEngine.setNumThread(numThread)
//------- init Logger -------
ocrEngine.initLogger(
isConsole = false,
isPartImg = false,
isResultImg = false
)
//------- init Models -------
val initModelsRet = ocrEngine.initModels(modelsDir, detName, clsName, recName, keysName)
if (!initModelsRet) {
log.error("模型初始化失败")
}else{
log.info("模型初始化成功")
}
}
}
更换模型
更多模型可以在官网 https://rapidai.github.io/RapidOCRDocs/model_list/#_1 下载(Onnx格式)
在PC端识别用到的就是:
val detName = "ch_PP-OCRv4_det_infer.onnx"
val recName = "ch_PP-OCRv4_rec_infer.onnx"
ppocr_keys_v1.txt 用原来的即可

浙公网安备 33010602011771号