使用CNN进行验证码识别:深度学习与图像预处理教程

news2024/11/15 19:41:47

验证码(CAPTCHA)广泛用于区分人类和自动化程序(如机器人),通常由扭曲的字母、数字或符号组成。为了实现验证码的自动识别,深度学习尤其是卷积神经网络(CNN)非常有效。本文将带你一起使用CNN构建一个验证码识别模型,并应用图像预处理技术来优化训练数据。
在这里插入图片描述
在这里插入图片描述

1. 预处理验证码图像

在训练模型之前,我们需要对图像进行一些预处理操作,以便让CNN能够更好地学习图像特征。以下是常见的图像预处理步骤:

  • 自适应阈值化:根据图像周围的区域动态确定阈值,适合处理光照不均的图像。
  • 形态学操作:如膨胀(Dilation)和腐蚀(Erosion),可以帮助去除噪声和连接断裂的字符。
  • 高斯模糊:去除图像中的噪声,平滑图像。

1.1 自适应阈值化

自适应阈值化是通过计算图像中每个小区域的均值或加权均值来确定该区域的阈值。这使得我们能更好地处理亮度不均的图像。

import cv2
import matplotlib.pyplot as plt

path1 = './samples/23n88.png'
path2 = './samples/23mdg.png'

# 读取图像
img1 = cv2.imread(path1, cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(path2, cv2.IMREAD_GRAYSCALE)

# 自适应阈值化
thresh_img1 = cv2.adaptiveThreshold(img1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 145, 0)
thresh_img2 = cv2.adaptiveThreshold(img2, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 145, 0)

# 显示阈值化结果
plt.figure(figsize=(20,5))
plt.subplot(1, 2, 1)
plt.imshow(thresh_img1, cmap='gray')
plt.subplot(1, 2, 2)
plt.imshow(thresh_img2, cmap='gray')
plt.show()

1.2 形态学操作(闭运算)

闭运算是先进行膨胀操作,然后进行腐蚀操作,主要用于去除小的噪点并填补字符中的小空洞。

# 形态学操作:闭运算
close_img1 = cv2.morphologyEx(thresh_img1, cv2.MORPH_CLOSE, np.ones((5,2), np.uint8))
close_img2 = cv2.morphologyEx(thresh_img2, cv2.MORPH_CLOSE, np.ones((5,2), np.uint8))

# 显示闭运算后的结果
plt.figure(figsize=(20,5))
plt.subplot(1, 2, 1)
plt.imshow(close_img1, cmap='gray')
plt.subplot(1, 2, 2)
plt.imshow(close_img2, cmap='gray')
plt.show()

1.3 膨胀操作

膨胀操作通过使用一个结构化元素对图像进行扫描,选择局部区域的最大值,通常用于扩展白色区域。

# 膨胀操作
dilate_img1 = cv2.dilate(close_img1, np.ones((2,2), np.uint8), iterations=1)
dilate_img2 = cv2.dilate(close_img2, np.ones((2,2), np.uint8), iterations=1)

# 显示膨胀后的结果
plt.figure(figsize=(20,5))
plt.subplot(1, 2, 1)
plt.imshow(dilate_img1, cmap='gray')
plt.subplot(1, 2, 2)
plt.imshow(dilate_img2, cmap='gray')
plt.show()

1.4 高斯模糊

高斯模糊有助于去除图像中的噪点,使图像更加平滑。

# 高斯模糊
gauss_img1 = cv2.GaussianBlur(dilate_img1, (1,1), 0)
gauss_img2 = cv2.GaussianBlur(dilate_img2, (1,1), 0)

# 显示模糊后的结果
plt.figure(figsize=(20,5))
plt.subplot(1, 2, 1)
plt.imshow(gauss_img1, cmap='gray')
plt.subplot(1, 2, 2)
plt.imshow(gauss_img2, cmap='gray')
plt.show()

1.5 将图像切割成小块

由于验证码通常包含多个字符,我们需要将每个字符切割出来作为模型的输入。这里,我们将图像分割成多个小块。

# 切割图像
image_list1 = [gauss_img1[10:50, 30:50], gauss_img1[10:50, 50:70], gauss_img1[10:50, 70:90], gauss_img1[10:50, 90:110], gauss_img1[10:50, 110:130]]
image_list2 = [gauss_img2[10:50, 30:50], gauss_img2[10:50, 50:70], gauss_img2[10:50, 70:90], gauss_img2[10:50, 90:110], gauss_img2[10:50, 110:130]]

# 显示切割结果
plt.figure(figsize=(20,5))
for i in range(5):
    plt.subplot(1, 5, i+1)
    plt.imshow(image_list1[i], cmap='gray')
plt.show()

2. 构建卷积神经网络(CNN)

接下来,我们将使用卷积神经网络(CNN)进行字符识别。CNN对于图像分类任务非常有效,因为它能够自动提取图像特征。

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, BatchNormalization, Dropout

def cnn_model(input_shape, num_classes):
    model = Sequential()
    model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=input_shape))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))

    model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.2))

    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))

    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    return model

# 创建模型
model = cnn_model((40, 20, 1), 19)  # 假设有19个类
model.summary()

3. 数据增强与过采样

3.1 SMOTE

SMOTE(合成少数类过采样技术)可以帮助我们增加少数类的样本量,以解决类别不平衡的问题。

from imblearn.over_sampling import SMOTE

# 假设 X_train 和 y_train 是训练集和标签
X_train = np.reshape(X_train, (4160, 40*20*1))  # 扁平化图像
X_train, y_train = SMOTE(sampling_strategy='auto', random_state=1).fit_resample(X_train, y_train)

X_train = np.reshape(X_train, (8037, 40, 20, 1))  # 恢复图像形状

3.2 使用 ImageDataGenerator 进行图像数据增强

数据增强可以生成更多样化的训练数据,从而帮助模型泛化能力的提升。

from keras.preprocessing.image import ImageDataGenerator

# 定义数据增强
traingen = ImageDataGenerator(rotation_range=5, width_shift_range=[-2, 2])
traingen.fit(X_train)

# 使用生成器
train_set = traingen.flow(X_train, y_train)

4. 模型训练与评估

我们可以使用Keras的ModelCheckpointReduceLROnPlateau回调来保存最佳模型,并在训练过程中调整学习率。

from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau

checkp = ModelCheckpoint('./captcha_model.h5', monitor='val_loss', save_best_only=True)
reduce = ReduceLROnPlateau(monitor='val_loss', patience=20, verbose=1)

history = model.fit(traingen.flow(X_train, y_train, batch_size=32

), validation_data=(X_test, y_test), epochs=10, callbacks=[checkp, reduce])

5. 测试与预测

训练完成后,我们可以用测试集进行评估,并通过model.predict()进行预测。

# 加载最佳模型
model = load_model('./captcha_model.h5')

# 预测
pred = model.predict(X_test)
pred = np.argmax(pred, axis=1)

# 打印准确率和分类报告
from sklearn.metrics import accuracy_score, classification_report
print('Accuracy:', accuracy_score(y_test, pred))
print(classification_report(y_test, pred))

6. 测试样本

我们还可以使用训练好的模型对一些新的验证码样本进行预测。

def get_demo(img_path):
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    img = t_img(img)
    img = c_img(img)
    img = d_img(img)
    img = b_img(img)
    
    image_list = [img[10:50, 30:50], img[10:50, 50:70], img[10:50, 70:90], img[10:50, 90:110], img[10:50, 110:130]]
    Xdemo = np.array([img_to_array(Image.fromarray(img)) for img in image_list]) / 255.0
    
    ydemo = model.predict(Xdemo)
    ydemo = np.argmax(ydemo, axis=1)
    
    for res in ydemo:
        print(info[res])
    print(img_path[-9:])

在这里插入图片描述
在这里插入图片描述

总结

通过图像预处理技术、数据增强、以及卷积神经网络的结合,我们可以构建一个高效的验证码识别系统。在实际应用中,可以根据具体的验证码类型调整预处理和模型参数,以提高准确性和泛化能力。

需要数据集的添加

在这里插入图片描述

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

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

相关文章

Springboot采用jasypt加密配置

目录 前言 一、Jasypt简介 二、运用场景 三、整合Jasypt 2.1.环境配置 2.2.添加依赖 2.3.添加Jasypt配置 2.4.编写加/解密工具类 2.5.自定义加密属性前缀和后缀 2.6.防止密码泄露措施 2.61.自定义加密器 2.6.2通过环境变量指定加密盐值 总结 前言 在以往的多数项目中&#xff0…

讯飞、阿里云、腾讯云:Android 语音合成服务对比选择

在 移动端 接入语音合成方面,讯飞和腾讯云等都是优秀的选择,但各有其特点和优势。咱们的需求是需要支持普通话/英语/法语三种语言,以下是对各个平台的详细比较: 一、讯飞语音合成介绍 与语音听写相反,语音合成是将一段…

python爬虫获得店铺的所有商品

在编写Python爬虫以获取店铺的所有商品信息时,通常涉及到发送HTTP请求、解析响应内容以及处理API返回的数据。以下是一个详细的Python爬虫示例,用于获取店铺的商品信息。这个示例假设API返回的是JSON格式的数据,并且需要API密钥进行认证。 步…

java程序打包及执行 jar命令及运行jar文件

java程序打包及执行 jar命令及运行jar文件 打包命令: 安装完成jdk之后采用 jar命令进行打包 jar -cvfe ddd.jar -C bin/ddd.java 打包 ddd.java 文件 jar -cvfe dddd.jar -C . 注意 -C 后面的点. 表示当前目录下所有 如图: 运行jar 文件 java -class…

计算机视觉空域处理完整版——超详细图文解

空域处理 图像空域处理 a.线性滤波b.非线性滤波c.二值图像处理方法 数学形态学连通成分标记 “点运算”是在不改变图像大小、几何形状以及局部结构的情况下,对像素值进行修改,新图像的像素值只与 原图像同一位置的像素值有关。 灰度级变换(线性变换,非…

【HarmonyOS】Hdc server port XXXX has been used.Configure environment variable

【HarmonyOS】Hdc server port XXXX has been used.Configure environment variable 一、 问题背景: 无法调试debug应用,IDE右下角显示该弹窗: Hdc server port XXXX has been used.Configure environment variable ‘OHOS_HDC_SERVER_POR…

立体工业相机提升工业自动化中的立体深度感知

深度感知对仓库机器人应用至关重要,尤其是在自主导航、物品拾取与放置、库存管理等方面。 通过将深度感知与各种类型的3D数据(如体积数据、点云、纹理等)相结合,仓库机器人可以在错综复杂环境中实现自主导航,物品检测…

深度解析:Android APP集成与拉起微信小程序开发全攻略

目录 一、背景以及功能介绍 二、Android开发示例 2.1 下载 SDK 2.2 调用接口 2.3 获取小程序原始Id 2.4 报错提示:bad_param 2.4.1 错误日志 2.4.2 解决方案 相关推荐 一、背景以及功能介绍 需求:产品经理需要APP跳转到公司的小程序(最好指定页…

stream学习

Stream流 定义 Steam流&#xff0c;用于操作集合或者数组中的数据&#xff0c;大量结合了Lamda表达式的语法风格&#xff0c;代码简洁。 重点&#xff1a; 流只能收集一次 ​ 获取Stream流 Stream流要与数据源建立连接。 1.list ​ 直接调用steam()即可 // list List<Stri…

python基础大杂烩

命令提示符程序&#xff0c;输入python&#xff0c;运行python程序 代码通过解释器程序翻译给计算机去执行 命令提示符输入的python本质上就是调用D:/dev/python/python3.12.5/python.exe这个解释器程序 有python程序将输入的代码翻译成二进制的0和1&#xff0c;去向计算机去运…

嵌入式硬件实战提升篇(一)-泰山派RK3566制作多功能小手机

引言&#xff1a;主要针对于嵌入式全栈内容的知识点汇总并对于linux等相关驱动知识点进行串联&#xff0c;用大家参考学习&#xff0c;并用到了嘉立创提供的泰山派RK3566作为学习的主控。 实物演示如下所示&#xff1a; 目录 一、硬件设计 1.转接电路 2.背光电路 3.音频接…

用两行命令快速搭建深度学习环境(Docker/torch2.5.1+cu118/命令行美化+插件),包含完整的 Docker 安装步骤

深度学习环境的配置过于繁琐&#xff0c;所以我制作了两个基础的镜像&#xff0c;希望可以帮助大家节省时间&#xff0c;你可以选择其中一种进行安装&#xff0c;版本说明&#xff1a; base 版本基于 pytorch/pytorch:2.5.1-cuda11.8-cudnn9-devel&#xff0c;默认 python 版本…

11个c语言编程练习题

0. 钞票和硬币 money.c 读取一个带有两个小数位的浮点数&#xff0c;代表货币价值。将该值分解为多种钞票和硬币的和&#xff0c;要求使用的钞票和硬币的总数量尽可能少。 货币面值有100&#xff0c;50&#xff0c;20&#xff0c;10&#xff0c;5&#xff0c;1&#xff0c;0.…

LaTeX之四:如何兼容中文(上手中文简历和中文论文)、在win/mac上安装新字体。

改成中文版 如果你已经修改了.cls文件和主文档&#xff0c;但编译后的PDF仍然显示英文版本&#xff0c;可能有以下几个原因&#xff1a; 编译器问题&#xff1a;确保你使用的是XeLaTeX或LuaLaTeX进行编译&#xff0c;因为它们对Unicode和中文支持更好。你可以在你的LaTeX编辑器…

K8S如何基于Istio实现全链路HTTPS

K8S如何基于Istio实现全链路HTTPS Istio 简介Istio 是什么?为什么选择 Istio?Istio 的核心概念Service Mesh(服务网格)Data Plane(数据平面)Sidecar Mode(边车模式)Ambient Mode(环境模式)Control Plane(控制平面)Istio 的架构与组件Envoy ProxyIstiod其他组件Istio 的流量管…

安全见闻-泷羽sec课程笔记

编程语言 C语言&#xff1a;一种通用的、面向过程的编程语言&#xff0c;广泛应用于系统软件和嵌入式开发。 C:在C语言基础上发展而来&#xff0c;支持面向对象编程&#xff0c;常用于尊戏开发、高性能计算等领域。 Java:一种广泛使用的面问对象编程语言&#xff0c;具有跨平台…

论文笔记(五十六)VIPose: Real-time Visual-Inertial 6D Object Pose Tracking

VIPose: Real-time Visual-Inertial 6D Object Pose Tracking 文章概括摘要I. INTRODACTIONII. 相关工作III. APPROACHA. 姿态跟踪工作流程B. VIPose网络 文章概括 引用&#xff1a; inproceedings{ge2021vipose,title{Vipose: Real-time visual-inertial 6d object pose tra…

LeetCode 热题100(八)【二叉树】(3)

目录 8.11二叉树展开为链表&#xff08;中等&#xff09; 8.12从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09; 8.13路径总和III&#xff08;中等&#xff09; 8.14二叉树的最近公共祖先&#xff08;中等&#xff09; 8.15二叉树中的最大路径和&#xff08;困…

【C语言】Union

一.Union的用法 1.什么是Union? union 共用体名{ 成员列表 }; union&#xff0c;“联合体、共用体”&#xff0c;在某种程度上类似结构体struct的一种数据结构&#xff0c;共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。 2.为什么使用union&#xff1…

Postgresql源码(138)alter table增加列的执行流程分析

alter table 逻辑比较繁琐&#xff0c;但并不复杂&#xff0c;这里以增加列为例简单梳理流程。 测试用例 drop table t_echo; create table t_echo(a int,b int); insert into t_echo select t.i, t.i*10 from generate_series(1,10) t(i); alter table t_echo add c varchar…