从零开发短视频电商 PaddleOCR Java推理 (四)优化OCR工具类

从零开发短视频电商 PaddleOCR Java推理 (四)优化OCR工具类

在这里插入图片描述

参考:https://github.com/mymagicpower/AIAS/blob/9dc3c65d07568087ac71453de9070a416eb4e1d0/1_image_sdks/ocr_v4_sdk/src/main/java/top/aias/ocr/OcrV4RecExample.java

import ai.djl.inference.Predictor;
import ai.djl.modality.Classifications;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;
import ai.djl.modality.cv.output.BoundingBox;
import ai.djl.modality.cv.output.DetectedObjects;
import ai.djl.modality.cv.output.Rectangle;
import ai.djl.modality.cv.util.NDImageUtils;
import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDManager;
import ai.djl.paddlepaddle.zoo.cv.imageclassification.PpWordRotateTranslator;
import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ZooModel;
import lombok.SneakyThrows;import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;public class PPOCR {static ZooModel<Image, DetectedObjects> detectionModel = null;static ZooModel<Image, Classifications> rotateModel = null;static ZooModel<Image, String> recognitionModel;static {try {Criteria<Image, DetectedObjects> detectionCriteria = Criteria.builder().optEngine("PaddlePaddle").setTypes(Image.class, DetectedObjects.class).optModelUrls("https://paddleocr.bj.bcebos.com/PP-OCRv4/chinese/ch_PP-OCRv4_det_infer.tar").optTranslator(new PpWordDetectionTranslator2(new ConcurrentHashMap<String, String>())).build();detectionModel = detectionCriteria.loadModel();Criteria<Image, Classifications> rotateCriteria = Criteria.builder().optEngine("PaddlePaddle").setTypes(Image.class, Classifications.class).optModelUrls("https://resources.djl.ai/test-models/paddleOCR/mobile/cls.zip").optTranslator(new PpWordRotateTranslator()).build();rotateModel = rotateCriteria.loadModel();Criteria<Image, String> recognitionCriteria = Criteria.builder().optEngine("PaddlePaddle").setTypes(Image.class, String.class).optModelPath(Path.of("C:\\laker-2")).optTranslator(new PpWordRecognitionTranslator2()).build();recognitionModel = recognitionCriteria.loadModel();} catch (Exception e) {throw new RuntimeException(e);}}public static void main(String[] args) {doOCRFromUrl("https://img-blog.csdnimg.cn/direct/96de53d999c64c2589d0ab6a630e59d6.png");
//        doOCRFromFile("C:\\laker\\demo3\\1.png");
//        doOCRFromUrl("https://resources.djl.ai/images/flight_ticket.jpg");}@SneakyThrowspublic static String doOCRFromUrl(String url) {Image img = ImageFactory.getInstance().fromUrl(url);return doOCR(img);}@SneakyThrowspublic static String doOCRFromFile(String path) {Image img = ImageFactory.getInstance().fromFile(Path.of(path));return doOCR(img);}@SneakyThrowspublic static String doOCR(Image img) {List<DetectedObjects.DetectedObject> boxes = detection(img);List<String> names = new ArrayList<>();List<Double> prob = new ArrayList<>();List<BoundingBox> rect = new ArrayList<>();BoundingBox firstBox = boxes.get(0).getBoundingBox();List<ArrayList<String>> lines = new ArrayList<>();List<String> line = new ArrayList<>();lines.add((ArrayList) line);for (int i = 0; i < boxes.size(); i++) {System.out.println(boxes.get(i).getBoundingBox());BoundingBox tmpBox = boxes.get(i).getBoundingBox();double y1 = firstBox.getBounds().getY();double y2 = tmpBox.getBounds().getY();double dis = Math.abs(y2 - y1) * img.getHeight();Image subImg = getSubImage(img, boxes.get(i).getBoundingBox());if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {subImg = rotateImg(subImg);}Classifications.Classification result = getRotateResult(subImg);if ("Rotate".equals(result.getClassName()) && result.getProbability() > 0.8) {subImg = rotateImg(subImg);}String name = recognizer(subImg);names.add(name);prob.add(-1.0);rect.add(boxes.get(i).getBoundingBox());if (dis < 20) { // 认为是同 1 行  - Considered to be in the same lineline.add(name);} else { // 换行 - Line breakfirstBox = tmpBox;line = new ArrayList<>();line.add(name);lines.add((ArrayList) line);}}String fullText = "";for (int i = 0; i < lines.size(); i++) {for (int j = 0; j < lines.get(i).size(); j++) {String text = lines.get(i).get(j);if (text.trim().equals(""))continue;fullText += text + " ";}fullText += '\n';}System.out.println("fullText--------------\n" + fullText);Image newImage = img.duplicate();newImage.drawBoundingBoxes(new DetectedObjects(names, prob, rect));newImage.getWrappedImage();newImage.save(Files.newOutputStream(Paths.get("C:\\laker\\demo3\\1-1-1.png")), "png");return "";}@SneakyThrowsprivate static List<DetectedObjects.DetectedObject> detection(Image img) {Predictor<Image, DetectedObjects> detector = detectionModel.newPredictor();DetectedObjects detectedObj = detector.predict(img);System.out.println(detectedObj);return detectedObj.items();}@SneakyThrowsprivate static Classifications.Classification getRotateResult(Image img) {Predictor<Image, Classifications> rotateClassifier = rotateModel.newPredictor();Classifications predict = rotateClassifier.predict(img);System.out.println(predict);return predict.best();}@SneakyThrowsprivate static String recognizer(Image img) {Predictor<Image, String> recognizer = recognitionModel.newPredictor();String text = recognizer.predict(img);System.out.println(text);return text;}static Image getSubImage(Image img, BoundingBox box) {Rectangle rect = box.getBounds();double[] extended = new double[]{rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()};int width = img.getWidth();int height = img.getHeight();int[] recovered = {(int) (extended[0] * width),(int) (extended[1] * height),(int) (extended[2] * width),(int) (extended[3] * height)};return img.getSubImage(recovered[0], recovered[1], recovered[2], recovered[3]);}private static Image rotateImg(Image image) {try (NDManager manager = NDManager.newBaseManager()) {NDArray rotated = NDImageUtils.rotate90(image.toNDArray(manager), 1);return ImageFactory.getInstance().fromNDArray(rotated);}}
}

输出纯文本

 java   博客之望 lakernote @ te码龄11年 (编辑资料) 
907,648 总访问量丨 丨499原创丨 |2,426排名| |52,478粉丝| 702铁粉| 」学习成就 
个人简介:不停的复盘自己,砥砺前行,不忘初衷 
IP属地:日本 
查看详细资料 
成就〉 最近  文章514  问答5 適资源42 原力等级 
CSDN @lakernote 

结果

在这里插入图片描述

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

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

相关文章

晶振线路匹配需要进哪一些测试

晶振线路匹配的测试对于确保晶振性能的稳定性和可靠性至关重要&#xff0c;那么晶振线路匹配需要进哪一些测试呢? 晶振线路匹配测试是确保晶振性能稳定性和可靠性的关键环节。为了全面评估晶振的性能&#xff0c;需要进行一系列的测试&#xff0c;包括负载电容测试、驱动电平…

计算3种颜色粉刷立方体的所有可能方法

“&#xff08;伯恩赛德引理&#xff09;设G是一个作用在有限集合X上的有限群&#xff0c;令N为轨道的个数&#xff0c;则 其中Fix(x)是被τ固定的x∈X的个数.“ *高等近世代数 Joseph J. Rotman P78 “设G是一个有限群&#xff0c;作用在集合X上。对每个g属于G令X^g表示X中在g…

在 Linux 本地部署 stable diffusion

由于工作站安装的是 ubuntu&#xff0c;卡也在上面&#xff0c;就只能在 ubuntu 上部署安装 stable diffusion 了。另外&#xff0c;Linux 上使用 stable diffusion 也会方便很多。 1 准备工作 NVIDIA 官网下载驱动&#xff0c;主要是为了规避多卡驱动不同的问题。由于本机是…

机器学习_梯度下降

文章目录 什么是梯度梯度下降梯度下降有什么用 什么是梯度 计算梯度向量其几何意义&#xff0c;就是函数变化的方向&#xff0c;而且是变化最快的方向。对于函数f(x)&#xff0c;在点(xo,yo)&#xff0c;梯度向量的方向也就是y值增加最快的方向。也就是说&#xff0c;沿着梯度…

【QML COOK】- 009-组件(Components)

组件对于QML来说就如同C的类一样。可以用同一个组件创建多个对象。 组件有两种定义方式&#xff1a; 用独立的.qml文件定义组件在.qml文件中用Component对象定义组件 1. 创建项目&#xff0c;新建文件IndependentComponent.qml import QtQuickRectangle {id : rootText {id…

绝地求生追封原理

绝地求生追封原理是指在网络游戏《绝地求生》中&#xff0c;玩家通过观察和分析游戏中的各种信息&#xff0c;追踪其他玩家的位置和行动&#xff0c;以便更好地进行战术和攻击。 追封原理主要通过以下几种方式实现&#xff1a; BattleEye作弊系统检测 绝地求生玩家对这个系统…

vue中使用mpegts.js播放flv的直播视频流

第一步&#xff1a;引入mpegts.js npm install --save mpegts.js 第二步&#xff1a;在vue文件中引入mpegts.js的依赖 第三步&#xff1a;编写展示视频的盒子 我这里是使用循环遍历的方式创建video标签&#xff0c;这样方便后面随机展示视频使用 <template><div>&l…

03 顺序表

目录 线性表顺序表练习 线性表(Linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串。。。 线性表在逻辑上时线性结构&#xff0c;是连续的一条直线。但在物理结…

【RTOS】快速体验FreeRTOS所有常用API(1)工程创建

目录 一、工程创建1.1 新建工程1.2 配置RCC1.3 配置SYS1.4 配置外设1&#xff09;配置 LED PC132&#xff09;配置 串口 UART13&#xff09;配置 OLED I2C1 1.5 配置FreeRTOS1.6 工程设置1.7 生成代码1.8 keil设置下载&复位1.9 添加用户代码 本工程皆在快速体验FreeRTOS所有…

智慧公厕:打造智慧城市公共厕所信息化管理的新升级

在现代社会中&#xff0c;随着科学技术的不断进步与应用&#xff0c;智慧公厕作为公共服务设施&#xff0c;正迎来一次新的升级与革新。利用先进技术&#xff0c;智慧公厕实现了信息化升级&#xff0c;能够实时监测人员、环境和设备状况&#xff0c;提高使用效率、安全性、舒适…

微信小程序(一)简单的结构及样式演示

注释很详细&#xff0c;直接上代码 涉及内容&#xff1a; view和text标签的使用类的使用flex布局水平方向上均匀分布子元素垂直居中对齐子元素字体大小文字颜色底部边框的宽和颜色 源码&#xff1a; index.wxml <view class"navs"><text class"active…

Android 11.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

1.前言 在11.0的系统rom定制化开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 2.mtp模式下连接pc后显示的文件夹禁止删…

Linux中文件名修改的多种方法

找一个不算漂亮的普通女孩&#xff0c;一起柴米油盐&#xff0c;一起日出日落&#xff0c;一起田间地头&#xff0c;一起春花冬雪&#xff01;要一个不算大的小房子&#xff0c;生两个健康可爱的宝宝&#xff0c;这样就很好。。。。。。 简介&#xff1a; 在Linux系统中&#x…

MongoDB Compass当前版本及历史版本下载安装

mongoDB compass 当前版本下载 官网 https://www.mongodb.com/try/download/compass 官网下载一般只能下载最新版本。 github https://github.com/mongodb-js/compass MongoDB Compass与MongoDB的版本对应关系 MongoDB CompassMongoDB1.9.12MongoDB 2.6.11 Community

mysql表的约束问题

目录 1. 表的约束问题: 主键约束: 案例&#xff1a; 非空约束 唯一约束: 默认值约束: 案例&#xff1a; 2.表的结构 前提:接上一张博客内容经行操作 1. 表的约束问题: 用来保证数据插入的安全性、完整性、正确性 主健,外键,唯一,默认值,非空,检查 1.1…

UL2034详细介绍UL 安全单站和多站一氧化碳报警器标准

在介绍相关标准之前先介绍一下UL认证和UL测试报告的区别&#xff0c;检测认证行业6年老司机 UL认证是自愿性的认证&#xff0c;需要检测产品和审核工厂&#xff0c;每个季度审核一次&#xff0c;费用高、时间久&#xff0c;而且审厂非常的严格。 UL测试报告是根据产品选用相应…

使用@Slf4j后引入log,idea标红

引入Slf4j注解 idea标红Cannot resolve symbol ‘log’ 引入Lombok插件 如果在Marketplace查不到时&#xff0c;不妨关闭菜单再打开试下

【Java数据结构】04-图(Prim,Kruskal,Dijkstra,topo)

5 图 推荐辅助理解 【视频讲解】bilibili Dijkstra Prim 【手动可视化】Algorithm Visualizer &#xff08;https://algorithm-visualizer.org/&#xff09; 【手动可视化】Data Structure Visualizations (https://www.cs.usfca.edu/~galles/visualization/Algorithms.ht…

MathType中文网站2024最新版本下载及嵌入word教程

MathType是一款专业的数学公式编辑器,兼容Office word,excel等700多种程序,用于编辑数学试卷、书籍、报刊、论文、幻灯演示等文档轻松输入各种复杂的数学公式和符号。 MathType是一款功能强大的数学公式编辑器&#xff0c;广泛用于编写和编辑数学公式。Word是微软公司推出的文…