PaddleOCR学习笔记2-初步识别服务
今天初步实现了网页,上传图片,识别显示结果到页面的服务。后续再完善。
采用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 timefrom . import blue_task
from flask import Flask, render_template, requestfrom 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'] = pointstmp_dict['text'] = texttmp_dict['score'] = scoreresult_dict['result'].append(tmp_dict)return result_dict# 转换图片
def convert_image(image, threshold=None):# 阈值 控制二值化程度,不能超过256,[200, 256]# 适当调大阈值,可以提高文本识别率,经过测试有效。if threshold is None:threshold = 200print('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] = 255else:pixels[x, y] = 0return 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.filenameprint(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_pathresult_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-初步识别服务
今天初步实现了网页,上传图片,识别显示结果到页面的服务。后续再完善。 采用flask paddleocr bootstrap快速搭建OCR识别服务。 代码结构如下: 模板页面代码文件如下: upload.html : <!DOCTYPE html> <html> <…...
【Opencv】Pyhton 播放上一帧,下一帧,存video,逐帧分析
文章目录 读取具体哪一帧等待按钮写入解码方式与文件格式对应全部代码 读取具体哪一帧 这个方法可以获取某一帧: while True:cap.set(cv2.CAP_PROP_POS_FRAMES, current_frame)ret, frame cap.read()if not ret:break等待按钮 这个方法可以显示当前帧,…...
【关于Java:认识异常】
文章目录 一、1. 异常概念与体系结构1.1 异常的概念1.2 常见的异常1.算数异常2.数组越界异常3.空指针异常 1.3 异常的体系结构1.4 异常的分类1. 编译时异常2. 运行时异常(RuntimeException) 二、 异常的处理方式2.1 防御式编程2.2 EAFP:(异常…...
【C++ • STL • 力扣】详解string相关OJ
文章目录 1、仅仅翻转字母2、字符串中的第一个唯一字符3、字符串里最后一个单词的长度4、验证一个字符串是否是回文5、字符串相加总结 ヾ(๑╹◡╹)ノ" 人总要为过去的懒惰而付出代价 ヾ(๑╹◡╹)ノ" 1、仅仅翻转字母 力扣链接 代码1展示&…...
【Tomcat服务部署及优化】
Tomcat 一、什么是Tomcat?二、Tomcat 核心组件2.1 Tomcat 组件2.3 Container组件的结构2.4 Tomcat 请求过程 三、Tomcat 部署3.1 安装JDK3.2 设置JDK环境变量3.3 安装Tomcat并用supervisor启动解压添加到supervisord服务测试能否通过supervisorctl启动 四、Tomcat的端口和主要…...
C++之红黑树
红黑树 红黑树的概念红黑树的性质红黑树结点的定义红黑树的插入红黑树的验证红黑树与AVL树的比较 红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上…...
Go语言网络编程(socket编程)TCP
1、TCP编程 1.1.1 Go语言实现TCP通信 TCP协议 TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协…...
C语言——局部和全局变量
局部变量 定义在函数内部的变量称为局部变量(Local Variable) 局部变量的作用域(作用范围)仅限于函数内部, 离开该函数后是无效的 离开该函数后,局部变量自动释放 示例代码: #include <stdio.h>// 函数定义 …...
【Java基础篇 | 类和对象】--- 聊聊什么是内部类
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 本专栏旨在分享学习Java的一点学习心得,欢迎大家在评论区讨论💌 前言 当一个事物的内部&…...
合宙Air724UG LuatOS-Air LVGL API控件-页面 (Page)
页面 (Page) 当控件内容过多,无法在屏幕内完整显示时,可让其在 页面 内显示。 示例代码 page lvgl.page_create(lvgl.scr_act(), nil) lvgl.obj_set_size(page, 150, 200) lvgl.obj_align(page, nil, lvgl.ALIGN_CENTER, 0, 0)label lvgl.label_crea…...
mongodb数据库操作
1、启动mongodb /usr/local/mongodb/bin/mongod --dbpath /var/mongodb/data/--logpath /var/mongodb/logs/log.log &在mongodb启动命令中 --dbpath 指定mongodb的数据存储路径 --logpath 指定mongodb的日志存储路径 2、停止mongodb 第一步先进入mongo命令行模式 第二…...
第 2 章 线性表 ( 双链循环线性表(链式存储结构)实现)
1. 背景说明 2. 示例代码 1) status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H#define CHECK_NULL(pointer) if (!(pointer)) { \printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR…...
redis在日常开发工作中的常见用法
redis是一款内存型数据库,在开发工作中经常用到,功能强大; 特别开一篇文章用来记录一下它的常见用法,算是一种总结; 它最主要的特点就是高可用的,速度快,分布式;有人说速度快&…...
小程序实现下拉刷新
小程序实现下拉刷新可以通过使用组件scroll-view和事件onPullDownRefresh来实现。 scroll-view组件的使用 在需要下拉刷新的页面的wxml文件中,通过scroll-view组件包裹需要滚动的内容,设置scroll-y属性为true,表示允许竖向滚动。示例代码如…...
Day 36 贪心算法 part05 : 435. 无重叠区间 763.划分字母区间 56. 合并区间
56. 合并区间 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例 1: 输入:inte…...
使用Python将网页数据保存到NoSQL数据库的方法和示例
随着大数据和人工智能技术的快速发展,对于大规模数据的处理需求日益增多。NoSQL数据库作为一种新兴的数据存储解决方案,具有高可扩展性、高性能和灵活性数据模型等优势,已经在许多行业得到广泛应用。传统的关系型数据库在处理海量数据时可能会…...
两个路由器如何连接设置的方法攻略
一、前言 随着智能家居时代来临,家里的网络部署需求开始复杂起来。往往一个路由器已经不能满足需求或者不利于拓展。两个路由器连接最常见的情况是家中已有一个路由器,并且已经通过这个路由器来正常上网。现在是因某些原因想在不改变已经在用的路由器的设…...
分类任务评价指标
分类任务评价指标 分类任务中,有以下几个常用指标: 混淆矩阵准确率(Accuracy)精确率(查准率,Precision)召回率(查全率,Recall)F-scorePR曲线ROC曲线 1. 混…...
c++静态成员
目录 静态成员 静态成员变量 静态成员函数 const 静态成员属性 静态成员实现单例模式 静态成员 在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字 static 声明为静态的,称为静态成员。 不管这…...
go-zero直连与etcd服务注册中心
go-zero中直连方式 在使用grpc是最重要的就是pb文件了,生成的pb文件,通过pb文件可以生成grpc的客户端和服务端,那么客户端和服务端就可以直连了,再次基础上可以引入etcd实现服务注册。 所有的代码都需要开发者编写,包…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
