当前位置: 首页 > 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…...

CentOS 7下‘Development Tools’和‘开发工具’组有区别吗?实测告诉你答案

CentOS 7下‘Development Tools’与‘开发工具’的隐藏关联&#xff1a;技术细节全解析在Linux系统管理中&#xff0c;yum的软件包组功能一直是个既实用又充满谜团的领域。特别是当系统语言环境与软件包元数据语言不一致时&#xff0c;开发者们常常会遇到一个有趣的现象&#x…...

Midjourney锐化效果失效真相(2024官方未公开的渲染管线瓶颈解析)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney锐化效果失效真相&#xff08;2024官方未公开的渲染管线瓶颈解析&#xff09; 自2024年V6.2版本起&#xff0c;大量用户反馈 --stylize 与 --sharp 参数组合下图像边缘锐化效果显著弱化&am…...

OpenClaw用户如何快速接入Taotoken并开始Agent工作流

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 OpenClaw用户如何快速接入Taotoken并开始Agent工作流 对于使用OpenClaw框架构建AI智能体的开发者而言&#xff0c;快速接入稳定、多…...

ROS Noetic实战:从bag包里‘抠’出雷达点云和IMU数据的保姆级教程(Ubuntu 20.04)

ROS Noetic实战&#xff1a;从bag包里提取雷达点云和IMU数据的完整指南&#xff08;Ubuntu 20.04&#xff09;在机器人开发中&#xff0c;ROS bag文件就像是一个装满珍贵数据的宝箱&#xff0c;而雷达点云和IMU数据则是其中最闪亮的宝石。作为一名长期与ROS打交道的开发者&…...

基于Arduino的智能蓝调节拍器:DIY音乐练习伴侣

1. 项目概述&#xff1a;一个能“演奏”蓝调的低成本节拍器玩乐器的人&#xff0c;对节拍器这东西又爱又恨。它像一位严厉的监工&#xff0c;用单调的“嘀嗒”声强迫你跟上节奏。但你想过没有&#xff0c;这个监工其实可以很有趣&#xff1f;几年前&#xff0c;我在练习蓝调吉他…...

GEO生成引擎优化:当AI成为信息分发的主角,品牌如何抢占对话窗口?

当用户不再"搜索-浏览"&#xff0c;而是直接"AI提问-获取答案"&#xff0c;传统SEO的逻辑正在被彻底改写。2026年&#xff0c;GEO&#xff08;Generative Engine Optimization&#xff0c;生成式引擎优化&#xff09;已经从概念走向规模化落地。本文从技术…...

DragonBones与Godot集成:骨骼动画的可编程化实践

1. 为什么在Godot里用DragonBones不是“锦上添花”&#xff0c;而是“绕不开的刚需” 去年上线一个横版动作手游Demo时&#xff0c;美术团队交来一套20个角色、每个角色含8套动画&#xff08;待机/跑动/跳跃/攻击/受击/死亡/闪避/必杀&#xff09;的Spine资源。我兴冲冲导入God…...

OmenSuperHub:释放惠普游戏本性能的纯净开源控制中心

OmenSuperHub&#xff1a;释放惠普游戏本性能的纯净开源控制中心 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 还在为官方…...

DeepSeek代码风格检查避坑指南(内部审计报告首次披露:37个被忽略的合规红线)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek代码风格检查的合规性本质与审计背景 DeepSeek代码风格检查并非单纯的技术偏好约束&#xff0c;而是嵌入研发治理链条中的合规性控制节点。其本质是将编程实践与组织级安全策略、行业监管要求&…...

3步快速解密中兴光猫配置:ZET工具终极实战指南

3步快速解密中兴光猫配置&#xff1a;ZET工具终极实战指南 【免费下载链接】ZET-Optical-Network-Terminal-Decoder 项目地址: https://gitcode.com/gh_mirrors/ze/ZET-Optical-Network-Terminal-Decoder 中兴光猫配置解密工具是每个网络管理员必备的神器&#xff01;Z…...