说明
离上次使用隔得有点久,我都忘了有这茬了。最近正好有一个应用,需要进行场景文字识别,而我也不想花太多精力搞,这个包应该是合适的。
上次的介绍cnocr的文章在这里,总体上来说,识别效果还可以。
内容
1 背景
大致要识别这样的图片里的文字
理论上,我觉得应该:
- 1 使用目标识别(例如yolo)把文本块找出来
- 2 对文本块进行预处理(例如形变恢复,或者去噪)
- 3 对文本块拆分
- 4 对拆分的文本块预测
- 5 合并结果
肯定是没时间去标记样本搞yolo的,肯定也是没时间去做汉字识别模型的。所以我觉得cnocr正好能解决时间的问题。
粗略的试一下,一堆大段的文字识别是有问题的(或者说全错了)。但是单行的识别是对的,比如「保护标志」,「兴业路76号」。所以我打算做一个小的修改,把识别到的大图(文本块)切分成一条一条的逐个识别
。
2 环境搭建
我还是希望使用docker来搭建运行环境,我使用自己的一个镜像进行增加
- 1 先打开一个容器
# 做新的镜像
docker run -it \
registry.cn-hangzhou.aliyuncs.com/andy08008/YOURIMAGE\
bash
- 2 执行命令
# 更新
apt-get update && apt-get install libgl1
这条命令如果不执行,后面会报ImportError: libGL.so.1: cannot open shared object file: No such file or directory
的错误,按百度搜到的apt install libgl1-mesa-glx
并没有用,系统说这个包已经存在并且是最新的。正解是在stackoverflow找到的
- 3 执行其他安装
# 要先升级,不然(opencv)会卡主
pip3 install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/
pip3 install scikit-build -i https://mirrors.aliyun.com/pypi/simple/
pip3 install cmake -i https://mirrors.aliyun.com/pypi/simple/
pip3 install opencv-python -i https://mirrors.aliyun.com/pypi/simple/
- 4 安装场景识别文字相关包
pip3 install cnstd -i https://mirrors.aliyun.com/pypi/simple/
pip3 install cnocr -i https://mirrors.aliyun.com/pypi/simple/
- 5 安装交互的环境
pip3 install ipython -i https://mirrors.aliyun.com/pypi/simple/
pip3 install jupyter -i https://mirrors.aliyun.com/pypi/simple/
对于jupyer做一些定制化(以便远程登录)
jupyter设置第一步,访问配置
# 生成配置
jupyter notebook --generate-config
# 编辑配置
vim /root/.jupyter/jupyter_notebook_config.py
---
c.NotebookApp.allow_remote_access = True
c.NotebookApp.ip = '0.0.0.0'
# 允许root启动
c.NotebookApp.allow_root = True
jupyter设置第二步,设置密码
# 设置密码
jupyter notebook password
在弹出的命令框里输入就可以了,比直接写配置文件安全、方便。
jupyter设置第三步,安装插件
pip3 install jupyter_contrib_nbextensions -i https://mirrors.aliyun.com/pypi/simple/
jupyter contrib nbextension install --user
# 设置生效
jupyter nbextensions_configurator enable --user
勾选hinterland、tableofcontent
。前者用于代码补全,可以省很多事;后者是把markdown编目录,也很有用。
要注意的是,如果ipython版本过高,可能会导致自动补全失败。具体可以参考这篇文章,我把版本降到ipython ==7.1.1
后成功
jupyter设置第四步,设置背景
jt -t monokai -f fira -fs 13 -cellw 90% -ofs 11 -dfs 11 -T -N
*固态硬盘要大一点(系统盘最好1个T以上,数据盘可以另外再挂载),这次m1因为系统盘只有120G,无法增加overlay,导致镜像拉到m1上。
然后配置一下frp端口透射就可以用了。
启动容器
docker run -d --name='m4_ocr_jupyter_v1'\
--restart=always \
-v /etc/localtime:/etc/localtime \
-v /opt/prj21/jupyter_server/data:/workspace \
-v /etc/timezone:/etc/timezone\
-v /home/mdisk1:/home/mdisk1\
-p 8889:8888\
-e "LANG=C.UTF-8"\
registry.cn-hangzhou.aliyuncs.com/YOURIMAGE\
sh -c "cd /workspace && jupyter notebook"
环境搭好,可以继续了
3 测试1
先看看程序处理的真实过程
from cnstd import CnStd
from cnocr import CnOcr
import numpy as np
from PIL import Image
std = CnStd()
cn_ocr = CnOcr()
box_info_dict = std.detect('test1.png')
for box_info in box_info_dict['detected_texts']:
cropped_img = box_info['cropped_img']
tem_img = Image.fromarray(cropped_img)
tem_img.show()
ocr_res = cn_ocr.ocr(cropped_img)
print('ocr result: %s' % ''.join(sum(ocr_res,[])))
我发现识别的结果是比较失败的
- 颠倒、误判
- 正确的部分、部分字没有获取的部分
结论:单行识别的效果还行,但是区域识别(抠图)是失败的
考虑到目前数据的特点是没有形变,整体还算清晰,有文字描述、图片和空白三种类型。下一步计划使用规则式的方法识别区域,再对文字进行横向分割
- 1 将图片灰度化,去噪
- 2 以矩形的方式进行扫描,如果区域内的灰度分布和文字的差距大则删除
- 3 留下文字矩形区域
- 4 分行识别