算力卡上部署OCR文本识别服务与测试

使用modelscope上的图像文本行检测和文本识别模型进行本地部署并转为API服务。
本地部署时把代码中的检测和识别模型路径改为本地模型的路径。
关于模型和代码原理可以参见modelscope上这两个模型相关的页面:
iic/cv_resnet18_ocr-detection-db-line-level_damo
iic/cv_convnextTiny_ocr-recognition-handwritten_damo

部署测试ocr模型的图片:
请添加图片描述
算力卡信息:

ixsmi
Timestamp    Wed May 28 17:28:09 2025
+-----------------------------------------------------------------------------+
|  IX-ML: 4.1.3       Driver Version: 4.1.3       CUDA Version: 10.2          |
|-------------------------------+----------------------+----------------------|
| GPU  Name                     | Bus-Id               | Clock-SM  Clock-Mem  |
| Fan  Temp  Perf  Pwr:Usage/Cap|      Memory-Usage    | GPU-Util  Compute M. |
|===============================+======================+======================|
| 0    Iluvatar MR-V50A         | 00000000:11:00.0     | 1000MHz   1600MHz    |
| 15%  45C   P0    19W / 75W    | 12290MiB / 16384MiB  | 0%        Default    |
+-------------------------------+----------------------+----------------------++-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU        PID      Process name                                Usage(MiB) |
|=============================================================================|
|    0    2505472      /usr/local/bin/python3 -c from multipro...  864        |
|    0    2503897      python3 ocr_api.py                          256        |
|    0    1688541      /usr/local/bin/python3 -c from multipro...  10992      |
+-----------------------------------------------------------------------------+

注意:以下ocr模型服务代码与硬件平台无关,只要把依赖软件安装了都能运行,即使cpu也能运行。部署测试过程中可能会报缺软件包的问题,根据提示pip install安装后即可运行。

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import JSONResponse
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
import uvicorn
import numpy as np
import cv2
import math
from typing import List
from io import BytesIO# 初始化OCR模型
ocr_detection = pipeline(Tasks.ocr_detection, model='iic/cv_resnet18_ocr-detection-db-line-level_damo')
ocr_recognition = pipeline(Tasks.ocr_recognition, model='iic/cv_convnextTiny_ocr-recognition-handwritten_damo')app = FastAPI(title="OCR API")# 工具函数
def crop_image(img, position):def distance(x1, y1, x2, y2):return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)position = position.tolist()for i in range(4):for j in range(i + 1, 4):if position[i][0] > position[j][0]:position[i], position[j] = position[j], position[i]if position[0][1] > position[1][1]:position[0], position[1] = position[1], position[0]if position[2][1] > position[3][1]:position[2], position[3] = position[3], position[2]x1, y1 = position[0]x2, y2 = position[2]x3, y3 = position[3]x4, y4 = position[1]corners = np.array([[x1, y1], [x2, y2], [x4, y4], [x3, y3]], dtype=np.float32)width = distance((x1 + x4)/2, (y1 + y4)/2, (x2 + x3)/2, (y2 + y3)/2)height = distance((x1 + x2)/2, (y1 + y2)/2, (x4 + x3)/2, (y4 + y3)/2)dst_corners = np.array([[0, 0], [width-1, 0], [0, height-1], [width-1, height-1]], dtype=np.float32)transform = cv2.getPerspectiveTransform(corners, dst_corners)dst = cv2.warpPerspective(img, transform, (int(width), int(height)))return dstdef order_point(coor):arr = np.array(coor).reshape([4, 2])centroid = np.mean(arr, axis=0)theta = np.arctan2(arr[:, 1] - centroid[1], arr[:, 0] - centroid[0])sort_points = arr[np.argsort(theta)]if sort_points[0][0] > centroid[0]:sort_points = np.concatenate([sort_points[3:], sort_points[:3]])return sort_points.astype('float32')def sort_boxes(boxes):def box_center(box):x = np.mean([p[0] for p in box])y = np.mean([p[1] for p in box])return x, ycenters = [box_center(box) for box in boxes]boxes_with_center = list(zip(boxes, centers))boxes_with_center.sort(key=lambda x: (x[1][1], x[1][0]))return [b[0] for b in boxes_with_center]# 主OCR函数
def ocr_from_bytes(image_bytes: bytes) -> str:image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)det_result = ocr_detection(image)['polygons']boxes = [order_point(box) for box in det_result]boxes = sort_boxes(boxes)lines: List[str] = []for pts in boxes:crop = crop_image(image, pts)text_result = ocr_recognition(crop)text = text_result['text'] if isinstance(text_result['text'], str) else ''.join(text_result['text'])lines.append(text)return '\n'.join(lines)# FastAPI 路由
@app.post("/ocr")
async def ocr_api(file: UploadFile = File(...)):try:image_bytes = await file.read()result = ocr_from_bytes(image_bytes)return JSONResponse(content={"text": result})except Exception as e:return JSONResponse(content={"error": str(e)}, status_code=500)# 启动方式(仅用于本地运行时)
# uvicorn ocr_api:app --reload
if __name__ == "__main__":uvicorn.run("ocr_api:app", host="0.0.0.0", port=8005, reload=True)

测试:

import requests# === 1. API 地址 === 
url = "http://localhost:8005/ocr"  # 改成你的 API 地址# === 2. 图片路径 === 
image_path = "ocr_img.jpg"  # 本地图片路径# === 3. 构造请求 === 
with open(image_path, "rb") as f:files = {'file': f}response = requests.post(url, files=files)# === 4. 输出结果 === if response.status_code == 200:result = response.json()print("识别结果:", result.get("text")) else:print(f"请求失败,状态码: {response.status_code}")print(response.text)

测试结果:
图片:
上面那个“妈妈说…"

测试返回:
约1秒
在这里插入图片描述

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

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

相关文章

大语言模型的完整训练周期从0到1的体系化拆解

以下部分内容参考了AI。 要真正理解大语言模型(LLM)的创生过程,我们需要将其拆解为一个完整的生命周期,每个阶段的关键技术相互关联,共同支撑最终模型的涌现能力。以下是体系化的训练流程框架: 阶段一&am…

吃水果(贪心)

文章目录 题目描述输入格式输出格式样例输入样例输出提交链接提示 解析参考代码 题目描述 最近米咔买了 n n n 个苹果和 m m m 个香蕉,他每天可以选择吃掉一个苹果和一个香蕉(必须都吃一个,即如果其中一种水果的数量为 0 0 0,则…

【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit(4)

1.问题描述: LoginWithHuaweiIDButton不支持深色模式下定制文字和loading样式? 解决方案: LoginWithHuaweiIDButtonParams 中的有个supportDarkMode属性,设置为true后,需要自行响应系统的变化,见文档&am…

【C语言】指针详解(接)

前言: 文接上章,在上章节讲解了部分指针知识点,在本章节为大家继续提供。 六指针与字符串:C 语言字符串的本质 在 C 语言中,字符串实际上是一个以\0结尾的字符数组。字符串常量本质上是指向字符数组首元素的指针&…

第5讲、Odoo 18 CLI 模块源码全解读

Odoo 作为一款强大的企业级开源 ERP 系统,其命令行工具(CLI)为开发者和运维人员提供了极大的便利。Odoo 18 的 odoo/cli 目录,正是这些命令行工具的核心实现地。本文将结合源码,详细解读每个 CLI 文件的功能与实现机制…

如何将 PDF 文件中的文本提取为 YAML(教程)

这篇博客文章将向你展示如何将 PDF 转换为 YAML,通过提取带有结构标签的标记内容来实现。 什么是结构化 PDF? 一些 PDF 文件包含结构化内容,也称为带标签(tagged)或标记内容(marked content)&…

银发团扎堆本地游,“微度假”模式如何盘活银发旅游市场?

​ 银发微度假,席卷江浙沪 作者 | AgeClub吕娆炜 前言 均价200-300元的两天一夜微度假产品,正在中老年客群中走红。 “我们属于酒店直营,没有中间商赚差价,老年人乘坐地铁到目的地站,会有大巴负责接送,半…

苹果iOS应用ipa文件进行签名后无法连接网络,我们该怎么解决

苹果iOS应用ipa文件在经过签名处理后,如果发现无法连接网络,这可能会给用户带来极大的不便。为了解决这一问题,可以采取一系列的排查和解决步骤,以确保应用能够顺利地访问互联网。 首先,确保你的设备已经连接到一个稳…

MySQL 中 ROW_NUMBER() 函数详解

MySQL 中 ROW_NUMBER() 函数详解 ROW_NUMBER() 是 SQL 窗口函数中的一种,用于为查询结果集中的每一行分配一个​​唯一的连续序号​​。与 RANK() 和 DENSE_RANK() 不同,ROW_NUMBER() 不会处理重复值,即使排序字段值相同,也会严格…

Leetcode百题斩-二叉树

二叉树作为经典面试系列,那么当然要来看看。总计14道题,包含大量的简单题,说明这确实是个比较基础的专题。快速过快速过。 先构造一个二叉树数据结构。 public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode…

Asp.Net Core 如何配置在Swagger中带JWT报文头

文章目录 前言一、配置方法二、使用1、运行应用程序并导航到 /swagger2、点击右上角的 Authorize 按钮。3、输入 JWT 令牌,格式为 Bearer your_jwt_token。4、后续请求将自动携带 Authorization 头。 三、注意事项总结 前言 配置Swagger支持JWT 一、配置方法 在 …

MySQL 定时逻辑备份

文章目录 配置密码编写备份脚本配置权限定时任务配置检查效果如果不想保留明文密码手工配置备份密码修改备份命令 配置密码 cat >> /root/.my.cnf <<"EOF" [client] userroot passwordYourPassword EOF编写备份脚本 cat > /usr/local/bin/mysql_dum…

在qt中使用c++实现与Twincat3 PLC变量通信

这是一个只针对新手的教程&#xff0c;下载安装就不说了&#xff0c;我下的是TC31-Full-Setup.3.1.4024.66.exe是这个版本&#xff0c;其他版本应该问题不大。 先创建一个项目 选中SYSTEM&#xff0c;在右侧点击Choose Target&#xff08;接下来界面跟我不一样没关系&#xf…

云原生微服务devops项目管理英文表述详解

文章目录 1.云原生CNCF trail map云原生技术栈路线图 2. 微服务单体应用与微服务应用架构区别GraphQLKey differences: GraphQL and REST 3.容器化&编排dockerKubernetesContainers and ContainerizationContainer Basics 4. DevOps & CI/CDTerms and Definitions 5.Ag…

pyside 使用pyinstaller导出exe(含ui文件)

第一步&#xff1a;首先确保安装好pyinstall&#xff0c;终端运行 pyinstaller -w main.py 生成两个文件夹 打开exe文件报错&#xff0c;问题是ui文件找不到 第二步&#xff1a;将ui文件复制到exe所在文件夹&#xff0c;打开成功 ![在这里插入图片描述](https://i-blog.csdni…

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器 js 代码 其他地方用直接导入js getCurrentUserId 这是自己后端获取 域账号地址 我是成功返回200 //true普通浏览器 fasle 无痕浏览器 export const checkBrowserMode async () > {try {const response a…

HTML 计算网页的PPI

HTML 计算网页的PPI vscode上安装live server插件&#xff0c;可以实时看网页预览 有个疑问&#xff1a; 鸿蒙density是按照类别写死的吗&#xff0c;手机520dpi 折叠屏426dpi 平板360dpi <html lang"en" data - overlayscrollbars - initialize><header&…

华为OD机试真题——Boss的收入(分销网络提成计算)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

<el-date-picker>组件传参时,选中时间和传参偏差8小时

遇到一个bug&#xff0c;不仔细看&#xff0c;都不一定能发现&#xff0c;bug描述&#xff1a;我们有一个搜索框&#xff0c;里面有一个时间选择器&#xff0c;当我使用<el-date-picker>时&#xff0c;我发现当我选择时分秒之后&#xff0c;显示都正常&#xff0c;但是当…

uni-app开发特殊社交APP

uni-app开发特殊社交APP 目录 1.展示APP功能 2.展示项目结构 3.关于我的GitHub 引言 博主最近自己在GitHub上面上传了一个关于社交软件的项目&#xff08;该项目早已开发完毕&#xff09;, 这个社交软件比较特殊, 被称之为blind-date&#xff0c; blind-date 是基于 uni-…