Skip to content

Commit

Permalink
readme
Browse files Browse the repository at this point in the history
  • Loading branch information
DayBreak-u committed Jul 30, 2020
1 parent ba4ccef commit 5e3cd08
Show file tree
Hide file tree
Showing 18 changed files with 43 additions and 127 deletions.
Binary file modified .DS_Store
Binary file not shown.
89 changes: 4 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,102 +1,21 @@
## 本项目基于[chineseocr](https://github.com/chineseocr/chineseocr)[psenet](https://github.com/WenmuZhou/PSENet.pytorch) 实现中文自然场景文字检测及识别

## chineseocr_lite 的 onnx 推理
# 环境
- pytorch 1.2.0

- python3
- python3.6

- linux/macos/windows
---
- windows环境配置参考热心网友的文章[Python构建快速高效的中文文字识别OCR](https://blog.csdn.net/lly1122334/article/details/104752851) 👍
- windows环境运行需要手动编译psenet/pse目录下的pse.cpp为DLL,为了方便新增支持python3.5和python3.6的pyd文件,在windows平台运行
的时候需要根据自己环境的python版本更改对应的pyd文件为pse.pyd即可

## Docker 环境
- 重写Dockerfile,资源占用更小,可在1C 1G的学生服务器编译成功
- 容器环境是python3.6 + pytorch-cpu1.2
- 编译方式:在项目根目录下运行 `docker build -t chineseocr:v1 .`
- Flask-RESTful API运行方式: `docker run --name ocr_api -p5000:5000 -d <Image ID>`
请求方式详见下方
- web app运行方式:`docker run --name ocr_ui -p8000:8000 -d <Image ID> python3 app.py 8000`


## PSENET 编译
``` Bash
cd psenet/pse
rm -rf pse.so
make
```

# 实现功能
- [x] 提供轻量的backone检测模型psenet(8.5M),crnn_lstm_lite(9.5M) 和行文本方向分类网络(1.5M)
- [x] 任意方向文字检测,识别时判断行文本方向
- [x] crnn\crnn_lite lstm\dense识别(ocr-dense和ocr-lstm是搬运[chineseocr](https://github.com/chineseocr/chineseocr)的)
- [x] 支持竖排文本识别
- [x] ncnn 实现 (支持lstm) nihui大佬实现的[crnn_lstm推理](https://github.com/ouyanghuiyu/chineseocr_lite/pull/41) 具体操作详解: [详细记录超轻量中文OCR LSTM模型ncnn实现](https://zhuanlan.zhihu.com/p/113338890?utm_source=qq&utm_medium=social&utm_oi=645149500650557440)
- [x] 提供竖排文字样例以及字体库(旋转90度的字体)
- [x] dbnet ncnn 实现 (感谢 @[zhengqicl](https://github.com/zhengqicl) 的实现)

# 2020.07.02更新
- 提供dbnet模型,dbnet.onnx(3.7M) dbnet_lite.onnx(1.7M)


# 2020.03.16更新
- psenet ncnn核扩展实现,有效解决粘连文本检测问题,详见[ncnn ocr一条龙](https://github.com/ouyanghuiyu/chineseocr_lite/tree/master/ncnn_project/ocr)
- nihui大佬实现的[crnn_lstm推理](https://github.com/ouyanghuiyu/chineseocr_lite/pull/41) 具体操作详解: [详细记录超轻量中文OCR LSTM模型ncnn实现](https://zhuanlan.zhihu.com/p/113338890?utm_source=qq&utm_medium=social&utm_oi=645149500650557440)

# 2020.03.12更新
- 升级crnn_lite_lstm_dw.pth模型crnn_lite_lstm_dw_v2.pth , 精度更高



## 竖排字体样式:
<img width="300" height="200" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/vertical_text_fonts/imgs/test.jpg"/>

## 竖排生成的竖排文本样例:
<img width="256" height="32" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/vertical_text_fonts/imgs/00156360.jpg"/>
<img width="256" height="32" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/vertical_text_fonts/imgs/00000027.jpg"/>
<img width="256" height="32" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/vertical_text_fonts/imgs/00156365.jpg"/>
<img width="256" height="32" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/vertical_text_fonts/imgs/00187940.jpg"/>


## web服务启动
``` Bash
cd chineseocr_lite## 进入chineseocr目录
python app.py 8080 ##8080端口号,可以设置任意端口
python backend/main.py
```
## 访问服务
http://127.0.0.1:8080/ocr


## Flask-RESTful API demo
`cd chineseocr_lite && python flask_app.py`
```text
- 请求url: http://ip:port/api/v1/ocr
- 请求方式:POST
- 请求参数
- ImgString:图片转base64后的字符串, str
- 返回实例
{
"code": "SUCCESS",
"text": "不配图我总觉得不舒服不完整不专业"
}
```
## 识别结果展示

<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/test_imgs/5_res.jpg"/>
<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/test_imgs/4_res.jpg"/>
<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/test_imgs/1_res.jpg"/>
<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/test_imgs/2_res.jpg"/>
<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/test_imgs/3_res.jpg"/>


## ncnn检测识别展示(x86 cpu 单进程)
<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/ncnn_project/ocr/res_imgs/res_3.jpg"/>
<img width="500" height="300" src="https://github.com/ouyanghuiyu/chineseocr_lite/blob/master/ncnn_project/ocr/res_imgs/res_2.jpg"/>

## flask-restful api 内存测试(dbnet)
200张图片测试稳定在1-1.5G左右的内存
![](test_imgs/flask-api.png)
<p align="center"><img src="test_imgs/res.jpg"\></p>


## 参考
Expand Down
6 changes: 3 additions & 3 deletions backend/webInterface/tr_run.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@


import time
from model import text_predict
from model import OcrHandle
import tornado.web
import tornado.gen
import tornado.httpserver
Expand All @@ -17,7 +17,7 @@

logger = logging.getLogger(log.LOGGER_ROOT_NAME + '.' +__name__)


ocrhandle = OcrHandle()

class TrRun(tornado.web.RequestHandler):
'''
Expand Down Expand Up @@ -106,7 +106,7 @@ def post(self):
new_height = int(img.height / scale + 0.5)
img = img.resize((new_width, new_height), Image.BICUBIC)

res = text_predict(img)
res = ocrhandle.text_predict(img)

img_detected = img.copy()
img_draw = ImageDraw.Draw(img_detected)
Expand Down
11 changes: 4 additions & 7 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@


dbnet_short_size = 960
crnn_type = "full"
crnn_lite = True

model_path = os.path.join(father_path, "models/dbnet.onnx")

# crnn相关
nh = 256

# if crnn_type == "full":
# crnn_model_path = os.path.join(father_path, "models/crnn_lstm.onnx")
# elif crnn_type == "lite":
crnn_model_path = os.path.join(father_path, "models/crnn_lite_lstm.onnx")
crnn_model_path = os.path.join(father_path, "models/crnn_lstm.onnx")
if crnn_lite:
crnn_model_path = os.path.join(father_path, "models/crnn_lite_lstm.onnx")


from crnn.keys import alphabetChinese as alphabet
Expand Down
64 changes: 32 additions & 32 deletions model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,52 @@
from dbnet.dbnet_infer import DBNET


text_handle = DBNET(model_path, short_size=dbnet_short_size)

class OcrHandle(object):
def __init__(self):
self.text_handle = DBNET(model_path, short_size=dbnet_short_size)
self.crnn_handle = CRNNHandle(crnn_model_path)

crnn_handle = CRNNHandle(crnn_model_path)
def crnnRecWithBox(self,im, boxes_list,score_list):
"""
crnn模型,ocr识别
@@model,
@@converter,
@@im:Array
@@text_recs:text box
@@ifIm:是否输出box对应的img
"""
results = []
boxes_list = sorted_boxes(np.array(boxes_list))
for index, (box ,score) in enumerate(zip(boxes_list,score_list)):

def crnnRecWithBox(im, boxes_list,score_list):
"""
crnn模型,ocr识别
@@model,
@@converter,
@@im:Array
@@text_recs:text box
@@ifIm:是否输出box对应的img
tmp_box = copy.deepcopy(box)
partImg_array = get_rotate_crop_image(im, tmp_box.astype(np.float32))

"""
results = []
boxes_list = sorted_boxes(np.array(boxes_list))
for index, (box ,score) in enumerate(zip(boxes_list,score_list)):

tmp_box = copy.deepcopy(box)
partImg_array = get_rotate_crop_image(im, tmp_box.astype(np.float32))

partImg = Image.fromarray(partImg_array).convert("RGB")

partImg = Image.fromarray(partImg_array).convert("RGB")

partImg_ = partImg.convert('L')

partImg_ = partImg.convert('L')
try:

try:
simPred = self.crnn_handle.predict(partImg_) ##识别的文本
except:
continue

simPred = crnn_handle.predict(partImg_) ##识别的文本
except:
continue

if simPred.strip() != u'':
results.append([tmp_box,simPred,score])
if simPred.strip() != u'':
results.append([tmp_box,simPred,score])

return results
return results


def text_predict(img):
boxes_list, score_list = text_handle.process(np.asarray(img).astype(np.uint8))
result = crnnRecWithBox(np.array(img), boxes_list,score_list)
return result
def text_predict(self,img):
boxes_list, score_list = self.text_handle.process(np.asarray(img).astype(np.uint8))
result = self.crnnRecWithBox(np.array(img), boxes_list,score_list)

return result


if __name__ == "__main__":
Expand Down
Binary file modified models/crnn_lite_lstm.onnx
Binary file not shown.
Binary file removed test_imgs/1.jpg
Binary file not shown.
Binary file removed test_imgs/1_res.jpg
Binary file not shown.
Binary file removed test_imgs/2.jpg
Binary file not shown.
Binary file removed test_imgs/2_res.jpg
Binary file not shown.
Binary file removed test_imgs/3.jpg
Binary file not shown.
Binary file removed test_imgs/3_res.jpg
Binary file not shown.
Binary file removed test_imgs/4.jpg
Binary file not shown.
Binary file removed test_imgs/4_res.jpg
Binary file not shown.
Binary file removed test_imgs/5.jpg
Binary file not shown.
Binary file removed test_imgs/5_res.jpg
Binary file not shown.
Binary file removed test_imgs/flask-api.png
Binary file not shown.
Binary file added test_imgs/res.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5e3cd08

Please sign in to comment.