import tensorflow as tf
import os
import pandas as pd
def load_pics(filename_list):
"""
1、读取图像数据,csv文件中的file_num为标签值的编号
:return:
"""
filename_queue = tf.train.string_input_producer(filename_list)
image_reader = tf.WholeFileReader()
filename, image = image_reader.read(filename_queue)
decoded = tf.image.decode_jpeg(image)
image_reshape = tf.reshape(decoded, shape=[60, 160, 3])
image_cast = tf.cast(image_reshape, dtype=tf.float32)
filename_batch, image_batch = tf.train.batch([filename, image_cast], batch_size=100, num_threads=1, capacity=200)
return filename_batch, image_batch
def read_csv(csv_data):
"""
2、解析csv文件,将标签值转换为数值表示(根据26英文字母对应索引0-25建立标签对应的数值表)
得到“图像-标签值”表
:return:
"""
data = csv_data
labels = []
for label_name in data["characters"]:
label_num = []
for letter in label_name:
label_num.append(ord(letter) - ord('A'))
labels.append(label_num)
data["labels"] = labels
return data
def filename2labels(file_name, batch_data):
"""
3、根据filename与file_num对应相同来联系特征值(图片)与目标值(标签)
通过文件名查表得到当前图像对应的标签
:param batch_data:
:return:
"""
label_list = []
for name in file_name:
num_str = "".join(list(filter(str.isdigit, str(name))))
target = batch_data.loc[num_str, "labels"]
label_list.append(target)
return label_list
def variable_init(shape):
"""
定义给定形状的变量
:return:
"""
return tf.Variable(initial_value=tf.random.normal(shape=shape))
def cnn_identifying(x):
"""
4、构建卷积神经网络得到y_predict
:return:
"""
input_image = tf.reshape(x, [-1, 60, 160, 3])
with tf.variable_scope("conv1"):
Weights_filter1 = variable_init([5, 5, 3, 32])
bias_filter1 = variable_init([32])
conv1 = tf.nn.conv2d(input=input_image, filter=Weights_filter1, strides=[1, 1, 1, 1], padding="SAME") + bias_filter1
conv1_relu = tf.nn.relu(conv1)
conv1_pool = tf.nn.max_pool(value=conv1_relu, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
with tf.variable_scope("conv2"):
Weights_filter2 = variable_init([5, 5, 32, 64])
bias_filter2 = variable_init([64])
conv2 = tf.nn.conv2d(input=conv1_pool, filter=Weights_filter2, strides=[1, 1, 1, 1], padding="SAME") + bias_filter2
conv2_relu = tf.nn.relu(conv2)
conv2_pool = tf.nn.max_pool(value=conv2_relu, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
with tf.variable_scope("fc"):
conv2_reshape = tf.reshape(conv2_pool, shape=[-1, 15*40*64])
Weights_fc = variable_init([15*40*64, 4*26])
bias_fc = variable_init([4*26])
y_predict = tf.matmul(conv2_reshape, Weights_fc) + bias_fc
return y_predict
if __name__ == "__main__":
file_list = os.listdir(r"C:\Users\Username\Desktop\Con-LSTM\captcha_cnn\captcha_train_pic")
filename_list = [os.path.join(r"C:\Users\Username\Desktop\Con-LSTM\captcha_cnn\captcha_train_pic", filename)
for filename in file_list if filename[-3:] == "jpg"]
filename, image = load_pics(filename_list)
csv_data = pd.read_csv(r"C:\Users\Username\Desktop\Con-LSTM\captcha_cnn\captcha_train_pic\labels.csv",
names={"file_no", "characters"}, index_col="file_no")
csv_data_train = read_csv(csv_data)
x = tf.placeholder(dtype=tf.float32, shape=[None, 60, 160, 3])
y_true = tf.placeholder(dtype=tf.float32, shape=[None, 4*26])
y_predict = cnn_identifying(x)
loss_list = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_predict)
loss = tf.reduce_mean(loss_list)
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
y_predict_reshape = tf.reshape(y_predict, shape=[-1, 4, 26])
y_true_reshape = tf.reshape(y_true, shape=[-1, 4, 26])
equal_list = tf.equal(tf.argmax(y_predict_reshape, axis=2), tf.argmax(y_true_reshape, axis=2))
accuracy = tf.reduce_mean(tf.cast(tf.reduce_all(equal_list, axis=1), tf.float32))
init = tf.global_variables_initializer()
saver = tf.train.Saver()
with tf.compat.v1.Session() as sess:
sess.run(init)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
filename_val, image_val = sess.run([filename, image])
image_labels = filename2labels(filename_val, csv_data_train)
labels_onehot = tf.one_hot(image_labels, depth=26)
labels_value = tf.reshape(labels_onehot, shape=[-1, 4*26]).eval()
for i in range(1000):
_, error, accuracy_value = sess.run([optimizer, loss, accuracy], feed_dict={x: image_val, y_true: labels_value})
if i % 100 == 0:
saver.save(sess=sess, save_path=r"C:\Users\Username\Desktop\Con-LSTM\captcha_cnn\model")
coord.request_stop()
coord.join(threads=threads)
from captcha.image import ImageCaptcha
from random import randint
import os
import csv
def captcha_pic_builder():
'''
生成序列验证码图片及包含其对应目标值的csv文件
:return:
'''
list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z']
with open(r'C:\Users\Username\Desktop\Con-LSTM\captcha_cnn\captcha_test_pic\labels.csv', 'a+', newline='') as csvfile:
writer = csv.writer(csvfile, dialect='excel')
writer.writerow(['file_num', 'chars'])
for j in range(100):
chars = ''
for i in range(4):
chars += list[randint(0, 25)]
print(chars)
image = ImageCaptcha().generate_image(chars)
filename = str(j) +'.jpg'
image.save(os.path.join(r'C:\Users\Username\Desktop\Con-LSTM\captcha_cnn\captcha_test_pic', filename))
writer.writerow([j, chars])
return None
if __name__ == '__main__':
captcha_pic_builder()