当前位置: 首页 > news >正文

利用深度学习实现验证码识别-2-使用Python导出ONNX模型并在Java中调用实现验证码识别

在这里插入图片描述

1. Python部分:导出ONNX模型

首先,我们需要在Python中定义并导出一个已经训练好的验证码识别模型。以下是完整的Python代码:

import string
import torch
import torch.nn as nn
import torch.nn.functional as FCHAR_SET = string.digits# 优化后的模型设计
class CaptchaModel(nn.Module):def __init__(self):super(CaptchaModel, self).__init__()self.conv1 = nn.Conv2d(1, 32, 3, padding=1)self.conv2 = nn.Conv2d(32, 64, 3, padding=1)self.conv3 = nn.Conv2d(64, 128, 3, padding=1)self.fc1 = nn.Linear(128 * 5 * 12, 256)  # 调整为实际展平维度self.fc2 = nn.Linear(256, 4 * len(CHAR_SET))self.dropout = nn.Dropout(0.5)def forward(self, x):x = F.relu(F.max_pool2d(self.conv1(x), 2))x = F.relu(F.max_pool2d(self.conv2(x), 2))x = F.relu(F.max_pool2d(self.conv3(x), 2))x = x.view(x.size(0), -1)x = F.relu(self.fc1(x))x = self.dropout(x)x = self.fc2(x)return x.view(-1, 4, len(CHAR_SET))# 使用CUDA,如果可用的话
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
# 假设你的模型已经训练好并保存在 'best_model.pth'
model = CaptchaModel().to(device)
model.load_state_dict(torch.load('best_model.pth'))# 生成一个测试输入 (示例输入的形状应与模型输入形状一致)
dummy_input = torch.randn(1, 1, 40, 100).to(device)# 导出模型为 ONNX 格式
torch.onnx.export(model, dummy_input, "captcha_model.onnx", input_names=["input"], output_names=["output"], dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}})print("Model exported to captcha_model.onnx")

这段代码定义了一个验证码识别模型,并将其导出为ONNX格式,以便在Java中使用。

2. Java部分:调用ONNX模型进行验证码识别

接下来,我们使用Java调用导出的ONNX模型进行验证码识别。以下是完整的Java代码:

  • 引用onnxruntime-1.19.0.jar
package com.tushuoit;import ai.onnxruntime.*;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.List;public class CaptchaInference {private static final String CHAR_SET = "0123456789";private static final int INPUT_WIDTH = 100;private static final int INPUT_HEIGHT = 40;private static final Random random = new Random();public static void main(String[] args) throws Exception {// 随机生成4个字符的验证码文本String captchaText = generateRandomText(4);System.out.println("Generated Captcha Text: " + captchaText);// 生成包含文本的Bitmap (BufferedImage)BufferedImage captchaImage = generateCaptcha(captchaText, 36, INPUT_WIDTH, INPUT_HEIGHT);// 将Bitmap保存为文件(仅用于查看生成的图像,实际使用中可以省略)ImageIO.write(captchaImage, "png", new File("generated_captcha.png"));// 将图像转换为浮点数数组,并进行归一化处理float[] inputData = imageToFloatArray(captchaImage);// 创建ONNX Runtime环境OrtEnvironment env = OrtEnvironment.getEnvironment();OrtSession.SessionOptions opts = new OrtSession.SessionOptions();// 加载ONNX模型OrtSession session = env.createSession("captcha_model.onnx", opts);// 创建输入张量FloatBuffer inputBuffer = FloatBuffer.wrap(inputData);OnnxTensor inputTensor = OnnxTensor.createTensor(env, inputBuffer,new long[] { 1, 1, INPUT_HEIGHT, INPUT_WIDTH });// 进行推理OrtSession.Result result = session.run(Collections.singletonMap("input", inputTensor));// Extract output tensor and decode itfloat[][][] outputData = (float[][][]) result.get(0).getValue();List<String> decodedTexts = decodeOutput(outputData);// Print the decoded captcha textfor (String text : decodedTexts) {System.out.println("Predicted Captcha Text: " + text);}System.out.println("Inference completed.");// 释放资源session.close();env.close();}// 随机生成指定长度的验证码文本private static String generateRandomText(int length) {StringBuilder text = new StringBuilder(length);for (int i = 0; i < length; i++) {text.append(CHAR_SET.charAt(random.nextInt(CHAR_SET.length())));}return text.toString();}// 生成包含文本的BufferedImageprivate static BufferedImage generateCaptcha(String text, int fontSize, int width, int height) {BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = image.createGraphics();// 设置背景颜色为白色g2d.setColor(Color.WHITE);g2d.fillRect(0, 0, width, height);// 设置字体和颜色g2d.setFont(new Font("DroidSansMono", Font.PLAIN, fontSize));g2d.setColor(Color.BLACK);// 绘制文本FontMetrics fm = g2d.getFontMetrics();int x = 5; // 文字开始的X坐标int y = fm.getAscent() + 5; // 文字开始的Y坐标g2d.drawString(text, x, y);g2d.dispose();return image;}// 将BufferedImage转换为float数组,并进行归一化处理private static float[] imageToFloatArray(BufferedImage image) {int width = image.getWidth();int height = image.getHeight();float[] floatArray = new float[width * height];for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {int rgb = image.getRGB(x, y);int gray = (rgb >> 16) & 0xFF; // 因为是灰度图,只需获取一个通道的值floatArray[y * width + x] = (gray / 255.0f - 0.5f) * 2.0f; // 归一化到[-1, 1]}}return floatArray;}private static List<String> decodeOutput(float[][][] outputData) {List<String> decodedTexts = new ArrayList<>();for (float[][] singleOutput : outputData) {StringBuilder decodedText = new StringBuilder();for (float[] charProbabilities : singleOutput) {int maxIndex = getMaxIndex(charProbabilities);decodedText.append(CHAR_SET.charAt(maxIndex));}decodedTexts.add(decodedText.toString());}return decodedTexts;}private static int getMaxIndex(float[] probabilities) {int maxIndex = 0;float maxProb = probabilities[0];for (int i = 1; i < probabilities.length; i++) {if (probabilities[i] > maxProb) {maxProb = probabilities[i];maxIndex = i;}}return maxIndex;}
}

这段Java代码首先生成一个随机的验证码图像,然后将其转换为模型输入格式,并通过ONNX Runtime调用导出的模型进行推理,最后解码模型的输出以获取识别的验证码文本。
在这里插入图片描述

总结

通过上述步骤,我们成功地在Python中导出了一个验证码识别模型,并在Java中调用该模型进行验证码识别。这种方法充分利用了Python在深度学习模型训练和导出方面的优势,以及Java在实际应用部署和性能方面的优势,实现了高效的验证码识别系统。

相关文章:

利用深度学习实现验证码识别-2-使用Python导出ONNX模型并在Java中调用实现验证码识别

1. Python部分&#xff1a;导出ONNX模型 首先&#xff0c;我们需要在Python中定义并导出一个已经训练好的验证码识别模型。以下是完整的Python代码&#xff1a; import string import torch import torch.nn as nn import torch.nn.functional as FCHAR_SET string.digits# …...

如何通过Spring Cloud Consul增强微服务安全性和可靠性

为了增强微服务的安全性和可靠性&#xff0c;Spring Cloud Consul 是一个非常强大的工具。它不仅提供了服务发现和配置管理功能&#xff0c;还能够有效地管理微服务的安全和健康状态。本文将深入探讨如何通过 Spring Cloud Consul 来增强微服务的安全性和可靠性&#xff0c;主要…...

无代码搭建小程序zion

无代码搭建小程序zion 一、无代码搭建小程序zion的降低技术门槛&#xff0c;提升开发效率 1. 无需编程经验&#xff1a;Zion无代码平台通过提供直观的可视化界面和拖拽式操作&#xff0c;让开发者无需具备复杂的编程技能也能进行小程序的开发。这种方式大大降低了技术门槛&a…...

【南方科技大学】CS315 Computer Security 【Lab1 Packet Sniffing and Wireshark】

目录 IntroductionBackgroundTCP/IP Network StackApplication LayerTransport LayerInternet LayerLink LayerPacket Sniffer Getting WiresharkStarting WiresharkCapturing PacketsTest Run Questions for the Lab Introduction 实验的第一部分介绍数据包嗅探器 Wireshark。…...

【人工智能/机器学习/机器人】数学基础-学习笔记

函数 奇偶性&#xff1a; 偶函数&#xff1a; f ( − x ) f ( x ) f(-x)f(x) f(−x)f(x)   y轴对称 f ( x ) x 2 f(x)x^2 f(x)x2     f ( − x ) ( − x ) 2 x 2 f ( x ) f(-x)(-x)^2x^2f(x) f(−x)(−x)2x2f(x) 奇函数&#xff1a; f ( − x ) − f ( x ) f(-…...

视频安防监控LntonAIServer安防管理平台抖动检测和过亮过暗检测

随着视频监控技术的发展&#xff0c;视频质量成为确保监控系统有效性的重要因素。LntonAIServer通过引入抖动检测与过亮过暗检测功能&#xff0c;进一步提升了视频监控系统的可靠性和用户体验。这些功能可以帮助及时发现并解决视频流中的质量问题&#xff0c;确保视频监控系统始…...

网络模型及协议介绍

一.OSI七层模型 OSI Open System Interconnect 开放系统互连模型 以前不同厂家所生产的网络设备的标准是不同的&#xff0c;所以为了统一生产规范就制定了OSI这个生产模型。 作用&#xff1a;降低网络进行数据通信复杂度 这个模型的作用第一降低数据通信的复杂度&#xff…...

手撕HashMap源码

终于通过不屑努力&#xff0c;把源码中的重要部分全都看完了&#xff0c;每一行代码都看明白了&#xff0c;还写了注释 import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; import java.util.function.Consumer; import java.ut…...

OceanBase block_file与log过大 的问题

一、说明 block_file 是存放sstable的数据文件&#xff0c;由datafile_disk_percentage 参数与datafile_size参数决定&#xff0c;两个参数同时配置&#xff0c;以datafile_size为主。 datafile_disk_percentage 默认值是90 datafile_size 默认值是0M到正无穷 因为block_file 的…...

【Focal Loss 本质】

Focal Loss 示例 Focal Loss公式&#xff1a; 在后面的例子中&#xff0c;我们假定 y 1 的样本中&#xff0c;有两个预测值分别为(0.8, 0.4)。显然&#xff0c;0.8 很容易分类&#xff0c;0.4 很难分类。 可以看出&#xff0c;Focal Loss 降低了容易分类&#xff08;prt 0…...

端口安全老化细节

我们都知道port-security aging-time命令用来配置端口安全动态MAC地址的老化时间&#xff0c;但是后面还可以加上类型&#xff1a; [SW1-GigabitEthernet0/0/1]port-security aging-time 5 type absolute Absolute time 绝对老化 inactivity Inactivity time相对老化 …...

【C++】—— string 模拟实现

【C】—— string模拟实现 0 前言1 string的底层结构2 默认成员函数的实现2.1 构造函数2.1.1 无参构造2.1.2 带参构造2.1.2 合并 2.2 析构函数2.3 拷贝构造函数2.3.1 传统写法2.3.2 现代写法 2.3 赋值重载2.3.1 传统写法2.3.2 现代写法2.3.3 传统写法与现代写法的优劣 3 size、…...

详解TensorRT的C++高性能部署以及C++部署Yolo实践

详解TensorRT的C高性能部署 一. ONNX1. ONNX的定位2. ONNX模型格式3. ONNX代码使用实例 二、TensorRT1 引言 三、C部署Yolo模型实例 一. ONNX 1. ONNX的定位 ONNX是一种中间文件格式&#xff0c;用于解决部署的硬件与不同的训练框架特定的模型格式的兼容性问题。 ONNX本身其…...

手机如何切换网络IP地址:‌方法详解与操作指南‌

在当今的数字化时代&#xff0c;‌网络IP地址作为设备在网络中的唯一标识&#xff0c;‌扮演着至关重要的角色。‌对于手机用户而言&#xff0c;‌了解如何切换网络IP地址不仅有助于提升网络体验&#xff0c;‌还能在一定程度上保护个人隐私。‌本文将详细介绍手机切换网络IP地…...

南通网站建设手机版网页

随着移动互联网的迅猛发展&#xff0c;越来越多的人通过手机浏览网页&#xff0c;进行在线购物、信息查询和社交互动。因此&#xff0c;建立一个适合移动端访问的网站已成为企业和个人不可忽视的重要任务。在南通&#xff0c;网站建设手机版网页的需求逐渐增加&#xff0c;如何…...

macos系统内置php文件列表 系统自带php卸载方法

在macos系统中, 自带已经安装了php, 根据不同的macos版本php的版本号可能不同, 我们可以通过 which php 命令来查看mac自带的默认php安装路径, 不过注意这个只是php的执行文件路径. 系统自带php文件列表 一下就是macos默认安装的php文件列表. macos 10.15内置PHP文件列表配置…...

微信小程序认证和备案

小程序备案的流程一般包括以下步骤‌&#xff1a; 准备备案所需材料‌&#xff1a;通常需要提供‌营业执照、法人的‌身份证、两个‌手机号和一个邮箱等资料。 ‌1 ‌登录‌微信公众平台‌&#xff1a;作为第一次开发微信小程序的服务商&#xff0c;需要通过微信公众平台申请…...

C++复习day05

类和对象 1. 面向对象和面向过程的区别是什么&#xff1f;&#xff08;开放性问题&#xff09; 1. **抽象级别**&#xff1a;- **面向对象**&#xff1a;以对象&#xff08;数据和方法的集合&#xff09;为中心&#xff0c;强调的是数据和行为的封装。- **面向过程**&#xf…...

python数值误差

最近在用fenics框架跑有限元代码&#xff0c;其中有一个部分是把在矩阵里定义的初始值&#xff0c;赋值到有限元空间里&#xff0c;这就涉及到了初始矩阵和有限元空间坐标的转化&#xff0c;部分代码如下 for i in range(len(dof_coordinates)):# x, y dof_coordinates[i…...

基于FPGA的OV5640摄像头图像采集

1.OV5640简介 OV5640是OV&#xff08;OmniVision&#xff09;公司推出的一款CMOS图像传感器&#xff0c;实际感光阵列为&#xff1a;2592 x 1944&#xff08;即500w像素&#xff09;&#xff0c;该传感器内部集成了图像出炉的电路&#xff0c;包括自动曝光控制&#xff08;AEC…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...