学习tensorflow有一段时间了,想做点东西来练一下手。为了更有意思点,下面将搭建一个简单的验证码识别系统。

准备验证码数据

下面将生成一万张四位英文字母的验证码,验证码的大小是100 * 30的图片,只包含大写的英文字母,并将目标值保存到csv文件。

import random
import pandas as pd
from PIL import Image, ImageDraw, ImageFont def generate_captcha(filename, format):
"""
生成四位验证码
:param filename: 要保存的文件名
:param format: 保存图片格式
:return: 验证码的值
"""
# 定义使用Image类实例化一个长为100px,宽为30px,基于RGB的(255,255,255)颜色的图片
img = Image.new(mode="RGB", size=(100, 30), color=(255, 255, 255))
# 实例化一支画笔
draw = ImageDraw.Draw(img, mode="RGB")
# 定义要使用的字体
font = ImageFont.truetype("arial", 28) result = "" for i in range(4):
# 每循环一次,从a到z中随机生成一个字母
# 65到90为字母的ASCII码,使用chr把生成的ASCII码转换成字符
# str把生成的数字转换成字符串
char = random.choice([chr(random.randint(65, 90))])
result += char # 每循环一次重新生成随机颜色
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) # 把生成的字母或数字添加到图片上
# 图片长度为100px,要生成4个数字或字母则每添加一个,其位置就要向后移动24px
draw.text([i * 24 + 3, 0], char, color, font=font) # 保存生成的文件
with open(filename, "wb") as f:
img.save(f, format=format) return result if __name__ == "__main__": data = [] # 生成10000张验证码图片,并将目标值存入csv文件
for j in range(10000):
val = generate_captcha("./pics/{}.png".format(j), "png")
data.append([val]) # 将验证码的值保存到csv文件
df = pd.DataFrame(data, columns=['label'])
df.to_csv('./pics/data.csv', header=False)

生成的验证码图片是这样子的,如下:

csv文件内容:

0,EFGQ
1,ZDKO
2,UWLD
3,CPDH
....

保存为tfrecords文件

上面生成的图片和其目标值是分开的,在进行训练时不太方便(训练时每次都要单独的读取图片和特征值)。保存为tfrecords文件,在训练时会方便很多,读取出来的每条记录既有图片特征值又有目标值。

import tensorflow as tf
import os
import numpy as np class CaptchaInput(object): def __init__(self, captcha_dir, letter, tfrecords_dir):
"""
:param captcha_dir: 验证码路径
:param letter: 验证码字符种类
:param tfrecords_dir: tfrecords文件保存的目录
"""
self.captcha_dir = captcha_dir
self.letter = letter
self.tfrecords_dir = tfrecords_dir # 列出图片文件,并进行排序
self.file_list = os.listdir(self.captcha_dir)
self.file_list = [i for i in self.file_list if i.endswith(".png")]
self.file_list.sort(key=lambda x: int(x[0:-4]))
self.file_list = [os.path.join(self.captcha_dir, i) for i in self.file_list] # 标签文件路径
self.labels_path = os.path.join(self.captcha_dir, "data.csv") def read_captcha_image(self):
"""读取验证码图片数据"""
# 构造文件队列
file_queue = tf.train.string_input_producer(self.file_list, shuffle=False) # 构建阅读器
reader = tf.WholeFileReader() # 读取图片内容
key, value = reader.read(file_queue)
# 解码图片
image = tf.image.decode_png(value)
image.set_shape([30, 100, 3]) # 批量读取
image_batch = tf.train.batch([image], batch_size=len(self.file_list),
num_threads=1, capacity=len(self.file_list))
return image_batch def read_captcha_label(self):
"""读取 验证码标签数据"""
# 构造文件队列
file_queue = tf.train.string_input_producer([self.labels_path], shuffle=False) # 构建文件阅读器
reader = tf.TextLineReader() # 读取标签内容
key, value = reader.read(file_queue) records = [[0], [""]]
index, label = tf.decode_csv(value, record_defaults=records) # 批量读取
label_batch = tf.train.batch([label], batch_size=len(self.file_list),
num_threads=1, capacity=len(self.file_list)) return label_batch def process_labels(self, labels):
"""将标签字符转换成数字张量"""
# 构建字符索引
num_letter_dict = dict(enumerate(list(self.letter)))
letter_num_dict = dict(zip(num_letter_dict.values(), num_letter_dict.keys())) ret = [] for label in labels:
arr = [letter_num_dict[i] for i in label.decode("utf-8")]
ret.append(arr) return np.array(ret) def write_to_tfrecords(self, images, labels):
"""
将图片和标签写入到tfrecords文件中
:param images: 特征值
:param labels: 目标值
:return:
"""
# labels = tf.cast(labels, tf.uint8)
# images = tf.cast(images, tf.uint8) # 建立存储文件
fw = tf.python_io.TFRecordWriter(self.tfrecords_dir)
for i in range(len(self.file_list)):
# images[i]为numpy.ndarray
image_bytes = images[i].tobytes()
# labels[i]为numpy.ndarray
label_bytes = labels[i].tobytes() example = tf.train.Example(features=tf.train.Features(feature={
"image": tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes])),
"label": tf.train.Feature(bytes_list=tf.train.BytesList(value=[label_bytes]))
})) print("保存第%d张图片" % (i, )) fw.write(example.SerializeToString()) # 关闭
fw.close() def execute(self):
image_batch = self.read_captcha_image()
label_batch = self.read_captcha_label() with tf.Session() as sess: coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess, coord=coord) # [b'EFGQ' b'ZDKO' b'UWLD' ... b'TKPD' b'ZZEU' b'ATYA']
labels = sess.run(label_batch) # labels为numpy.ndarray
labels = self.process_labels(labels)
# images为numpy.ndarray
images = sess.run(image_batch) self.write_to_tfrecords(images, labels) coord.request_stop()
coord.join(threads) FLAGS = tf.app.flags.FLAGS tf.app.flags.DEFINE_string("captcha_dir", "./pics", "验证码图片路径")
tf.app.flags.DEFINE_string("letter", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "验证码字符种类")
tf.app.flags.DEFINE_string("tfrecords_dir", "./tfrecords/captcha.tfrecords", "验证码tfrecords文件") if __name__ == "__main__":
c = CaptchaInput(FLAGS.captcha_dir, FLAGS.letter, FLAGS.tfrecords_dir)
c.execute()

需要注意:

  • os.listdir返回的文件名称的顺序是按照ascii表的顺序(1.png, 10.png...)需要对其进行排序
  • 使用tensorflow读取图片和标签文件时,需要加上shuffle=False,避免文件乱序了,图片和目标值对应不上。

验证码训练

import tensorflow as tf

FLAGS = tf.app.flags.FLAGS

tf.app.flags.DEFINE_string("captcha_dir", "./tfrecords/captcha.tfrecords", "验证码数据文件")
tf.app.flags.DEFINE_integer("batch_size", 100, "每批次训练样本数") def read_and_decode():
"""读取验证码数据
:return image_batch, label_batch
"""
# 文件队列
file_queue = tf.train.string_input_producer([FLAGS.captcha_dir]) # 文件读取器
reader = tf.TFRecordReader() # 读取内容
key, value = reader.read(file_queue)
# 解析tfrecords
features = tf.parse_single_example(value, features={
"image": tf.FixedLenFeature([], tf.string),
"label": tf.FixedLenFeature([], tf.string)
})
# 解码
image = tf.decode_raw(features["image"], tf.uint8)
label = tf.decode_raw(features["label"], tf.uint8)
# print(image, label) # 改变形状
image_reshape = tf.reshape(image, [30, 100, 3])
label_reshape = tf.reshape(label, [4])
# print(image_reshape, label_reshape) # 批处理
image_batch, label_batch = tf.train.batch([image_reshape, label_reshape],
batch_size=FLAGS.batch_size, num_threads=1, capacity=FLAGS.batch_size)
return image_batch, label_batch def weight_variables(shape):
"""权重初始化函数"""
w = tf.Variable(tf.random_normal(shape=shape, mean=0.0, stddev=1.0))
return w def bias_variables(shape):
"""偏置初始化函数"""
b = tf.Variable(tf.constant(0.0, shape=shape))
return b def fc_model(image):
"""全连接模型"""
with tf.variable_scope("fc_model"):
image_reshape = tf.reshape(image, [-1, 30 * 100 * 3]) # 随机初始化权重和偏重
weights = weight_variables([30 * 100 * 3, 4 * 26])
bias = bias_variables([4 * 26]) # 全连接计算
y_predict = tf.matmul(tf.cast(image_reshape, tf.float32), weights) + bias return y_predict def label_to_onehot(label):
"""目标值转换成one-hot编码"""
label_onehot = tf.one_hot(label, depth=26, on_value=1.0, axis=2)
return label_onehot def captcharec():
"""验证码识别"""
image_batch, label_batch = read_and_decode()
# [100, 104]
y_predict = fc_model(image_batch) y_true = label_to_onehot(label_batch) # softmax计算,交叉熵损失计算
with tf.variable_scope("soft_cross"):
loss = tf.nn.softmax_cross_entropy_with_logits(
labels=tf.reshape(y_true, [-1, 4 * 26]),
logits=y_predict
) # 梯度下降损失优化
with tf.variable_scope("optimizer"):
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss) # 准确率
with tf.variable_scope("acc"):
equal_list = tf.equal(tf.argmax(y_true, 2), tf.argmax(tf.reshape(y_predict, [-1, 4, 26]), 2))
accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32)) init_op = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init_op) coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess, coord=coord) for i in range(3000):
sess.run(train_op) print("第%d次训练的准确率为:%f" % (i, accuracy.eval())) coord.request_stop()
coord.join(threads) if __name__ == '__main__':
captcharec()

使用tensorflow搭建自己的验证码识别系统的更多相关文章

  1. Tensorflow搭建CNN实现验证码识别

    完整代码:GitHub 我的简书:Awesome_Tang的简书 整个项目代码分为三部分: Generrate_Captcha: 生成验证码图片(训练集,验证集和测试集): 读取图片数据和标签(标签即 ...

  2. windows下简单验证码识别——完美验证码识别系统

    此文已由作者徐迪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 讲到验证码识别,大家第一个可能想到tesseract.诚然,对于OCR而言,tesseract确实很强大,自带 ...

  3. AI识万物:从0搭建和部署手语识别系统 ⛵

    作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 计算机视觉实战系列: https://www.showmeai.tech ...

  4. 基于TensorFlow的车牌号识别系统

    简介 过去几周我一直在涉足深度学习领域,尤其是卷积神经网络模型.最近,谷歌围绕街景多位数字识别技术发布了一篇不错的paper.该文章描述了一个用于提取街景门牌号的单个端到端神经网络系统.然后,作者阐述 ...

  5. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现教程

    视频中的物体识别 摘要 物体识别(Object Recognition)在计算机视觉领域里指的是在一张图像或一组视频序列中找到给定的物体.本文主要是利用谷歌开源TensorFlow Object De ...

  6. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现(一)[超详细教程] ubuntu16.04版本

    谷歌宣布开源其内部使用的 TensorFlow Object Detection API 物体识别系统.本教程针对ubuntu16.04系统,快速搭建环境以及实现视频物体识别系统功能. 本节首先介绍安 ...

  7. 对于谷歌开源的TensorFlow Object Detection API视频物体识别系统实现教程

    本教程针对Windows10实现谷歌近期公布的TensorFlow Object Detection API视频物体识别系统,其他平台也可借鉴. 本教程将网络上相关资料筛选整合(文末附上参考资料链接) ...

  8. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现(二)[超详细教程] ubuntu16.04版本

    本节对应谷歌开源Tensorflow Object Detection API物体识别系统 Quick Start步骤(一): Quick Start: Jupyter notebook for of ...

  9. 强智教务系统验证码识别 Tensorflow CNN

    强智教务系统验证码识别 Tensorflow CNN 一直都是使用API取得数据,但是API提供的数据较少,且为了防止API关闭,先把验证码问题解决 使用Tensorflow训练模型,强智教务系统的验 ...

随机推荐

  1. 前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令

    一.单页面应用(SPA) 1.1 C/S到B/S页面架构的转变 C/S:客户端/服务器(Client/Server)架构的软件. C/S 软件的特点: ① 从window桌面双击打开 ② 更新的时候会 ...

  2. 『Möbius函数与Möbius反演』

    Möbius函数 定义 设正整数\(n\)算数基本定理分解后为\(n=\prod_{i=1}^{k}p_i^{a_i}\),定义函数 \[ \mu(n)= \begin{cases} 0\ \ (\e ...

  3. BeetleX快速构建多平台的TCP和SSL TCP应用

    对于普通开发者而言编写TCP应用通讯是一件相对复杂的工作,毕竟需要一系列的bytes操作:如果再针对SSL的安全性处理相信会把很多普通开发者拒之门外.为了简化这一问题BeetleX引入了Stream操 ...

  4. 我的Lambda的学习笔记

    前述 Lambda表达式是 Java 8 的新特性.许多语言都有 Lambda 的特性. 因此使用的 Java 环境一定要 8 以上的环境. Lambda 到底什么是 Lambda 表达式呢? Lam ...

  5. .NET Core:依赖注入

      在Startup的ConfigureServices方法中加入需要依赖注入的东西. 每次从容器 中获取的时候都是一个新的实例:services.AddTransient<ITransient ...

  6. SQL Server内幕之数据页

    数据页是包含已添加到数据库表中的用户数据的结构. 如前所述, 数据页有三种, 每个都以不同的格式存储数据. SQL server 有行内数据页.行溢出数据页和 LOB 数据页. 与 SQL serve ...

  7. 设计模式(Design Patterns)的简单讲解

    模式的诞生与定义 模式(Pattern)起源于建筑业而非软件业(小本本记下来--) 模式之父--美国加利佛尼亚大学环境结构中心研究所所长Christopher Alexander博士; 模式 : -C ...

  8. SQL注入渗透实战

    概述: 判断注入点: http://www.xxxxx.com/page.php?pid=42 and 1=1 #true http://www.xxxxx.com/page.php?pid=42 a ...

  9. 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限

    上一篇<[原]无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限>介绍了实现Shiro的基础认证.本篇谈谈实现 ...

  10. VIVADO时序约束及STA基础

    一.前言 无论是FPGA应用开发还是数字IC设计,时序约束和静态时序分析(STA)都是十分重要的设计环节.在FPGA设计中,可以在综合后和实现后进行STA来查看设计是否能满足时序上的要求.本文阐述基本 ...