前言
因项目需要,调研了一下目前市面上一些开源的OCR工具,支持本地部署,非调用API,主要有PaddleOCR/CnOCR/chinese_lite OCR/EasyOCR/Tesseract/chineseocr/mmocr这几款产品。
本文主要尝试了EasyOCR/CnOCR/Tesseract/PaddleOCR这四款产品。
EasyOCR
EasyOCR官方仓库:https://github.com/JaidedAI/EasyOCR
安装EasyOCR:
pip install easyocr
测试例程
import easyocr
reader = easyocr.Reader(['ch_sim','en']) # this needs to run only once to load the model into memory
result = reader.readtext('chinese.jpg')
实测EasyOCR对cuda的要求比较严格,在一个pytorch正常的环境中,运行之后会报错:
Could not load symbol cublasGetSmCountTarget from cublas64_11.dll. Error code 127
#833提到了该问题,谈及原因可能是cuda和cudnn不匹配,更换cudnn之后,报错仍未消失,遂暂置不提。
CnOCR
CnOCR官方仓库:https://github.com/breezedeus/CnOCR
CnOCR安装:
pip install cnocr
CnOCR的环境要求比较严格,其在requirements.txt
写了非常多的依赖版本号,因此如果在现有环境中直接安装,它会将Pytorch等依赖卸载重装,比较坑,使用最好先单开新环境。
测试例程:
from cnocr import CnOcr
img_fp = 'img/output_2.png'
ocr = CnOcr() # 所有参数都使用默认值
out = ocr.ocr(img_fp)
print(out)
实测在我的业务场景下,使用默认模型效果不太行。
Tesseract
Tesseract官方仓库:https://github.com/tesseract-ocr/tesseract
Tesseract是用C++进行开发的,因此如果要在python中进行使用,需要借助第三方依赖pytesseract
首先需要在本机上安装Tesseract
安装包下载地址:https://digi.bib.uni-mannheim.de/tesseract/
安装过程可参考:https://blog.csdn.net/weixin_51571728/article/details/120384909
配置完成后,在命令行输入tesseract -v
打印出版本信息则表示安装成功。
之后安装pytesseract
:
pip install pytesseract
测试例程
img_path = 'img/img_1.png'
# 添加tesseract的路径
pytesseract.pytesseract.tesseract_cmd = r'C:\Users\zxy\AppData\Local\Programs\Tesseract-OCR\tesseract.exe'
"""
image_to_string():如果识别英文或数字可以不必额外参数,如果识别其他语言则需要加上lang参数
lang='chi_sim'表示要识别的是中文简体
没有识别出来时,返回空白
"""
text = pytesseract.image_to_string(Image.open(img_path), lang='chi_sim')
print(text)
实测这个效果在我的场景也表现一般,并且tesseract对于中英文有不同的模型,泛用性不是很好。
PaddleOCR
PaddleOCR是百度旗下的产品,目前已经迭代到第四版。
PaddleOCR官方仓库:https://github.com/PaddlePaddle/PaddleOCR
PaddleOCR安装:
pip install paddleocr
测试例程:
import cv2
from paddleocr import PaddleOCR
if __name__ == '__main__':
ocr = PaddleOCR(use_angle_cls=True, lang="ch", ocr_version='PP-OCRv4')
image_input_fullname = 'img/output_5.png'
img = cv2.imread(image_input_fullname)
result = ocr.ocr(img, cls=True)
print(result)
根据PP-OCRv4的介绍文档,PP-OCRv4在训练时以(32,320), (48,320), (64,320)三个不同尺度上进行训练。
实测发现当文字区域小于这个范围时,效果会受到影响,因此,可以引入padding策略,即在文字区域范围周边加一圈白边,使输入模型的图片分辨率提升。
import cv2
from paddleocr import PaddleOCR
def add_padding_to_image(image, output_size=(640, 640), color=(255, 255, 255)):
h, w = image.shape[:2]
# 计算需要添加的padding大小
delta_w = max(output_size[0] - w, 0)
delta_h = max(output_size[1] - h, 0)
top, bottom = delta_h // 2, delta_h - (delta_h // 2)
left, right = delta_w // 2, delta_w - (delta_w // 2)
# 添加padding
padded_image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
return padded_image
if __name__ == '__main__':
ocr = PaddleOCR(use_angle_cls=True, lang="ch", ocr_version='PP-OCRv4')
image_input_fullname = 'img/output_5.png'
img = cv2.imread(image_input_fullname)
padded_img = add_padding_to_image(img)
result = ocr.ocr(img, cls=True)
print(result)
在我的业务场景中,PaddleOCR
的表现最好,基本能达到80%以上的识别准确率,如果还需要提升,还可以根据自己的数据再训练。
标注工具:PPOCRLabelv2
使用文档:https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.5/PPOCRLabel/README_ch.md
训练文档:https://aistudio.baidu.com/modelsdetail/270?modelId=270