PaddleOCR学习笔记2-初步识别服务

news2025/1/22 18:53:38

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

采用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应用,测试结果如下:

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

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

相关文章

Activiti7工作流引擎:在线流程编辑器Activiti Modoler5.x

一&#xff1a;简介 有的时候我们的流程图需要业务人员自己绘制&#xff0c;然后使用自己绘制的流程图&#xff0c;此时就需要一个在线流程图编辑器需要集成到我们的web系统中。Activiti Modoler是Activiti官方推出的在线流程编辑器。 二&#xff1a;pom.xml <dependency…

tomcat安装、部署JSPGOU项目、Tomcat多实例

安装 官网找包 Apache Tomcat - Welcome! tomcat 8 准备运行环境 安装tomcat catalina.sh 服务脚本管理文件 server.xml 主配置文件 修改8009&#xff08;删除注释&#xff09; 启动tomcat 访问 为了避免每次进入绝对路径启动tomcat 法二&#xff1a; 三&#xff1a;部署…

SpringMvc增删改查

SpringMvc增删改查 一、前期准备二、逆向生成增删改查2.2.aspect切面层2.3.Mybatis generator逆向生成2.4.根据生成代码编写Biz层与实现类 三、controller层代码编写四、前台代码与分页代码五、案例测试 一、前期准备 1.2.导入pom.xml依赖 <?xml version"1.0" …

搭建自己的OCR服务,第三步:PPOCRLabel标注工具安装

一、安装说明 安装好了PaddleOCR后&#xff0c;还需要安装PPOCRLabel这个标注工具&#xff0c;想要自己训练模型的话&#xff0c;有个标注工具会起很大作用。 尤其是PPOCRLabel就是跟PaddleOCR配套的标注工具&#xff0c;同样是开源的。 在下载 PaddleOCR 整个源码中&#x…

Apache DolphinScheduler - 快速扩展 TaskPlugin 从入门到放弃

目前在大数据生态中&#xff0c;调度系统是不可或缺的一个重要组件。Apache DolphinScheduler 作为一个顶级的 Apache 项目&#xff0c;其稳定性和易用性也可以说是名列前茅的。而对于一个调度系统来说&#xff0c;能够支持的可调度的任务类型同样是一个非常重要的因素&#xf…

如何去除eclipse中default package

选择default package ,然后选择后面的 选择FILTER 选择 Empty开头的几个 点击ok&#xff0c;就可以去掉空的default package

sql:SQL优化知识点记录(十三)

&#xff08;1&#xff09;行锁理论 &#xff08;2&#xff09;CAP理论 二 、 C、 A、P的含义 借用一下维基百科CAP理论一文中关于C、A、P三者的定义。 &#xff08;3&#xff09;行锁案例讲解 MySql5.5以后数据库默认都是InnoDB存储引擎&#xff0c;事物的操作默认给你提交了…

Unity之3D物理导航系统

一 介绍 Unity自带寻路(导航)系统是unity官方自带的一种寻路系统。我们可以通过它来制作简单的寻路&#xff0c;比如可以制作点击某个位置&#xff0c;让角色自动的绕开障碍走到目标点的效果&#xff0c;比如可以制作敌人AI&#xff0c;让它可以通过NavMesh绕开障碍追击我方单…

l8-d9 UDP通信实现

一、函数接口扩展与UDP通信实现流程 1.write/read到send/recv 函数原型&#xff1a; ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t recv(int sockfd, void *buf, size_t len, int flags); 前三个参数同read/write一样&#xff1b; ssize_t rea…

景联文科技可为多模态语音翻译模型提供数据采集支持

8月22日Facebook的母公司Meta Platforms发布了一种能够翻译和转录数十种语言的人工智能模型——SeamlessM4T&#xff0c;可以在日常生活中或者商务交流中为用户提供更便捷的翻译和转录服务。 相较于传统的文本翻译&#xff0c;这项技术的最大区别在于它可以实现端到端的语音翻译…

对象的构造和析构

目录 构造函数和析构函数 构造函数的分类和调用 c默认构造的函数 浅拷贝和深拷贝 多个对象的构造和析构 初始化列表 类对象作为成员 构造函数和析构函数 对象的初始化和清理是两个非常重要的安全问题&#xff0c;一个对象或者变量没有初始时&#xff0c;对其使用后果是未…

Ae 效果:CC Star Burst

模拟/CC Star Burst Simulation/CC Star Burst CC Star Burst&#xff08;CC 星爆&#xff09;可以模拟星际穿越的效果&#xff0c;也可以像 CC Ball Action 效果模拟球体的扩散运动。 CC Star Burst 效果的原理是将图层网格化&#xff0c;然后基于每个网格里的图层内容取平均颜…

【东软实训Day2】用Java实现客户端与服务器交互

一、客户端-服务器编程模型 1个应用 1个服务器进程 1…N个客户端进程&#xff0c;其中服务器管理资源&#xff0c;并通过操作这种资源为客户端服务。 客户端-服务器模型中的基本操作是事务&#xff08;transaction&#xff09;&#xff08;注&#xff1a;不同于数据库中的t…

软考-高级-信息系统项目管理第四版(完整24章全笔记)

《信息系统项目管理师教程》&#xff08;第4版&#xff09;是由全国计算机专业技术资格考试办公室组织编写的考试用书&#xff0c;根据2022年审定通过的《信息系统项目管理师考试大纲》编写&#xff0c;对信息系统项目管理师岗位所要求的主要知识及应用技术进行了阐述。 《信息…

ubuntu 20.04 通过 samba 共享文件夹到 windows

前言 ubuntu 与 windows 共享&#xff0c;有两条路&#xff0c;一是 windows 的目录共享给 ubuntu&#xff0c;比如使用 VM Ware 虚拟机&#xff0c;直接通过 VMWare 虚拟机共享文件夹的方式&#xff0c;windows 上的目录就共享给了 ubuntu ubuntu 如何把目录共享给 windows 呢…

zemax坐标断点实现光束偏移

简单来说就是将前面的坐标打断&#xff0c;实现新的坐标设置 基础设置&#xff1a; 对表面进行旋转&#xff1a; 系统自动插入坐标断点面 此时设置的旋转角度为0&#xff0c;我们将这个设置为变量&#xff1a; 在评价函数编辑器中选择REAY&#xff0c;控制光线高度 执行优化&a…

指针-矩阵变换

任务描述 给定一个矩阵&#xff0c;请编程将其按照以下约定的操作方式变换后输出。 相关知识 参考之前的关卡。 编程要求 根据提示&#xff0c;在右侧编辑器的Begin-End区域内补充代码。 测试说明 输入&#xff1a;第一行三个正整数 n&#xff0c;m 和 q 分别表示矩阵 A…

时间旅行的Bug 奇怪的输入Bug

故事一&#xff1a;时间旅行的Bug 在一个普通的工作日&#xff0c;程序员小明正在开发一个时间旅行的应用程序。这个应用程序可以让用户选择一个特定的日期和时间&#xff0c;然后将用户的意识传送到过去或未来的那个时刻。小明对这个项目非常兴奋&#xff0c;他认为这将是一个…

2023年9月8日

1> 自行封装一个栈的类&#xff0c;包含私有成员属性&#xff1a;栈的数组、记录栈顶的变量 成员函数完成&#xff1a;构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 #include <iostream>using namespace std;class…

使用docker创建minio镜像并上传文件,提供demo

使用docker创建minio镜像并上传文件&#xff0c;提供demo 1. 整体描述2. 环境搭建2.1 windows环境搭建2.2 docker部署 3. spring集成3.1 添加依赖3.2 配置文件3.3 创建config类3.4 创建minio操作类3.5 创建启动类3.6 测试controller 4. 测试操作4.1 demo运行4.2 页面查看4.3 上…