.NET Core 调用百度 PaddleOCR 识别图文

了解 PaddleOCR 之前,首先了解一下 PaddlePaddle。飞桨(PaddlePaddle)以百度多年的深度学习技术研究和业务应用为基础,是中国首个开源开放、技术领先、功能完备的产业级深度学习平台,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体。目前,飞桨已凝聚超265万开发者,服务企业10万家,基于飞桨开源深度学习平台产生了34万个模型。飞桨助力开发者快速实现AI想法,快速上线AI业务。帮助越来越多的行业完成AI赋能,实现产业智能化升级。

官网:https://www.paddlepaddle.org.cn/

PaddleOCR 旨在打造一套丰富、领先、且实用的OCR工具库,助力使用者训练出更好的模型,并应用落地。

首先看效果图:


(原图)


(识别后,标注的边框是自己根据返回的结果绘出来的)

百度飞桨需要的 Windows 环境

Windows 7/8/10 专业版/企业版 (64bit)
GPU版本支持CUDA 9.0/10.0/10.1/10.2/11.0,且仅支持单卡
Python 版本 2.7.15+/3.5.1+/3.6+/3.7+/3.8+ (64 bit)
pip 版本 20.2.2+ (64 bit)

注意:使用高版本的 python,如:python 3.9 会报错如下:

 ERROR: Could not find a version that satisfies the requirement paddlepaddle (from versions: none)
ERROR: No matching distribution found for paddlepaddle

解决方案:

下载支持的版本,例如:3.8.8 版本,下载地址:https://www.python.org/ftp/python/3.8.8/python-3.8.8-amd64.exe

python --version
pip --version
python -c "import platform;print(platform.architecture()[0]);print(platform.machine())"

需要确认Python和pip是64bit,并且处理器架构是x86_64(或称作x64、Intel 64、AMD64)架构,目前PaddlePaddle不支持arm64架构。下面的第一行输出的是”64bit”,第二行输出的是”x86_64”、”x64”或”AMD64”即可。

 

D:\itsvse>python --version
Python 3.8.8

D:\itsvse>pip --version
pip 20.2.3 from c:\program files\python38\lib\site-packages\pip (python 3.8)

D:\itsvse>python -c "import platform;print(platform.architecture()[0]);print(platform.machine())"
64bit
AMD64

Windows 10 安装 PaddlePaddle CPU 版本

命令:

python -m pip install paddlepaddle==2.0.1 -i https://mirror.baidu.com/pypi/simple

验证安装

安装完成后您可以使用 python 或 python3 进入python解释器,输入import paddle ,再输入 paddle.utils.run_check()

如果出现 PaddlePaddle is installed successfully!,说明您已成功安装。如下图:



(不要执行)卸载命令:

 

python -m pip uninstall paddlepaddle

 

安装 paddlehub

命令:

pip install paddlehub --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple

下载克隆 PaddleOCR

有条件的使用 git clone 命令下载,没条件的直接下载成压缩包再解压,地址:https://github.com/PaddlePaddle/PaddleOCR

我直接下载后,解压到:D:\itsvse\PaddleOCR-release-2.0 文件夹下面。

下载推理模型

安装服务模块前,需要准备推理模型并放到正确路径。

检测模型:https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_det_infer.tar
方向分类器:https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar
识别模型:https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_infer.tar

我是下载后,放在了 D:\itsvse\PaddleOCR-release-2.0\deploy\model 文件夹下面,如下图:




安装检测+识别串联服务模块

修改 "D:\itsvse\PaddleOCR-release-2.0\deploy\hubserving\ocr_system\params.py" 配置,如下:

# -*- coding:utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function


class Config(object):
pass


def read_params():
cfg = Config()

#params for text detector
cfg.det_algorithm = "DB"
cfg.det_model_dir = "D:\itsvse\PaddleOCR-release-2.0\deploy\model\ch_ppocr_server_v2.0_det_infer"
cfg.det_limit_side_len = 960
cfg.det_limit_type = 'max'

#DB parmas
cfg.det_db_thresh = 0.3
cfg.det_db_box_thresh = 0.5
cfg.det_db_unclip_ratio = 1.6
cfg.use_dilation = False

#EAST parmas
cfg.det_east_score_thresh = 0.8
cfg.det_east_cover_thresh = 0.1
cfg.det_east_nms_thresh = 0.2

#params for text recognizer
cfg.rec_algorithm = "CRNN"
cfg.rec_model_dir = "D:\itsvse\PaddleOCR-release-2.0\deploy\model\ch_ppocr_server_v2.0_rec_infer"

cfg.rec_image_shape = "3, 32, 320"
cfg.rec_char_type = 'ch'
cfg.rec_batch_num = 30
cfg.max_text_length = 25

cfg.rec_char_dict_path = "./ppocr/utils/ppocr_keys_v1.txt"
cfg.use_space_char = True

#params for text classifier
cfg.use_angle_cls = True
cfg.cls_model_dir = "D:\itsvse\PaddleOCR-release-2.0\deploy\model\ch_ppocr_mobile_v2.0_cls_infer"
cfg.cls_image_shape = "3, 48, 192"
cfg.label_list = ['0', '180']
cfg.cls_batch_num = 30
cfg.cls_thresh = 0.9

cfg.use_pdserving = False
cfg.use_tensorrt = False
cfg.drop_score = 0.5

return cfg

使用 cmd 窗口在 D:\itsvse\PaddleOCR-release-2.0 文件夹下面执行如下命令:

hub install deploy\hubserving\ocr_system\

备注:修改 \hubserving\ocr_system 下的 python 文件,需要重新安装部署,还是执行如上命令即可。

可能会报错如下:

 

ModuleNotFoundError: No module named 'imgaug'
ModuleNotFoundError: No module named 'pyclipper'
ModuleNotFoundError: No module named 'lmdb'

 

使用 pip 安装即可,例如:pip install imgaug

安装成功如下图:

[2021-03-15 15:59:37,549] [    INFO] - Successfully uninstalled ocr_system
[2021-03-15 15:59:38,237] [    INFO] - Successfully installed ocr_system-1.0.0




启动 ocr_system 服务

这里配置参数使用配置文件,首先修改"D:\itsvse\PaddleOCR-release-2.0\deploy\hubserving\ocr_system\config.json"配置,如下:

{
"modules_info": {
"ocr_system": {
"init_args": {
"version": "1.0.0",
"use_gpu": false
},
"predict_args": {
}
}
},
"port": 8866,
"use_multiprocess": true,
"workers": 2
}

使用如下命令启动服务:

hub serving start -c "D:\itsvse\PaddleOCR-release-2.0\deploy\hubserving\ocr_system\config.json"

 




使用 python 客户端测试图片

将需要测试的图片放入 "D:\itsvse\PaddleOCR-release-2.0\doc\imgs1" 文件夹内,在 D:\itsvse\PaddleOCR-release-2.0 执行如下命令:




test_hubserving.py 源码如下:

# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(__dir__)
sys.path.append(os.path.abspath(os.path.join(__dir__, '..')))

from ppocr.utils.logging import get_logger
logger = get_logger()

import cv2
import numpy as np
import time
from PIL import Image
from ppocr.utils.utility import get_image_file_list
from tools.infer.utility import draw_ocr, draw_boxes

import requests
import json
import base64


def cv2_to_base64(image):
return base64.b64encode(image).decode('utf8')


def draw_server_result(image_file, res):
img = cv2.imread(image_file)
image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
if len(res) == 0:
return np.array(image)
keys = res[0].keys()
if 'text_region' not in keys: # for ocr_rec, draw function is invalid
logger.info("draw function is invalid for ocr_rec!")
return None
elif 'text' not in keys: # for ocr_det
logger.info("draw text boxes only!")
boxes = []
for dno in range(len(res)):
boxes.append(res[dno]['text_region'])
boxes = np.array(boxes)
draw_img = draw_boxes(image, boxes)
return draw_img
else: # for ocr_system
logger.info("draw boxes and texts!")
boxes = []
texts = []
scores = []
for dno in range(len(res)):
boxes.append(res[dno]['text_region'])
texts.append(res[dno]['text'])
scores.append(res[dno]['confidence'])
boxes = np.array(boxes)
scores = np.array(scores)
draw_img = draw_ocr(image, boxes, texts, scores, drop_score=0.5)
return draw_img


def main(url, image_path):
image_file_list = get_image_file_list(image_path)
is_visualize = True
headers = {"Content-type": "application/json"}
cnt = 0
total_time = 0
for image_file in image_file_list:
img = open(image_file, 'rb').read()
if img is None:
logger.info("error in loading image:{}".format(image_file))
continue

# 发送HTTP请求
starttime = time.time()
data = {'images': [cv2_to_base64(img)]}
r = requests.post(url=url, headers=headers, data=json.dumps(data))
elapse = time.time() - starttime
total_time += elapse
logger.info("Predict time of %s: %.3fs" % (image_file, elapse))
res = r.json()["results"][0]
logger.info(res)

if is_visualize:
draw_img = draw_server_result(image_file, res)
if draw_img is not None:
draw_img_save = "./server_results/"
if not os.path.exists(draw_img_save):
os.makedirs(draw_img_save)
cv2.imwrite(
os.path.join(draw_img_save, os.path.basename(image_file)),
draw_img[:, :, ::-1])
logger.info("The visualized image saved in {}".format(
os.path.join(draw_img_save, os.path.basename(image_file))))
cnt += 1
if cnt % 100 == 0:
logger.info("{} processed".format(cnt))
logger.info("avg time cost: {}".format(float(total_time) / cnt))


if __name__ == '__main__':
if len(sys.argv) != 3:
logger.info("Usage: %s server_url image_path" % sys.argv[0])
else:
server_url = sys.argv[1]
image_path = sys.argv[2]
main(server_url, image_path)

使用 .NET Core 客户端测试图片

直接上代码,如下:

using Newtonsoft.Json;
using System;
using System.Net.Http;

namespace PaddleOCRDemo
{
class Program
{
static void Main(string[] args)
{
var base64 = Convert.ToBase64String(System.IO.File.ReadAllBytes(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "xzz.jpg")));
Console.WriteLine(base64);
HttpClient client = new HttpClient();
HttpContent content = new StringContent(JsonConvert.SerializeObject(new { images = new string[] { base64 } }));
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
var ret = client.PostAsync("http://192.168.120.78:8866/predict/ocr_system", content).Result;
if (ret.IsSuccessStatusCode)
{
Console.WriteLine(ret.Content.ReadAsStringAsync().Result);
}
Console.WriteLine("Hello World!");
}
}
}

响应如下

{"msg":"","results":[[{"confidence":0.9994004964828491,"text":"博客统计","text_region":[[23,18],[85,18],[85,33],[23,32]]},{"confidence":0.9951881170272827,"text":"大家好,我是小渣渣,于2015年4月5日开通了博客","text_region":[[22,74],[471,74],[471,93],[22,93]]},{"confidence":0.9985174536705017,"text":"截至此时2021-03-1516:19:52","text_region":[[23,111],[217,111],[217,126],[23,126]]},{"confidence":0.9762932062149048,"text":"累计关于.NET的文章1184篇,累计阅读6844154次,累计评论10505次","text_region":[[24,153],[448,153],[448,165],[24,165]]},{"confidence":0.9847920536994934,"text":"累计所有文章2807 篇,累计阅读14210224次,累计评论19074次","text_region":[[24,177],[414,177],[414,188],[24,189]]}]],"status":"000"}

 




由于我是用的是虚拟机部署的服务端,有时候会报内存的错误:

Fail to alloc memory of 268418688 size.

临时的解决方案,重新启动服务端。 

参考资料:

https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.0/deploy/hubserving/readme.md
https://www.paddlepaddle.org.cn/install/quick

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据时代,数据科学都有些啥?

暑假咻地一下过完啦,前几天,小天介绍了关于数模课程的开学季限时优惠(传送门),今天要介绍的是python课程。接下来,小天来详细说明一下!19月17日~23日报名《python机器学习实战》即可享受限时330…

那些被.NET大厂拒绝的大佬们,究竟弱在哪里?

如火如荼的金三银四跳槽季迎来尾声,几家欢喜几家愁,既看到腾讯阿里百度的大厂offer,又羡慕30k、40k、50k的高薪,更多其实还是各种面试失蹄的故事。成功的案例五花八门,而失败的原因却千篇一律。据统计,约70…

在python中strip_python中strip()函数怎么用?

python中strip()函数怎么用?发布时间:2020-05-19 16:57:38来源:亿速云阅读:182作者:Leah今天小编为大家分享的是python中strip()函数的使用方法。代码详细容易理解,为此分享给大家做个参考。一起跟随小编过…

有哪些经济学理论可以用在谈恋爱上?

全世界有3.14 % 的人已经关注了数据与算法之美大概两周前回加拿大的航班上,我在机舱尾部跟一位空姐聊了很久。大概两周前回加拿大的航班上,我在机舱尾部跟一位空姐聊了很久。看到浮标沉下去了,我却把鱼竿放回地上,难道我是素食主义…

python 局部变量 占内存吗_Python中全局变量和局部变量的理解与区别

前言学过编程的人应该对全局变量与局部变量这两个名词并不陌生,Python也同多数编程语言一样,也有全局变量与局部变量的概念但是与其他编程语言又有所不同全局变量与局部变量两者的本质区别就是在于作用域用通俗的话来理解的话,全局变量是在整…

C# 离线使用nuget

正常在我们使用nuget进行程序集下载的时候,直接在vs编辑器中直接进行操作,下载自己想要的各种程序,但是某些时候,在进行一些办公时,公司要求本机编码不能进行联网操作,那么这种情况下我们怎么进行nuget程序…

21个令程序员泪流满面的瞬间

「1」公司实习生找 Bug「2」在调试时,将断点设置在错误的位置「3」当我有一个很棒的调试想法时 「4」偶然间看到自己多年前写的代码「5」当我第一次启动我的单元测试时「6」数据库的Delete语句忘了使用限定词where... 「7」明明是个小bug但就是死活修不好......「8…

python气象数据处理与绘图_Python气象数据处理与绘图:纬高图的另一种思路

前言有些时候为了研究不同高度上气象要素之间的联系,纬度-高度作为xy轴的图在一些SCI论文中比较常见。这是我研究的CMIP6数据中ua,va,wap,ta这几个气象要素在纬度-高度图上的不同。读取数据的地方就略去了,需要注意的是需要进行平均,温度转为…

.Net Core 集成 Kafka

最近维护的一个系统并发有点高,所以想引入一个消息队列来进行削峰。考察了一些产品,最终决定使用kafka来当做消息队列。以下是关于kafka的一些知识的整理笔记。kafkakafka 是分布式流式平台。它由linkedin开发,后贡献给了Apache开源组织并成为…

如果生活中没有数学,那么。。。

随着科技的快速发展,人工智能的重要性日渐显现。对于大多数新手来说,弄清楚入门人工智能需要哪些数学基础、需要熟悉什么框架等,都至关重要。机器学习是一个异常丰富的研究领域,有大量未解决的问题:公正、可解释性、易…

mysql5.6查看归档_MySQL5.6 使用 pt-archiver 分批删除、归档数据

pt-archiver是一个十分高效的表数据归档工具,归档数据可以分批进行事务处理,减少性能消耗;如果实例开启了GTID,因为GTID不支持CTAS创建表的语法,可以使用pt-archiver处理;对于跨实例或者跨服务器的表数据归…

Microsoft宣布将停止支持多个 .NET Framework版本

Microsoft 宣布,使用传统的、不安全的安全哈希算法1(SHA-1)签名的多个 .NET 框架版本将在明年停止支持。据 .NET 首席工程经理 Jamshed Damkewala 表示,.NET 框架 4.5.2、4.6 和 4.6.1 将在 2022 年 4 月 26 日后停止支持&#xf…

算法有偏见?总比人类识别强吧!

在讨伐算法导致的偏见和产生的作用时,更重要的问题是:与完全没有使用算法的情况相比是怎样的?我们应该比较算法的缺陷与人类的缺陷,而不是简单地询问算法是否存在缺陷。一场革命正在悄然进行。这场革命与大部分新闻报道中出现的人…

通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪

Dapr提供了一些开箱即用的分布式链路追踪解决方案,今天我们来讲一讲如何通过dapr的configuration来实现非侵入式链路追踪的目录:一、通过Dapr实现一个简单的基于.net的微服务电商系统二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架…

21副酷炫的动图让你了解各种数学概念

数学是很难的科学,但因为它是科学家用数学来解释宇宙的语言,我们无可避免的要学习它。看看下面的这些GIF动图,它们提供了视觉的方式来帮助你理解各种数学技巧。1椭圆的画法2杨辉三角问题(Pascal triangles)解法3使用“FOIL”轻松的解决二项式…

VMware 虚拟机(linux)增加根目录磁盘空间

今天查看学校的监控报修系统,不能访问了!!!系统运行很慢,用top命令查看发现内存使用率90%,用"df -h ”查看“/”目录使用率已达到80%,导致系统运行很慢。我用以下方法扩大根目录磁盘空间。…

网关Ocelot功能演示完结,久等了~~~

前言关于网关(Ocelot)的分享,还遗留一些功能没演示呢,接着来聊聊;这次重点针对网关Ocelot使用缓存、集成Polly做服务治理、集成IdentityServer4做认证授权来详细说说;如果对上一篇感兴趣,点这里(网关Ocelot功能演示安排…

数学课本上的几大变态

数学课本上的几大变态数据与算法之美用数据解决不可能长按扫码关注

牛逼顿的一生:当智商高到一定程度,情商就不重要了

牛顿老师在科学圈里曾经很有权势,被女王封了爵位成了贵族,人称牛爵爷,官至皇家造币局局长兼皇家学会会长。如果阿尔伯特没有辞了以色列总统的话和他有一拼。说他有权势并不仅是官大,主要是贡献大。如果17世纪就有诺贝尔奖的话&…

趣味图解+源码分析,轻松吃透Linux

如今的软件开发行业,服务器端市场基本被 Linux 系统占领了。移动端中的 Android 系统是基于 Linux 内核开发的,那些很火的虚拟化、消息队列、云计算、大数据等技术,都默认支持 Linux 操作系统。而对软件工程师来说,也几乎一定会遇…