学习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. Mybatis学习笔记之一(环境搭建和入门案例介绍)

    一.Mybatis概述 1.1 Mybatis介绍 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了go ...

  2. JS 图片放大镜

    今天练习一个小demo, 从本地读取图片, 然后实现类似淘宝放大镜的效果, 再加两个需求 1 .可以调节缩放比例,默认放大两倍 2 . 图片宽高自适应, 不固定宽高 话不多说先看效果: 原理:1, 右 ...

  3. 基于Token认证的多点登录和WebApi保护

    在文章中有错误的地方,或是有建议或意见的地方,请大家多多指正,邮箱: linjie.rd@gmail.com 一天张三,李四,王五,赵六去动物园,张三没买票,李四制作了个假票,王五买了票,赵六要直接F ...

  4. Winform/WPF中内嵌BeetleX的HTTP服务

    在新版本的BeetleX.FastHttpApi加入了对netstandard2.0支持,如果程序基于.NetFramework4.6.1来构建WinForm或WPF桌面程序的情况下可以直接把Beet ...

  5. MTCNN算法与代码理解—人脸检测和人脸对齐联合学习

    目录 写在前面 算法Pipeline详解 如何训练 损失函数 训练数据准备 多任务学习与在线困难样本挖掘 预测过程 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 主 ...

  6. MTK Camera相关的Makefile Option详解

    列举了所有Camera相关的MakefileOption,并对其功能含义和OptionValues做了详细的解释.[KEYWORD]Others[SOLUTION]YUVCAM_INTERPOLATI ...

  7. sqlserver2014无法打开报Cannot find one or more components_修复方案

    前言:我跟网上大家的原因基本一样,就是好久没用sqlserver了,中间也对VS进行过卸载升级等,突然有一天发现,打开Sqlserver时打不开了,出了一个弹框:Cannot find one or ...

  8. ReactNative之从“拉皮条”来看RN中的Spring动画

    上篇博客我们聊了RN中关于Timing的动画,详情请参见于<ReactNative之结合具体示例来看RN中的的Timing动画>本篇博客我们将从一个“拉皮条”的一个动画说起,然后来看一下R ...

  9. @SuppressWarnings("rawtypes") 是什么含义

    简介:java.lang.SuppressWarnings是J2SE 5.0中标准的Annotation之一.可以标注在类.字段.方法.参数.构造方法,以及局部变量上.作用:告诉编译器忽略指定的警告, ...

  10. 知名区块链人脸识别公司iFace Chain [爱妃链] 支招,如何防止钱包数字币被盗...

    最近众多钱包发行方跑路频发,让非常多的用户蒙受巨大经济损失,知名区块链人脸识别公司iFace Chain [爱妃链] 前日做客某区块链媒体为网友支招,如何防止钱包数字币被盗. 那么,用户怎么降低Tok ...