基于服务器部署的OCR在线识别应用

一、前言

前段时间,接了一个OCR在线识别的外包程序,在实现过程中遇到了很多麻烦,也走过很多弯路。在网络查阅了许多相关资料后,发现关于这一块知识详细而完整的文章不多,故写下此文,既是对前段时间的总结,也为今后有同样困扰的朋友提供一些帮助。

几经比较,本文最终决定使用百度的开源OCR框架作为基础,实现服务器部署以及端口调用。PaddleOCR是百度开源的OCR识别框架,采用Paddlehub可快速一键部署。PaddleOCR 的 github 地址:https://github.com/PaddlePaddle/PaddleOCR


二、准备

1、自备服务器,如果没有服务器使用ubuntu作为模拟服务器也行,本文使用的是阿里云服务器

2、在服务器内安装Python环境,建议直接安装Anaconda,可以省去很多时间

3、安装百度的PaddlePaddle,这是个所有百度框架的老大哥,只要你想使用百度的框架产品,这个是必备的

4、安装百度的PaddleHub,这是PaddlePaddle的头号小老弟,安装这个后才能一键部署PaddleOCR

5、安装第三方库shapely、pyclipper,这是运行PaddleOCR的依赖库,没有他们PaddleOCR运行不了

6、安装百度的PaddleOCR框架,有基于移动端的识别框架,也有基于服务端的识别框架,本文使用服务端框架


三、详细步骤

1、配置Python环境

       对于初始的服务器来说,其内置的Python版本一般为2.7,已经不再适用当前环境所需的要求,所以需要重新安装新版本的Python环境。为了方便,我直接使用了Anaconda,它把Python和一些常用的库有集合起来了,不需要后续再一个个下载安装。下面进行第一步,下载Anaconda安装包。建议使用使用清华的镜像下载,速度会快很多,清华园镜像地址

在这里插入图片描述

将镜像下载进自己的服务器内,我新建了一个Downloads目录专门来存放下载下来的文件

在这里插入图片描述

把Anaconda的安装包下载下列后,只需要执行一个bash命令即可: bash Anaconda3-2020.02-Linux-x86_64.sh然后就是根据提示,要么回车要么输入 yes 。由于笔者写文的时候,环境已经配置好了,没有保留Anaconda的安装截图,如果中途没有报错,一般就是安装成功了。要验证也非常简单,只需要输入:anaconda -Vconda -V ,有显示相对应的版本号就算成功了,如下图。

在这里插入图片描述

因为有用到图像处理,所以还需要安装一个openCV,安装步骤也非常简单,一句命令即可

pip install opencv-python


2、安装PaddlePaddle

       PaddlePaddle是百度旗下的一个人工智能开发框架,功能类似于tensorflow和PyTorch等等。对于PaddlePaddle的安装和使用,百度有给出非常简单而清楚的使用教程,教程链接:https://www.paddlepaddle.org.cn/install/quick#show_info ,这里给出了各个系统各个环境对应的安装教程,笔者也是根据这份教程进行简易安装的。

在这里插入图片描述

  • 需要确认您的 Ubuntu 14.04/16.04/18.04 是 64 位操作系统*
  • 确认您需要安装 PaddlePaddle 的 Python 是您预期的位置,因为您计算机可能有多个 Python
which python3

(根据您的环境您可能需要替换本说明中所有命令行中的 python3python ,或者替换为具体的 Python 路径)

  • 同时检查 Python 3 的版本,确认是 3.5.1+/3.6/3.7:
python3 --version
  • 确认 Python 有对应的 pip,检查 Python 对应的 pip 的版本,确认是 9.0.1+:
python3 -m ensurepip
python3 -m pip --version
  • 确认 Python 和 pip 是 64 bit,并且处理器架构是x86_64架构,目前PaddlePaddle不支持arm64架构
    下面的两个命令分别输出的是 “64bit” 和 “x86_64” 即可:
python3 -c "import platform;print(platform.architecture()[0]);print(platform.machine())"
  • 执行以下命令安装(推荐使用百度源):
python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple

python3 -m pip install paddlepaddle -i https://pypi.tuna.tsinghua.edu.cn/simple

验证信息

使用 python3 进入python解释器,输入import paddle.fluid ,再输入 paddle.fluid.install_check.run_check()
如果出现 Your Paddle Fluid is installed successfully!,说明您已成功安装。

如果顺利的话,大概几分钟就可以安装成功了,安装教程非常简单。


3、安装PaddleHub

       paddlehub安装就极其简单了,一句命令就行:pip install paddlehub,如果担心自己安装的版本不是最新版,也可以使用paddlehub的更新命令:pip install paddlehub --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple

4、安装第三方库shapely、pyclipper

       理论上来说,在没有意外的情况下,使用下面两句话就可以安装成功了。安装后检验的方式也非常简单,使用 python 进入python解释器,尝试导入两个库,没有报错就说明安装成功了!

pip install shapely -i https://pypi.tuna.tsinghua.edu.cn/simple 
pip install pyclipper -i https://pypi.tuna.tsinghua.edu.cn/simple 

在这里插入图片描述

这里插个题外话,笔者最开始使用paddlehub是在自己的windows系统上,在windows上安装shapely,不能直接使用上面这句命令对于在windows上安装shapely需要先去相应的网站下载其whl文件,再进行pip安装才行,笔者最开始被这个问题困扰许久,所以有用windows系统安装shapely的朋友,可以直接百度windows下安装shapely的教程。windows所需要的whl文件下载地址如下:https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely


5、安装PaddleOCR

       前面的东西都搞定后,当然就是我们的主角登场啦!如果前面的东西都安装没有问题后,那么安装PaddleOCR就变的十分简单了,前面有提到,PaddleOCR是PaddlePaddle的小老弟,那么PaddleOCR也可以算是Paddlehub的小老弟,有了Paddlehub,安装相应的OCR框架就是一句命令的事情。

       在安装之前有一个小科普,PaddleHub现已开源OCR文字识别的预训练模型主要有两种:移动端的超轻量模型、服务器端的精度更高模型,从名字也可以大致知道,前者适用于安卓端,后者适用于服务端;前者速度高,后者精度高。对于这两个模型的安装和使用,百度也给了非常非常详细的教程。

移动端的超轻量模型:仅有8.6M,chinese_ocr_db_crnn_mobile

服务器端的精度更高模型:识别精度更高,chinese_ocr_db_crnn_server

​ 所接的外包程序有明确的精度需求,所以选择了服务端的OCR预训练模型,下面给出安装服务端的安装命令:

hub install chinese_ocr_db_crnn_server==1.0.3


6、发布PaddleOCR

​ 官网给出的发布命令如下:

hub serving start -m chinese_ocr_db_crnn_server

根据官网给出的发布命令,虽然可以发布成功,但是存在一个很大的问题:我们必须一直开启着这个窗口,并且不能继续执行下一条命令。这对我们来说,执行和调用就非常不方便了,所以考虑将这个进程放入后台,放入后台的命令如下:

nohup hub serving start -m chinese_ocr_db_crnn_server &

nohup:加在一个命令的最前面,表示不挂断的运行命令;&:加载一个命令的最后面,表示这个命令放在后台执行


四、调用

1、Python的调用
import requests
import json
import cv2
import base64

def cv2_to_base64(image):
    data = cv2.imencode('.jpg', image)[1]
    return base64.b64encode(data.tostring()).decode('utf8')

# 发送HTTP请求
data = {'images':[cv2_to_base64(cv2.imread("图片地址"))]}
headers = {"Content-type": "application/json"}
url = "http://xxx(服务器ip):8866/predict/chinese_ocr_db_crnn_server"
r = requests.post(url=url, headers=headers, data=json.dumps(data))

# 打印预测结果
print(r.json()["results"])

这是官方教程给出的Python调用模板,非常简单优雅的代码。但是由于笔者要开始一个在线扫一扫应用,所以使用安卓语言进行调用,于是在这个代码的基础上进行语言转换。

2、Java的调用
package test;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.text.ParseException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import sun.misc.BASE64Encoder;

public class InvoiceOcr {
	    //接口地址
		private static String apiURL = "http://xxxx:8866/predict/chinese_ocr_db_crnn_server";
		//private Log logger = LogFactory.getLog(this.getClass());
		private HttpClient httpClient = null;
		private HttpPost method = null;
		private long startTime = 0L;
		private long endTime = 0L;
		private int status = 0;
	 
		/**
		 * 接口地址
		 * 
		 * @param url
		 */
		public InvoiceOcr(String url) {
	 
			if (url != null) {
				this.apiURL = url;
			}
			if (apiURL != null) {
				httpClient = new DefaultHttpClient();
				method = new HttpPost(apiURL);
	 
			}
		}
	 
		/**
		 * 调用 API
		 * 
		 * @param parameters
		 * @return
		 */
		public String post(String parameters) {
			String body = null;
			if (method != null & parameters != null && !"".equals(parameters.trim())) {
				try {
	 
					// 建立一个NameValuePair数组,用于存储欲传送的参数
					method.addHeader("Content-type","application/json");
					method.setHeader("Accept", "application/json");
					method.setEntity(new StringEntity(parameters, Charset.forName("UTF-8")));
					startTime = System.currentTimeMillis();
	 
					HttpResponse response = httpClient.execute(method);
					
					endTime = System.currentTimeMillis();
					int statusCode = response.getStatusLine().getStatusCode();
					
					//logger.info("statusCode:" + statusCode);
					//logger.info("调用API 花费时间(单位:毫秒):" + (endTime - startTime));
					if (statusCode != HttpStatus.SC_OK) {
						//logger.error("Method failed:" + response.getStatusLine());
						status = 1;
					}
					body = EntityUtils.toString(response.getEntity(),"utf-8");
				} catch (IOException e) {
					// 网络错误
					status = 3;
					System.out.println(e);
				} finally {
					//logger.info("调用接口状态:" + status);
				}
			}
			return body;
		}
	 
		public static void main(String[] args) throws ParseException {
			InvoiceOcr ac = new InvoiceOcr(apiURL);
			JSONArray arry = new JSONArray();
			JSONObject j = new JSONObject();
			arry.add(imageToBase64("E:\\DESK_LIVE\\20200907\\first\\image2.png"));
			j.put("images",arry);
	        String result = ac.post(j.toJSONString());
	        System.out.println(result);
		}
		
		public static String imageToBase64(String path) {
		        byte[] data = null;
		        // 读取图片字节数组
		        try {
		            InputStream in = new FileInputStream(path);
		            data = new byte[in.available()];
		            in.read(data);
		            in.close();
		        } catch (IOException e) {
		            e.printStackTrace();
		        }
		        // 对字节数组Base64编码
		        BASE64Encoder encoder = new BASE64Encoder();
		        return encoder.encode(data);// 返回Base64编码过的字节数组字符串
		    }
		/**
		 * 0.成功 1.执行方法失败 2.协议错误 3.网络错误
		 * 
		 * @return the status
		 */
		public int getStatus() {
			return status;
		}
	 
		/**
		 * @param status
		 *            the status to set
		 */
		public void setStatus(int status) {
			this.status = status;
		}
	 
		/**
		 * @return the startTime
		 */
		public long getStartTime() {
			return startTime;
		}
	 
		/**
		 * @return the endTime
		 */
		public long getEndTime() {
			return endTime;
		}
}

现在知道为什么说python代码很优雅了吧!以上代码还需要五个配套的架包,架包名称如下:commons-codec-1.9.jar、commons-logging-1.2.jar、fastjson-1.2.67.jar、httpclient-4.5.jar、httpcore-4.4.1.jar,并且将其关联到相应的lib目录下。


五、结果展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

可以看到图片越来越模糊,但是识别的精确度依旧很高,满足用户需求,模型效率表现良好!

自此,本次小结就到此结束了,可以看到整个过程并不困难,复现起来也十分简单,所以如果你觉得有意思,不如动手试试看,做一个自己的在线OCR识别应用程序。

  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
受到大佬项目 免root跨平台自动化测试框架webrebot 本地离线OCR的启发和指引,成功的把百度开源的 PaddleOCR 应用到PYTHON及VC++ 经过小范围测试python的效果比VC++理想很多,绝大多数游戏及日常都可以成功通用识别. 更新添加DLL版本了 在网盘里已经更新了VC++的 DLL版本,及VC++调用测试的!知道易语言 怎么调用64位DLL的也发个例子吧 注: PYTHON代码里还用到了两个组件要在按下面的安装完成PaddlePaddle和PaddleOCR后再执行两个命令才能使用 fastapi 一个异步的超强WEB框架 1、python -m pip install fastapi 2、python -m pip install uvicorn 游戏小图识别成功率比较高 大图测试 python部分代码: python 的安装很多的坑..在期间找了无数贴子。。自己把经验总结分享 一、安装python         安装3.7或者3.8 python         我的安装环境是 WIN10 X64 PYTHON 3.85 二、安装PaddlePaddle 升级PIP  python -m pip install --upgrade pip         如果您的机器安装的是CUDA9或CUDA10,请运行以下命令安装         python -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple         如果您的机器是CPU,请运行以下命令安装, 工作室或者GPU不太好的就用这个, 正常也使用这个就好了         python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple 三、克隆\安装PaddleOCR代码         方法一:                git clone https://gitee.com/paddlepaddle/PaddleOCR                 安装第三方库                 cd PaddleOCR                 python -m pip install -r requirments.txt         方法二:                 pip install paddleocr -i https://mirror.baidu.com/pypi/simple PS:95% 运行不成功的问题, 是在这步造成的         安装完成后 再执行 更新 默认安装的numpy版本太高。。 python -m pip install numpy==1.19.3 -i https://mirror.baidu.com/pypi/simple 四、目前PYTHON的识别比C++的高 另附上VC++的识别图 VC++版本因为太大(几个文件,无需安装,命令行取回显方式调用)和PYTHON识别库上传到BAIDU网盘中 链接: https://pan.baidu.com/s/1jC7wgx7hiQ-FsYluiIKukQ  提取码: gycx
### 回答1: 基于MATLAB的OCR(光学字符识别)主要用于识别文本或手写字符,不适用于指纹识别。指纹识别是一种生物特征识别技术,用于识别和比对人类指纹图像。它基于图像处理和模式识别算法,通过提取指纹图像中的特征细节,如纹线、纹谷和细节点,以建立一个独特的指纹特征向量。而MATLAB的OCR工具箱是用于处理和识别文本字符的工具,无法提取和比对指纹图像中的细节特征。要实现指纹识别,通常需要使用专门针对指纹特征的算法和库,如Minutiae算法或Fingerprint SDK等。这些算法能够对指纹图像进行分析和比对,以实现高精度的指纹识别。所以,基于MATLAB的OCR工具箱不能识别指纹,需要使用专门的指纹识别算法和库。 ### 回答2: 基于MATLAB的OCR(Optical Character Recognition, 光学字符识别)主要用于识别文字和数字,而不是指纹。 指纹识别属于生物识别技术,用于识别和验证个人身份。MATLAB提供了一些图像处理和模式识别的功能,可以用于指纹图像的处理和分析。但是,直接使用MATLAB的OCR工具箱无法识别指纹。 要实现指纹识别,一般需要通过专门的指纹识别算法和图像处理技术。这些算法和技术通常需要结合其他编程语言或专门的指纹识别库来实现。MATLAB可以作为一个辅助工具,用于指纹图像的预处理、特征提取和数据分析等方面。 总之,基于MATLAB的OCR工具箱主要用于文字和数字的识别,不能直接用于指纹识别。指纹识别通常需要使用专门的算法和库来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值