本项目基于mobilenetv3与pyqt5 实现自然场景文字检测及识别
实现功能
- 文字方向检测 0、90、180、270度检测(支持dnn/tensorflow)
- 支持(darknet/opencv dnn /keras)文字检测,支持darknet/keras训练
- 不定长OCR训练(英文、中英文) crnn\dense ocr 识别及训练 ,新增pytorch转keras模型代码(tools/pytorch_to_keras.py)
- 支持darknet 转keras, keras转darknet, pytorch 转keras模型
- 身份证/火车票结构化数据识别
- 新增CNN+ctc模型,支持DNN模块调用OCR,单行图像平均时间为0.02秒以下
- CPU版本加速
- 支持基于用户字典OCR识别
- 支持手写体和印刷体文字识别
- 新增语言模型修正OCR识别结果
- 支持树莓派实时识别方案
使用模型
1.cnstd
通过识别图片中的文字,我们可以更好地理解图片的内容。cnstd 是 Python 3 下基于MXNet的场景文字检测(Scene Text Detection,简称STD)工具包,自带了多个训练好的检测模型,安装后即可直接使用。当前的文字检测模型使用的是 PSEnet,目前支持两种 backbone 模型:mobilenetv3
和 resnet50_v1b
。它们都是在 ICPR 和 ICDAR15 的 11000
张训练集图片上训练得到的。
pip install cnstd
使用类 CnStd
进行场景文字的检测。类 CnStd
的初始化函数如下:
class CnStd(object):
"""
场景文字检测器(Scene Text Detection)。虽然名字中有个"Cn"(Chinese),但其实也可以轻松识别英文的。
"""
def __init__(
model_name='mobilenetv3',
model_epoch=None,
root=data_dir(),
context='cpu',
name=None,
):
其中的几个参数含义如下:
-
model_name
: 模型名称,即上面表格第一列中的值,目前仅支持取值为mobilenetv3
和resnet50_v1b
。默认为mobilenetv3
。 -
model_epoch
: 模型迭代次数。默认为None
,表示使用系统自带的模型对应的迭代次数。对于模型名称mobilenetv3
就是59
。 -
root
: 模型文件所在的根目录。 -
- Linux/Mac下默认值为
~/.cnstd
,表示模型文件所处文件夹类似~/.cnstd/0.1.0/mobilenetv3
。 - Windows下默认值为
C:\Users\<username>\AppData\Roaming\cnstd
。
- Linux/Mac下默认值为
-
context
:预测使用的机器资源,可取值为字符串cpu
、gpu
,或者mx.Context
实例。 -
name
:正在初始化的这个实例的名称。如果需要同时初始化多个实例,需要为不同的实例指定不同的名称。
每个参数都有默认取值,所以可以不传入任何参数值进行初始化:std = CnStd()
。
文本检测使用类CnOcr
的函数 **detect()**
,以下是详细说明:
类函数CnStd.detect(img_fp, max_size, pse_threshold, pse_min_area)
函数说明:
-
输入参数
img_fp
: 可以是需要识别的图片文件路径,或者是已经从图片文件中读入的数组,类型可以为mx.nd.NDArray
或np.ndarray
,取值应该是[0,255]
的整数,维数应该是(height, width, 3)
,第三个维度是channel,它应该是RGB
格式的。 -
输入参数
max_size
: 如果图片的长边超过这个值,就把图片等比例压缩到长边等于这个size。 -
输入参数
pse_threshold
: pse中的阈值;越低会导致识别出的文本框越大;反之越小。 -
输入参数
pse_min_area
: 面积大小低于此值的框会被去掉。所以此值越小,识别出的框可能越多。 -
返回值:类型为
list
,其中每个元素是一个字典, 存储了检测出的一个框的各种信息。字典包括以下几个值: -
- “box”:检测出的文字对应的矩形框四个点的坐标(第一列对应宽度方向,第二列对应高度方向);
np.ndarray
类型,shape==(4, 2)
; - “score”:得分;float类型;分数越高表示越可靠;
- “croppped_img”:对应 “box” 中的图片patch(
RGB
格式),会把倾斜的图片旋转为水平。np.ndarray
类型,shape==(width, height, 3)
; - 示例:
- “box”:检测出的文字对应的矩形框四个点的坐标(第一列对应宽度方向,第二列对应高度方向);
[{'box': array([[416, 77],
[486, 13],
[800, 325],
[730, 390]], dtype=int32),
'score': 1.0,
'cropped_img': array([[[25, 20, 24],
[26, 21, 25],
[25, 20, 24],
...,
[11, 11, 13],
[11, 11, 13],
[11, 11, 13]]], dtype=uint8)},
...
]
调用示例
from cnstd import CnStd
std = CnStd()
box_info_list = std.detect('examples/taobao.jpg')
或:
import mxnet as mx
from cnstd import CnStd
std = CnStd()
img_fp = 'examples/taobao.jpg'
img = mx.image.imread(img_fp, 1)
box_info_list = std.detect(img)
2.识别检测框中的文字(OCR)
上面示例识别结果中"cropped_img"对应的值可以直接交由 cnocr 中的 CnOcr
进行文字识别。如上例可以结合 CnOcr
进行文字识别:
from cnstd import CnStd
from cnocr import CnOcr
std = CnStd()
cn_ocr = CnOcr()
box_info_list = std.detect('examples/taobao.jpg')
for box_info in box_info_list:
cropped_img = box_info['cropped_img']
ocr_res = cn_ocr.ocr_for_single_line(cropped_img)
print('ocr result: %s' % ''.join(ocr_res))
注:运行上面示例需要先安装 cnocr
:
pip install cnocr
脚本使用
cnstd 包含了几个命令行命令,安装 cnstd 后即可使用。
预测单个文件或文件夹中所有图片
使用命令 cnstd evaluate
预测单个文件或文件夹中所有图片,以下是使用说明:
(venv) ➜ cnstd git:(master) ✗ cnstd evaluate -h
Usage: cnstd evaluate [OPTIONS]
Options:
--backbone [mobilenetv3|resnet50_v1b]
backbone model name
--model_root_dir TEXT 模型所在的根目录
--model_epoch INTEGER model epoch
-i, --img_dir TEXT 评估图片所在的目录或者单个图片文件路径
--max_size INTEGER 图片预测时的最大尺寸(最好是32的倍数)。超过这个尺寸的图片会被等比例压缩到此尺寸
[Default: 768]
--pse_threshold FLOAT threshold for pse [Default: 0.45]
--pse_min_area INTEGER min area for pse [Default: 100]
--gpu INTEGER 使用的GPU数量。默认值为-1,表示自动判断
-o, --output_dir TEXT 输出结果存放的目录
-h, --help Show this message and exit.
例如可以使用以下命令对图片 examples/taobao.jpg
进行检测,并把检测结果存放在目录 outputs
中:
cnstd evaluate -i examples/taobao.jpg -o outputs
具体使用也可参考文件 Makefile。
模型训练
使用命令 cnstd train
训练文本检测模型,以下是使用说明:
(venv) ➜ cnstd git:(master) ✗ cnstd train -h
Usage: cnstd train [OPTIONS]
Options:
--backbone [mobilenetv3|resnet50_v1b]
backbone model name
--pretrain_model_fp TEXT 初始化模型路径
--gpu INTEGER 使用的GPU数量。默认值为-1,表示自动判断
--optimizer TEXT optimizer for training [Default: Adam]
--batch_size INTEGER batch size for each device [Default: 4]
--epoch INTEGER train epochs [Default: 50]
--lr FLOAT learning rate [Default: 0.001]
--momentum FLOAT momentum [Default: 0.9]
--wd FLOAT weight decay factor [Default: 0.0]
--log_step INTEGER 隔多少步打印一次信息 [Default: 5]
-r, --root_dir TEXT 数据所在的根目录,它与索引文件中指定的文件路径合并后获得最终的文件路径
-i, --train_index_fp TEXT 存放训练数据的索引文件
-o, --output_dir TEXT 模型输出的根目录 [Default: ~/.cnstd]
-h, --help Show this message and exit.
3.pyqt5
pyqt5是一套Python绑定Digia QT5应用的框架。它可用于Python 2和3。本教程使用Python 3。Qt库是最强大的GUI库之一。pyqt5的官方网站http://www.riverbankcomputing.co.uk/news。
pyqt5做为Python的一个模块,它有620多个类和6000个函数和方法。这是一个跨平台的工具包,它可以运行在所有主要的操作系统,包括UNIX,Windows,Mac OS。pyqt5是双重许可。开发者可以在GPL和商业许可之间进行选择。
pyqt5的类别分为几个模块,包括以下:
-
QtCore
-
QtGui
-
QtWidgets
-
QtMultimedia
-
QtBluetooth
-
QtNetwork
-
QtPositioning
-
Enginio
-
QtWebSockets
-
QtWebKit
-
QtWebKitWidgets
-
QtXml
-
QtSvg
-
QtSql
-
QtTest
-
QtCore:包含了核心的非GUI功能。此模块用于处理时间、文件和目录、各种数据类型、流、URL、MIME类型、线程或进程。
-
QtGui包含类窗口系统集成、事件处理、二维图形、基本成像、字体和文本。
-
Qtwidgets模块包含创造经典桌面风格的用户界面提供了一套UI元素的类。
-
QtMultimedia包含的类来处理多媒体内容和API来访问相机和收音机的功能。
-
Qtbluetooth模块包含类的扫描设备和连接并与他们互动。描述模块包含了网络编程的类。这些类便于TCP和IP和UDP客户端和服务器的编码,使网络编程更容易和更便携。
-
Qtpositioning包含类的利用各种可能的来源,确定位置,包括卫星、Wi-Fi、或一个文本文件。
-
Enginio模块实现了客户端库访问Qt云服务托管的应用程序运行时。
-
Qtwebsockets模块包含实现WebSocket协议类。
-
QtWebKit包含一个基于Webkit2图书馆Web浏览器实现类。
-
Qtwebkitwidgets包含的类的基础webkit1一用于qtwidgets应用Web浏览器的实现。
-
QtXml包含与XML文件的类。这个模块为SAX和DOM API提供了实现。
-
QtSvg模块提供了显示SVG文件内容的类。可伸缩矢量图形(SVG)是一种描述二维图形和图形应用的语言。
-
QtSql模块提供操作数据库的类。
-
QtTest包含的功能,使pyqt5应用程序的单元测试
-
bSocket协议类。 QtWebKit包含一个基于Webkit2图书馆Web浏览器实现类。
-
Qtwebkitwidgets包含的类的基础webkit1一用于qtwidgets应用Web浏览器的实现。
-
QtXml包含与XML文件的类。这个模块为SAX和DOM API提供了实现。
-
QtSvg模块提供了显示SVG文件内容的类。可伸缩矢量图形(SVG)是一种描述二维图形和图形应用的语言。
-
QtSql模块提供操作数据库的类。 QtTest包含的功能,使pyqt5应用程序的单元测试
参考资料:
1.PyQt5官方文档教程
2.cnstd和cnocr文档
3.MobileNet网络文档