今天初步实现了网页,上传图片,识别显示结果到页面的服务。后续再完善。

采用flask + paddleocr+ bootstrap快速搭建OCR识别服务。

代码结构如下:

模板页面代码文件如下:

upload.html :

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>PandaCodeOCR</title>
<!--静态加载 样式-->
<link rel="stylesheet" href={{ url_for('static',filename='bootstrap3/css/bootstrap.min.css') }}></link>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.header {
background-color: #f0f0f0;
text-align: center;
padding: 20px;
}
.title {
font-size: 32px;
margin-bottom: 10px;
} .menu {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #FFDEAD;
border: 2px solid #DCDCDC;
} .menu li {
float: left;
font-size: 24px;
} .menu li a {
display: block;
color: #333;
text-align: center;
padding: 14px 16px;
text-decoration: none;
} .menu li a:hover {
background-color: #ddd;
} .content {
padding: 20px;
border: 2px solid blue;
}
</style>
</head>
<body>
<div class="header">
<div class="title">PandaCodeOCR</div>
</div> <ul class="menu">
<li><a href="http://localhost:5000/uploader">通用文本识别</a></li>
</ul> <div class="content">
<!--上传图片文件-->
<div id="upload_file">
<form action="http://localhost:5000/uploader" method="POST" enctype="multipart/form-data">
<div class="form-group">
<input type="file" class="form-control" id="upload_file" name="upload_file" placeholder="upload_file">
</div>
<div class="form-group">
<button type="submit" class="form-control btn-primary">上传图片文件</button>
</div>
</form>
</div>
</div>
</body>
</html>

result.html :

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>结果</title>
<!--静态加载 样式-->
<link rel="stylesheet" href={{ url_for('static',filename='bootstrap3/css/bootstrap.min.css') }}></link>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.header {
background-color: #f0f0f0;
text-align: center;
padding: 20px;
}
.title {
font-size: 32px;
margin-bottom: 10px;
} .menu {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #FFDEAD;
border: 2px solid #DCDCDC;
} .menu li {
float: left;
font-size: 24px;
} .menu li a {
display: block;
color: #333;
text-align: center;
padding: 14px 16px;
text-decoration: none;
} .menu li a:hover {
background-color: #ddd;
}
</style>
</head>
<body>
<div class="header">
<div class="title">PandaCodeOCR</div>
</div> <ul class="menu">
<li><a href="http://localhost:5000/uploader">通用文本识别</a></li>
</ul> <div class="row">
<!--显示上传的图片-->
<div class="col-md-6" style="border: 2px solid #ddd;">
<span class="label label-info">上传图片</span>
<!--静态加载 图片-->
<img src="{{ url_for('static', filename = result_dict['filename'])}}" alt="show_img" class="img-responsive">
</div> <div class="col-md-6" style="border: 2px solid #ddd;">
<!--显示识别结果JSON报文列表-->
<span class="label label-info">识别结果:</span>
{% for line_str in result_dict['result'] %}
<p class="text-left">{{ line_str['text'] }}</p>
{% endfor %}
</div>
</div>
</body>
</html>
<!--静态加载 script-->
<script src={{ url_for('static',filename='jquery1.3.3/jquery.min.js')}}></script>

  

主要视图代码文件如下:

views.py :
import json
import os
import time from . import blue_task
from flask import Flask, render_template, request from paddleocr import PaddleOCR
from PIL import Image,ImageDraw
import numpy as np '''
自定义模型测试ocr方法
''' def test_model_ocr(img):
# 返回字典结果对象
result_dict = {'result': []}
# paddleocr 目前支持的多语言语种可以通过修改lang参数进行切换
# 例如`ch`, `en`, `fr`, `german`, `korean`, `japan`
# 使用CPU预加载,不用GPU
# 模型路径下必须包含model和params文件,目前开源的v3版本模型 已经是识别率很高的了
# 还要更好的就要自己训练模型了。
ocr = PaddleOCR(det_model_dir='./inference/ch_PP-OCRv3_det_infer/',
rec_model_dir='./inference/ch_PP-OCRv3_rec_infer/',
cls_model_dir='./inference/ch_ppocr_mobile_v2.0_cls_infer/',
use_angle_cls=True, lang="ch", use_gpu=False)
# 识别图片文件
result0 = ocr.ocr(img, cls=True)
result = result0[0]
for index in range(len(result)):
line = result[index] tmp_dict = {}
points = line[0]
text = line[1][0]
score = line[1][1]
tmp_dict['points'] = points
tmp_dict['text'] = text
tmp_dict['score'] = score result_dict['result'].append(tmp_dict)
return result_dict # 转换图片
def convert_image(image, threshold=None):
# 阈值 控制二值化程度,不能超过256,[200, 256]
# 适当调大阈值,可以提高文本识别率,经过测试有效。
if threshold is None:
threshold = 200
print('threshold : ', threshold)
# 首先进行图片灰度处理
image = image.convert("L")
pixels = image.load()
# 在进行二值化
for x in range(image.width):
for y in range(image.height):
if pixels[x, y] > threshold:
pixels[x, y] = 255
else:
pixels[x, y] = 0
return image @blue_task.route('/upload')
def upload_file():
return render_template('upload.html') @blue_task.route('/uploader', methods=['GET', 'POST'])
def uploader():
if request.method == 'POST':
#每个上传的文件首先会保存在服务器上的临时位置,然后将其实际保存到它的最终位置。
filedata = request.files['upload_file']
upload_filename = filedata.filename
print(upload_filename)
#保存文件到指定路径
#目标文件的名称可以是硬编码的,也可以从 ​request.files[file] ​对象的​ filename ​属性中获取。
#但是,建议使用 ​secure_filename()​ 函数获取它的安全版本
img_path = os.path.join('upload/', upload_filename)
filedata.save(img_path)
print('file uploaded successfully') start = time.time() print('=======开始OCR识别======')
# 打开图片
img1 = Image.open(img_path)
# 转换图片, 识别图片文本
# print('转换图片,阈值=220时,再转换为ndarray数组, 识别图片文本')
# 转换图片
img2 = convert_image(img1, 220)
# Image图像转换为ndarray数组
img_2 = np.array(img2)
# 识别图片
result_dict = test_model_ocr(img_2) # 识别时间
end = time.time()
recognize_time = int((end - start) * 1000) result_dict["filename"] = img_path
result_dict["recognize_time"] = str(recognize_time)
result_dict["error_code"] = "000000"
result_dict["error_msg"] = "识别成功" # return json.dumps(result_dict, ensure_ascii=False), {'Content-Type': 'application/json'}
# render_template方法:渲染模板
# 参数1: 模板名称 参数n: 传到模板里的数据
return render_template('result.html', result_dict=result_dict)
else:
return render_template('upload.html')

启动flask应用,测试结果如下:

PaddleOCR学习笔记2-初步识别服务的更多相关文章

  1. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

  2. 学习笔记TF058:人脸识别

    人脸识别,基于人脸部特征信息识别身份的生物识别技术.摄像机.摄像头采集人脸图像或视频流,自动检测.跟踪图像中人脸,做脸部相关技术处理,人脸检测.人脸关键点检测.人脸验证等.<麻省理工科技评论&g ...

  3. Binder学习笔记(九)—— 服务端如何响应Test()请求 ?

    从服务端代码出发,TestServer.cpp int main() { sp < ProcessState > proc(ProcessState::self()); sp < I ...

  4. 10月9日Android学习笔记:活动与服务之间的通信

    最近在照着<第一行代码>这本书来学安卓,顺便记下笔记.主要的内容是Android中服务的第二种启动方式,通过活动绑定服务来启动服务,实现活动与服务之间的通信. 一. 首先创建一个服务类 p ...

  5. Netty4 学习笔记之一:客户端与服务端通信 demo

    前言 因为以前在项目中使用过Mina框架,感受到了该框架的强大之处.于是在业余时间也学习了一下Netty.因为Netty的主要版本是Netty3和Netty4(Netty5已经被取消了),所以我就直接 ...

  6. Netty4 学习笔记之四: Netty HTTP服务的实现

    前言 目前主流的JAVA web 的HTTP服务主要是 springMVC和Struts2,更早的有JSP/servlet. 在学习Netty的时候,发现Netty 也可以作HTTP服务,于是便将此整 ...

  7. Docker学习笔记 - Docker客户端和服务端

    学习内容: Docker客户端和服务端的通讯方式:client和自定义程序 Docker客户端和服务端的连接方式:socket 演示Docker客户端和服务端之间用remote-api通讯:nc   ...

  8. Webpack4 学习笔记七 跨域服务代理

    webpack 小插件使用 webpack 监听文件变化配置 webpack 处理跨域问题 Webpack 小插件使用 clean-webpack-plugin: 用于在生成之前删除生成文件夹的Web ...

  9. iOS学习笔记06-手势识别

    一.UIGestureRecognizer简单介绍 我们已经学习了触摸事件处理,但触摸事件处理起来很麻烦,每个触摸事件处理都需要实现3个touches方法,比较繁琐,实际上我们可以使用更加简单的触摸事 ...

  10. FastSocket学习笔记~再说客户端与服务端的组成

    废话多说 很久之前,我写过几篇FastSocket的文章,基本属于使用的方法,而缺乏对概念的总结讲解,而本讲就是弥补一下上几讲的不足,将核心的模块再说说,再谈谈,再聊聊! 首先FastSocket由C ...

随机推荐

  1. Eclipse生成javadoc方法与错误解决

    1.Eclipse生成javadoc方法与错误解决 2.Eclipse自动生成文件注释以及使用javadoc命令自动生成API文档 3.maven配置生成java doc文档中文乱码问题解决方案 4. ...

  2. JVM实战—6.频繁YGC和频繁FGC的后果

    大纲 1.JVM GC导致系统突然卡死无法访问 2.什么是Young GC什么是Full GC 3.Young GC.Old GC和Full GC的发生情况 4.频繁YGC的案例(G1解决大内存YGC ...

  3. gRPC编译与字段编号的细节探讨

    上次我们专门通过一个简单的HelloWorld示例来了解了gRPC的基本概念和使用方法.今天,我们将继续深入探讨gRPC,重点讨论一些在实际应用中需要特别注意的要点.实际上,gRPC的核心目标是简化远 ...

  4. 使用GPIO判断网线拔插

    USB网卡和以太网交换机"常连"后,增加交换机插拔网线判断机制 这个项目已经做了小半年了,客户是一个做智能电话机的.所谓的智能电话就是一台可以插网线.电话线,外观却是座机的手机. ...

  5. map循环如何跳出循环

    今天在开发的时候遇到了一个问题.就是想在使用map的时候跳出循环无法实现,于是就在网上搜寻了一番,说map本身不能跳出循环,有一个大佬提出了抛出异常的方法,记录一下 let list=[1,2,3,4 ...

  6. WxPython跨平台开发框架之使用PyInstaller 进行打包处理

    使用PyInstaller 打包Python项目是一个常见的需求,它可以将Python程序及其所有依赖项打包成一个独立的可执行文件或者安装文件,方便在没有安装Python环境的机器上运行.本随笔介绍W ...

  7. 深入解析 Spring AI 系列:解析OpenAI接口对接

    今天我们将主要探讨OpenAI是如何进行接口对接的,虽然我们不打算深入细节,但会对整体流程进行一个大概的了解.后续会逐步分析其中的具体细节,大家可以耐心等待,逐步展开.好的,现在让我们开始,下面是我简 ...

  8. SpringBoot整合Netty+WebSocket

    SpringBoot整合Netty+WebSocket 构建环境 pom.xml <?xml version="1.0" encoding="UTF-8" ...

  9. 分布式文件系统KFS基础知识介绍

    Kosmos distributed file system,简称KFS,是一个类GFS的分布式文件系统,被设计用于分布式的结构化存储.下面将对KFS的体系结构进行简单介绍,最后给出一个使用KFS C ...

  10. 深入解析 Spring AI 系列:解析请求参数处理

    大家在使用Spring AI项目开发Agent时,可能会发现,尽管外层的接口设计和调用逻辑比较统一,但实际上每个第三方接口在实现时都会有一些微妙的差异.这些差异可能体现在请求参数的构造.数据格式的处理 ...