【ocr识别003】flask+paddleocr+bootstrap搭建OCR文本推理WEB服务

news2024/12/23 15:45:28

1.欢迎点赞、关注、批评、指正,互三走起来,小手动起来!
2.了解、学习OCR相关技术知识领域,结合日常的场景进行测试、总结。如本文总结的flask+paddleocr+bootstrap搭建OCR文本推理WEB服务应用示例场景。

文章目录

    • 1.代码结构
    • 2.效果演示
    • 3.接口返回
    • 4.代码详情
      • 4.1 `HTML`代码详情
      • 4.2`Python`代码详情
    • 5.后续展望

1.代码结构

  • 如下图所示:
    在这里插入图片描述

2.效果演示

  • 详情如下:
    在这里插入图片描述

3.接口返回

  • 接口测试效果图
    在这里插入图片描述

  • 返回结果详情部分示例

    {
        "error_code": "000000",
        "error_msg": "识别成功",
        "filename": "cstp2.png",
        "recognize_time": "5890",
        "result": [
            {
                "points": [
                    [
                        14.0,
                        11.0
                    ],
                    [
                        108.0,
                        11.0
                    ],
                    [
                        108.0,
                        40.0
                    ],
                    [
                        14.0,
                        40.0
                    ]
                ],
                "score": 0.979973316192627,
                "text": "性别:男"
            },
            {
                "points": [
                    [
                        289.0,
                        11.0
                    ],
                    [
                        400.0,
                        9.0
                    ],
                    [
                        401.0,
                        37.0
                    ],
                    [
                        290.0,
                        39.0
                    ]
                ],
                "score": 0.8993546962738037,
                "text": "住院号:"
            },
            {
                "points": [
                    [
                        677.0,
                        2.0
                    ],
                    [
                        713.0,
                        12.0
                    ],
                    [
                        707.0,
                        31.0
                    ],
                    [
                        672.0,
                        21.0
                    ]
                ],
                "score": 0.6370271444320679,
                "text": "贝别:"
            }
        ]
    }
    

4.代码详情

4.1 HTML代码详情

  • <!DOCTYPE html>
    <html>
    <meta charset="utf-8">
    <head>
        <title>OCR文字检测识别试运行系统</title>
        <!--静态加载 样式-->
        <link rel="stylesheet" href={{ url_for('static',filename='bootstrap-3.4.1/css/bootstrap.min.css') }}></link>
        <link rel="stylesheet" href={{ url_for('static',filename='css/upload.css') }}></link>
        <link rel="stylesheet" href={{ url_for('static',filename='css/36buttons.css') }}></link>
    </head>
    <body>
    <div class="header">
        <div class="title">【OCR】PP-OCRv3 文字检测识别试运行系统v0.3.0</div>
    </div>
    
    <ul class="menu">
        <li><a href="/upload/">通用文本检测识别处理</a></li>
    </ul>
    
    <div class="content">
        <!--上传图片文件-->
        <div id="upload_file">
            <form id="fileForm" action="/upload/" method="POST" enctype="multipart/form-data">
                <div class="form-group">
                    <input type="file" class="form-control" id="_upload_file" name="upload_file">
    <!--                <label class="sr-only" for="upload_file">上传图片</label>-->
                    </br>
                    <button id="resetButton" name="resetButton" type="reset" class="button green">重置推理结果</button>
                </div>
            </form>
        </div>
    </div>
    </div>
    
    <div id="show" style="display: none;">
        <!--显示上传的图片-->
        <div class="col-md-6" style="border: 2px solid #ddd;">
            </br>
            <span class="label label-info" style="font-size: 24px;"><<<<<< 原始图片展示 >>>>>> </br></span>
            <!--静态加载 图片, url_for() 动态生成路径 -->
            </br>
            <img id="src_pic_show" src="" alt="Image preview area..." title="preview-img" class="img-responsive">
        </div>
        <div class="col-md-6" style="border: 2px solid #ddd;">
            <!--显示识别结果JSON报文列表-->
            </br>
            <span class="label label-info" style="font-size: 24px;"><<<<<< 推理结果详情 >>>>>> </br></span>
            </br>
            <!-- 结果显示区 -->
            <div id="result_show" style="font-size: 28px;">客官,您提交的任务加急推理中......</div>
        </div>
    </div>
    </body>
    </html>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="http://malsup.github.io/jquery.form.js"></script>
    
    <script type="text/javascript">
        var fileInput = document.querySelector('input[type=file]');
        var previewImg = document.querySelector('img');
    
        {#上传图片事件#}
        fileInput.addEventListener('change', function () {
            var file = this.files;
            var reader = new FileReader();
    
            //显示预览界面
            $("#show").css("display", "block");
    
            // 监听reader对象的的onload事件,当图片加载完成时,把base64编码賦值给预览图片
            reader.addEventListener("load", function () {
                previewImg.src = reader.result;
            }, false);
    
            // 调用reader.readAsDataURL()方法,把图片转成base64
            reader.readAsDataURL(file);
    
            //初始化输出结果信息
            $("#result_show").html("</br>客官,您提交的任务加急推理中......");
    
            {#上传图片识别表单事件,并显示识别结果信息#}
            {# ajaxSubmit 请求异步响应#}
    
            $("#fileForm").ajaxSubmit(function (data) {
                var inner = '<table border="1"> <thead> <tr> <th>序号</th> <th>文本目标</th> <th>置信度分数</th> </tr> </thead> <tbody>';
                //循环输出返回结果,响应识别结果为每行列表
                var inc = 1;
                for (var i in data['result']) {
                    var text = data['result'][i]['text'];
                    var score = data['result'][i]['score'];
                    inner += "<tr><td>" + inc + "</td>" + "<td>" + text + "</td>" + "<td>" + score + "</td></tr>";
                    inc += 1;
                }
                inner += '</tbody></table>'
                //清空输出结果信息
                $("#result_show").html("");
    
                //添加识别结果信息
                $("#show").append( inner );
            });
        }, false);
    
        document.getElementById('resetButton').addEventListener('click', function() {
            document.getElementById('src_pic_show').src = '';
            $('#result_show').empty();
        });
    </script>
    

4.2Python代码详情

  • 源代码
    import json
    import os
    import time
    import numpy as np
    import pandas as pd
    from pyautogui import *
    from paddleocr import PaddleOCR
    from PIL import Image, ImageDraw
    from flask import Flask, render_template, request, jsonify
    # 应用名称,当前py名称,视图函数
    app = Flask(__name__)
    # 相对路径
    BASE_DIR = os.path.dirname(os.path.basename(__name__))
    
    # 上传文件路径
    UPLOAD_DIR = os.path.join(os.path.join(BASE_DIR, 'static'), 'upload')
    
    def ocr_img2text( image ):
        result_dict = {'result': []}
        paddleocr = 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=True)
        if image == "":
            image = screenshot()  # 使用pyautogui进行截图操作
            image = np.array(image)
        else:
            # 不为空就打开
            image = Image.open(image).convert('RGB')
            image = np.array(image)  # 经提醒,需要添加array
    
        print( image, type(image) )
        # 识别图片文件
        result0 = paddleocr.ocr( image, cls=True )
        result = result0[0]
    
        # for line in result0:
        #     for word in line:
        #         print( word )
    
        for index in range(len(result)):
            line = result[index]
            p_dict = {}
            points = line[1]
            text = line[1][0]
            score = line[1][1]
            p_dict['points'] = points
            p_dict['text'] = text
            p_dict['score'] = score
            result_dict['result'].append( p_dict )
        return result_dict
    
    @app.route('/')
    def upload_file():
        return render_template('upload.html')
    
    @app.route('/upload/', methods=['GET', 'POST'])
    def upload():
        if request.method == 'POST':
            # 每个上传的文件首先会保存在服务器上的临时位置,然后将其实际保存到它的最终位置。
            filedata = request.files['upload_file']
            upload_filename = filedata.filename
            print(upload_filename)
            # 保存文件到指定路径
            # 目标文件的名称可以是硬编码的,也可以从 ​request.files[file] ​对象的​ filename ​属性中获取。
            # 但是,建议使用 ​secure_filename()​ 函数获取它的安全版本
            if not os.path.exists(UPLOAD_DIR):
                os.makedirs(UPLOAD_DIR)
            img_path = os.path.join(UPLOAD_DIR, upload_filename)
            filedata.save(img_path)
            start = time.time()
            # 打开图片
            img1 = Image.open(img_path)
            # 识别图片
            result_dict = ocr_img2text(img_path)
    
            # 识别时间
            end = time.time()
            recognize_time = int((end - start) * 1000)
    
            result_dict["filename"] = upload_filename
            result_dict["recognize_time"] = str(recognize_time)
            result_dict["error_code"] = "000000"
            result_dict["error_msg"] = "识别成功"
            return jsonify(result_dict)
        else:
            return render_template('upload.html')
    

5.后续展望

  • 持续改进优化该部分代码,并完善文档。欢迎交流。。。
  • https://www.cnblogs.com/xh2023/p/17642994.html

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

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

相关文章

【算法】梯度下降

一、引言 梯度下降算法&#xff08;Gradient Descent&#xff09;是一种一阶迭代优化算法&#xff0c;用于求解最小化目标函数的问题&#xff0c;广泛应用于机器学习和人工智能中的参数优化。 用于优化问题的迭代算法&#xff0c;尤其在机器学习和深度学习中广泛用于最小化损失…

EMQX Platform Snowflake:构建可再生分布式能源的智慧未来

引言 可再生能源如风力和太阳能发电&#xff0c;具有低成本和环保的特性&#xff0c;是未来能源供应的主要方向。然而&#xff0c;这类发电方式存在供应分散、设备数量多、地区分布广等特点。再加上不同地区的季节和天气变化&#xff0c;不确定性极大。 随着社会用电需求的持…

11 Radiobutton组件

11 Radiobutton组件 Tkinter 是 Python 的标准图形用户界面库&#xff0c;它提供了一个 Radiobutton 控件&#xff0c;用于在一组选项中让用户选择一个选项。Radiobutton 通常用于提供一组互斥的选项&#xff0c;用户只能选择其中一个。 Radiobutton 组件基础 Radiobutton 控…

CMake详解-捡重要的讲

CMake 通常我们使用cmake构建C++项目,其实就是编写CMakeLists.txt文件,过程如下 首先在创建项目名称,我这里是CMake文件夹,在路径下创建CMakeLists.txt文件,也就是在工作空间的目录下创建,具体有几个要素要设置 CMake最低版本要求项目名称-自定义即可编译方法:Debug或…

html+css+js网页制作 自定义电商10个页面

htmlcssjs网页制作 自定义电商10个页面 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#…

前端面试题整理-Javascript

JS组成&#xff1a; JS是运行在浏览器的一门编程语言 函数类型&#xff1a; 1. 说说 js 都有哪些数据类型&#xff0c;他们在内存存储上有什么不同 基本数据类型&#xff1a;number、boolean、string、null&#xff08;null就是特殊的object&#xff09;、undefined、Symbo…

循环神经网络三

一.介绍 在普通的神经网络中&#xff0c;信息的传递是单向的&#xff0c;这种限制虽然使得网络变得更容易学习&#xff0c;单在一定程度上也减弱了神经网络模型的能力。特别是在现实生活中&#xff0c;网络的输出不仅和当前时刻的输入相关&#xff0c;也过去一段时间的输出相关…

keepalived搭建与基础配置

目录 1 keepalived部署与环境准备 1.1 Keepalived 实验环境准备 1.2 Keepalived 相关文件 1.3 Keepalived 安装 1.4 KeepAlived 配置说明 1.5 配置语法说明 2 企业应用示例与配置 2.1 主从架构 2.1.1 启用keepalived日志功能 2.1.2 vrrp_iptables 参数 2.1.3 实现独立子配置文件…

python实现模型训练期间定时查询解析GPU资源详细信息,根据实际显存占用量动态启动新模型训练任务

经常要做模型开发训练的人一定对于GPU的查询不会陌生&#xff0c;实例如下&#xff1a; 详情数据如下&#xff1a; Tue Aug 13 16:42:31 2024 ----------------------------------------------------------------------------- | NVIDIA-SMI 450.80.02 Driver Versi…

oracle普通导出导入

原始的普通导出导入工具&#xff0c;是一个客户端工具。使用导出工具&#xff08;export utility简称exp&#xff09;是将数据从oracle数据库以二进制形式写入操作系统文件&#xff0c;这个文件存储在数据库之外&#xff0c;并且可以被另一个数据库使用导入工具&#xff08;imp…

大数据系列之:Flink Doris Connector,实时同步数据到Doris数据库

大数据系列之&#xff1a;Flink Doris Connector&#xff0c;实时同步数据到Doris数据库 一、版本兼容性二、使用三、Flink SQL四、DataStream五、Lookup Join六、配置通用配置项接收器配置项查找Join配置项 七、Doris 和 Flink 列类型映射八、使用Flink CDC访问Doris的示例九、…

Unity协程WaitForSeconds在编辑器和WebGL表现不同问题的解决方法参考

最近做的一个效果让下面为了让下面这种图片生成一个翻页效果&#xff08;使用ShaderGraph中的FlipBook节点&#xff09;&#xff0c;我通过携程来实现连续翻页。 先是定义一个Coroutine coroutine null&#xff1b; 然后在一定情况下执行coroutine StartCoroutine(KeepPrevie…

Spring入门讲解

这里写目录标题 Spring基础概念关键重点主要特性主要优势Spring与Java EE的对比Spring生态系统概述总结 Spring 基础概念 Spring是一个开源的轻量级Java开发框架&#xff0c;它提供了全面的基础设施支持&#xff0c;简化了企业级应用的开发和部署。Spring的核心理念是依赖注入…

基于华为atlas下的yolov5+BoT-SORT/ByteTrack煤矿箕斗状态识别大探索

写在前面&#xff1a; 本项目的代码原型基于yolov5yolov8。其中检测模型使用的yolov5&#xff0c;跟踪模型使用的yolov8。 这里说明以下&#xff0c;为什么不整体都选择yolov8呢&#xff0c;v8无疑是比v5优秀的&#xff0c;但是atlas这块经过不断尝试没有过去&#xff0c;所以…

前端进行分页Vue3+Setup写法

当后端不方便提供数据分页查询接口时&#xff0c;就需要前端来自己分割进行分页操作 在有可能的情况下还是建议用分页查询接口&#xff0c;减少网络数据传输 首先el-table绑定数组 分页组件&#xff0c;变量自己定义防止报错 <el-paginationlayout"->, total, siz…

Springboot实现doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频在线预览功能,你学“废”了吗?

最近工作中&#xff0c;客户需要生成包含动态内容的word/pdf报告&#xff0c;并且需要在线预览。 刚开始使用后台直接生成word文档&#xff0c;返回文件流给前端&#xff0c;浏览器预览会发生格式错乱问题&#xff0c;特别是文档中的图片有些还不显示。 想到最简单的办法就是…

在原生未启用kdump的BCLinux 8系列服务器上启用kdump及报错处理

本文记录了在原生未启用kdump的BCLinux 8系列操作系统的服务器上手动启用kdump服务及报错处理的过程。 一、问题描述 BCLinux 8系列操作系统&#xff0c;系统初始化安装时未启用kdump服务&#xff0c;手动启动时报以下“No memory reserved for crash kernel”或“ConditionK…

数学建模——评价决策类算法(层次分析法、Topsis)

一、层次分析法 概念原理 通过相互比较确定各准则对于目标的权重, 及各方案对于每一准则的权重&#xff0c;这些权重在人的思维过程中通常是定性的, 而在层次分析法中则要给出得到权重的定量方法. 将方案层对准则层的权重及准则层对目标层的权重进行综合, 最终确定方案层对目标…

解读RPA自动化流程机器人

RPA全称Robotic Process Automation&#xff0c;即机器人流程自动化&#xff0c;基于人工智能和自动化技术&#xff0c;能够将大量重复、规则明确的日常事务操作实现自动化处理&#xff0c;通常被形象地称为“数字员工”。本文金智维将深入探讨RPA的主要价值和应用领域&#xf…

除悟空CRM外,主流的6大CRM私有部署的厂商

支持私有化部署的CRM有&#xff1a;1.纷享销客&#xff1b; 2.悟空CRM&#xff1b; 3.销售易&#xff1b; 4.有赞CRM&#xff1b; 5.知客CRM&#xff1b; 6.八骏CRM&#xff1b; 7.白码CRM。 面对日益复杂的网络环境和严峻的数据保护法规&#xff0c;私有化部署的CRM系统成为了…