#!/usr/bin/python3.5??
#?-*-?coding:?utf-8?-*-????
??
import?sys??
import?os??
import?time??
import?random??
??
import?numpy?as?np??
import?tensorflow?as?tf??
??
from?PIL?import?Image,ImageFilter
??
??
SIZE?=?1280??
WIDTH?=?32??
HEIGHT?=?40??
NUM_CLASSES?=?6??
iterations?=?300??
??
SAVER_DIR?=?"D/train-saver/province/"??
??
PROVINCES?=?("京","閩","粵","蘇","滬","浙")??
nProvinceIndex?=?0??
??
time_begin?=?time.time()??
??
??
#?定義輸入節(jié)點,對應(yīng)于圖片像素值矩陣集合和圖片標(biāo)簽(即所代表的數(shù)字)??
x?=?tf.placeholder(tf.float32,?shape=[None,?SIZE])??
y_?=?tf.placeholder(tf.float32,?shape=[None,?NUM_CLASSES])??
??
x_image?=?tf.reshape(x,?[-1,?WIDTH,?HEIGHT,?1])??
??
??
#?定義卷積函數(shù)??
def?conv_layer(inputs,?W,?b,?conv_strides,?kernel_size,?pool_strides,?padding):??
????L1_conv?=?tf.nn.conv2d(inputs,?W,?strides=conv_strides,?padding=padding)??
????L1_relu?=?tf.nn.relu(L1_conv?+?b)??
????return?tf.nn.max_pool(L1_relu,?ksize=kernel_size,?strides=pool_strides,?padding='SAME')??
??
#?定義全連接層函數(shù)??
def?full_connect(inputs,?W,?b):??
????return?tf.nn.relu(tf.matmul(inputs,?W)?+?b)??
??
??
if?__name__?=='__main__'?and?sys.argv[1]=='train':??
????#?第一次遍歷圖片目錄是為了獲取圖片總數(shù)??
????input_count?=?0??
????for?i?in?range(0,NUM_CLASSES):??
????????dir?=?'D:/tf_car_license_dataset/train_images/training-set/chinese-characters/%s/'?%?i???????????#?這里可以改成你自己的圖片目錄,i為分類標(biāo)簽??
????????for?rt,?dirs,?files?in?os.walk(dir):??
????????????for?filename?in?files:??
????????????????input_count?+=?1??
??
????#?定義對應(yīng)維數(shù)和各維長度的數(shù)組??
????input_images?=?np.array([[0]*SIZE?for?i?in?range(input_count)])??
????input_labels?=?np.array([[0]*NUM_CLASSES?for?i?in?range(input_count)])??
??
????#?第二次遍歷圖片目錄是為了生成圖片數(shù)據(jù)和標(biāo)簽??
????index?=?0??
????for?i?in?range(0,NUM_CLASSES):??
????????dir?=?'D:/tf_car_license_dataset/train_images/training-set/chinese-characters/%s/'?%?i??????????#?這里可以改成你自己的圖片目錄,i為分類標(biāo)簽??
????????for?rt,?dirs,?files?in?os.walk(dir):??
????????????for?filename?in?files:??
????????????????filename?=?dir?+?filename??
????????????????img?=?Image.open(filename)??
????????????????width?=?img.size[0]??
????????????????height?=?img.size[1]??
????????????????for?h?in?range(0,?height):??
????????????????????for?w?in?range(0,?width):??
????????????????????????#?通過這樣的處理,使數(shù)字的線條變細(xì),有利于提高識別準(zhǔn)確率??
????????????????????????if?img.getpixel((w,?h))?>?230:??
????????????????????????????input_images[index][w+h*width]?=?0??
????????????????????????else:??
????????????????????????????input_images[index][w+h*width]?=?1??
????????????????input_labels[index][i]?=?1??
????????????????index?+=?1??
??
????#?第一次遍歷圖片目錄是為了獲取圖片總數(shù)??
????val_count?=?0??
????for?i?in?range(0,NUM_CLASSES):??
????????dir?=?'D:/tf_car_license_dataset/train_images/validation-set/chinese-characters/%s/'?%?i???????????#?這里可以改成你自己的圖片目錄,i為分類標(biāo)簽??
????????for?rt,?dirs,?files?in?os.walk(dir):??
????????????for?filename?in?files:??
????????????????val_count?+=?1??
??
????#?定義對應(yīng)維數(shù)和各維長度的數(shù)組??
????val_images?=?np.array([[0]*SIZE?for?i?in?range(val_count)])??
????val_labels?=?np.array([[0]*NUM_CLASSES?for?i?in?range(val_count)])??
??
????#?第二次遍歷圖片目錄是為了生成圖片數(shù)據(jù)和標(biāo)簽??
????index?=?0??
????for?i?in?range(0,NUM_CLASSES):??
????????dir?=?'D:/tf_car_license_dataset/validation-set/chinese-characters/%s/'?%?i??????????#?這里可以改成你自己的圖片目錄,i為分類標(biāo)簽??
????????for?rt,?dirs,?files?in?os.walk(dir):??
????????????for?filename?in?files:??
????????????????filename?=?dir?+?filename??
????????????????img?=?Image.open(filename)??
????????????????width?=?img.size[0]??
????????????????height?=?img.size[1]??
????????????????for?h?in?range(0,?height):??
????????????????????for?w?in?range(0,?width):??
????????????????????????#?通過這樣的處理,使數(shù)字的線條變細(xì),有利于提高識別準(zhǔn)確率??
????????????????????????if?img.getpixel((w,?h))?>?230:??
????????????????????????????val_images[index][w+h*width]?=?0??
????????????????????????else:??
????????????????????????????val_images[index][w+h*width]?=?1??
????????????????val_labels[index][i]?=?1??
????????????????index?+=?1??
??????
????with?tf.Session()?as?sess:??
????????#?第一個卷積層??
????????W_conv1?=?tf.Variable(tf.truncated_normal([8,?8,?1,?16],?stddev=0.1),?name="W_conv1")??
????????b_conv1?=?tf.Variable(tf.constant(0.1,?shape=[16]),?name="b_conv1")??
????????conv_strides?=?[1,?1,?1,?1]??
????????kernel_size?=?[1,?2,?2,?1]??
????????pool_strides?=?[1,?2,?2,?1]??
????????L1_pool?=?conv_layer(x_image,?W_conv1,?b_conv1,?conv_strides,?kernel_size,?pool_strides,?padding='SAME')??
??
????????#?第二個卷積層??
????????W_conv2?=?tf.Variable(tf.truncated_normal([5,?5,?16,?32],?stddev=0.1),?name="W_conv2")??
????????b_conv2?=?tf.Variable(tf.constant(0.1,?shape=[32]),?name="b_conv2")??
????????conv_strides?=?[1,?1,?1,?1]??
????????kernel_size?=?[1,?1,?1,?1]??
????????pool_strides?=?[1,?1,?1,?1]??
????????L2_pool?=?conv_layer(L1_pool,?W_conv2,?b_conv2,?conv_strides,?kernel_size,?pool_strides,?padding='SAME')??
??
??
????????#?全連接層??
????????W_fc1?=?tf.Variable(tf.truncated_normal([16?*?20?*?32,?512],?stddev=0.1),?name="W_fc1")??
????????b_fc1?=?tf.Variable(tf.constant(0.1,?shape=[512]),?name="b_fc1")??
????????h_pool2_flat?=?tf.reshape(L2_pool,?[-1,?16?*?20*32])??
????????h_fc1?=?full_connect(h_pool2_flat,?W_fc1,?b_fc1)??
??
??
????????#?dropout??
????????keep_prob?=?tf.placeholder(tf.float32)??
??
????????h_fc1_drop?=?tf.nn.dropout(h_fc1,?keep_prob)??
??
??
????????#?readout層??
????????W_fc2?=?tf.Variable(tf.truncated_normal([512,?NUM_CLASSES],?stddev=0.1),?name="W_fc2")??
????????b_fc2?=?tf.Variable(tf.constant(0.1,?shape=[NUM_CLASSES]),?name="b_fc2")??
??
????????#?定義優(yōu)化器和訓(xùn)練op??
????????y_conv?=?tf.matmul(h_fc1_drop,?W_fc2)?+?b_fc2??
????????cross_entropy?=?tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,?logits=y_conv))??
????????train_step?=?tf.train.AdamOptimizer((1e-4)).minimize(cross_entropy)??
??
????????correct_prediction?=?tf.equal(tf.argmax(y_conv,?1),?tf.argmax(y_,?1))??
????????accuracy?=?tf.reduce_mean(tf.cast(correct_prediction,?tf.float32))??
??
????????#?初始化saver??
????????saver?=?tf.train.Saver()??
??
????????sess.run(tf.global_variables_initializer())??
??
????????time_elapsed?=?time.time()?-?time_begin??
????????print("讀取圖片文件耗費時間:%d秒"?%?time_elapsed)??
????????time_begin?=?time.time()??
??
????????print?("一共讀取了?%s?個訓(xùn)練圖像,?%s?個標(biāo)簽"?%?(input_count,?input_count))??
??
????????#?設(shè)置每次訓(xùn)練op的輸入個數(shù)和迭代次數(shù),這里為了支持任意圖片總數(shù),定義了一個余數(shù)remainder,譬如,如果每次訓(xùn)練op的輸入個數(shù)為60,圖片總數(shù)為150張,則前面兩次各輸入60張,最后一次輸入30張(余數(shù)30)??
????????batch_size?=?60??
????????iterations?=?iterations??
????????batches_count?=?int(input_count?/?batch_size)??
????????remainder?=?input_count?%?batch_size??
????????print?("訓(xùn)練數(shù)據(jù)集分成?%s?批,?前面每批?%s?個數(shù)據(jù),最后一批?%s?個數(shù)據(jù)"?%?(batches_count+1,?batch_size,?remainder))??
??
????????#?執(zhí)行訓(xùn)練迭代??
????????for?it?in?range(iterations):??
????????????#?這里的關(guān)鍵是要把輸入數(shù)組轉(zhuǎn)為np.array??
????????????for?n?in?range(batches_count):??
????????????????train_step.run(feed_dict={x:?input_images[n*batch_size:(n+1)*batch_size],?y_:?input_labels[n*batch_size:(n+1)*batch_size],?keep_prob:?0.5})??
????????????if?remainder?>?0:??
????????????????start_index?=?batches_count?*?batch_size;??
????????????????train_step.run(feed_dict={x:?input_images[start_index:input_count-1],?y_:?input_labels[start_index:input_count-1],?keep_prob:?0.5})??
??
????????????#?每完成五次迭代,判斷準(zhǔn)確度是否已達(dá)到100%,達(dá)到則退出迭代循環(huán)??
????????????iterate_accuracy?=?0??
????????????if?it%5?==?0:??
????????????????iterate_accuracy?=?accuracy.eval(feed_dict={x:?val_images,?y_:?val_labels,?keep_prob:?1.0})??
????????????????print?('第?%d?次訓(xùn)練迭代:?準(zhǔn)確率?%0.5f%%'?%?(it,?iterate_accuracy*100))??
????????????????if?iterate_accuracy?>=?0.9999?and?it?>=?150:??
????????????????????break;??
??
????????print?('完成訓(xùn)練!')??
????????time_elapsed?=?time.time()?-?time_begin??
????????print?("訓(xùn)練耗費時間:%d秒"?%?time_elapsed)??
????????time_begin?=?time.time()??
??
????????#?保存訓(xùn)練結(jié)果??
????????if?not?os.path.exists(SAVER_DIR):??
????????????print?('不存在訓(xùn)練數(shù)據(jù)保存目錄,現(xiàn)在創(chuàng)建保存目錄')??
????????????os.makedirs(SAVER_DIR)??
????????saver_path?=?saver.save(sess,?"%smodel.ckpt"%(SAVER_DIR))??
??
??
??
if?__name__?=='__main__'?and?sys.argv[1]=='predict':??
????saver?=?tf.train.import_meta_graph("%smodel.ckpt.meta"%(SAVER_DIR))??
????with?tf.Session()?as?sess:??
????????model_file=tf.train.latest_checkpoint(SAVER_DIR)??
????????saver.restore(sess,?model_file)??
??
????????#?第一個卷積層??
????????W_conv1?=?sess.graph.get_tensor_by_name("W_conv1:0")??
????????b_conv1?=?sess.graph.get_tensor_by_name("b_conv1:0")??
????????conv_strides?=?[1,?1,?1,?1]??
????????kernel_size?=?[1,?2,?2,?1]??
????????pool_strides?=?[1,?2,?2,?1]??
????????L1_pool?=?conv_layer(x_image,?W_conv1,?b_conv1,?conv_strides,?kernel_size,?pool_strides,?padding='SAME')??
??
????????#?第二個卷積層??
????????W_conv2?=?sess.graph.get_tensor_by_name("W_conv2:0")??
????????b_conv2?=?sess.graph.get_tensor_by_name("b_conv2:0")??
????????conv_strides?=?[1,?1,?1,?1]??
????????kernel_size?=?[1,?1,?1,?1]??
????????pool_strides?=?[1,?1,?1,?1]??
????????L2_pool?=?conv_layer(L1_pool,?W_conv2,?b_conv2,?conv_strides,?kernel_size,?pool_strides,?padding='SAME')??
??
??
????????#?全連接層??
????????W_fc1?=?sess.graph.get_tensor_by_name("W_fc1:0")??
????????b_fc1?=?sess.graph.get_tensor_by_name("b_fc1:0")??
????????h_pool2_flat?=?tf.reshape(L2_pool,?[-1,?16?*?20*32])??
????????h_fc1?=?full_connect(h_pool2_flat,?W_fc1,?b_fc1)??
??
??
????????#?dropout??
????????keep_prob?=?tf.placeholder(tf.float32)??
??
????????h_fc1_drop?=?tf.nn.dropout(h_fc1,?keep_prob)??
??
??
????????#?readout層??
????????W_fc2?=?sess.graph.get_tensor_by_name("W_fc2:0")??
????????b_fc2?=?sess.graph.get_tensor_by_name("b_fc2:0")??
??
????????#?定義優(yōu)化器和訓(xùn)練op??
????????conv?=?tf.nn.softmax(tf.matmul(h_fc1_drop,?W_fc2)?+?b_fc2)??
??
????????for?n?in?range(1,2):??
????????????path?=?"test_images/%s.bmp"?%?(n)??
????????????img?=?Image.open(path)??
????????????width?=?img.size[0]??
????????????height?=?img.size[1]??
??
????????????img_data?=?[[0]*SIZE?for?i?in?range(1)]??
????????????for?h?in?range(0,?height):??
????????????????for?w?in?range(0,?width):??
????????????????????if?img.getpixel((w,?h))?<?190:??
????????????????????????img_data[0][w+h*width]?=?1??
????????????????????else:??
????????????????????????img_data[0][w+h*width]?=?0??
??????????????
????????????result?=?sess.run(conv,?feed_dict?=?{x:?np.array(img_data),?keep_prob:?1.0})??
????????????max1?=?0??
????????????max2?=?0??
????????????max3?=?0??
????????????max1_index?=?0??
????????????max2_index?=?0??
????????????max3_index?=?0??
????????????for?j?in?range(NUM_CLASSES):??
????????????????if?result[0][j]?>?max1:??
????????????????????max1?=?result[0][j]??
????????????????????max1_index?=?j??
????????????????????continue??
????????????????if?(result[0][j]>max2)?and?(result[0][j]<=max1):??
????????????????????max2?=?result[0][j]??
????????????????????max2_index?=?j??
????????????????????continue??
????????????????if?(result[0][j]>max3)?and?(result[0][j]<=max2):??
????????????????????max3?=?result[0][j]??
????????????????????max3_index?=?j??
????????????????????continue??
??????????????
????????????nProvinceIndex?=?max1_index??
????????????print?("概率:??[%s?%0.2f%%]????[%s?%0.2f%%]????[%s?%0.2f%%]"?%?(PROVINCES[max1_index],max1*100,?PROVINCES[max2_index],max2*100,?PROVINCES[max3_index],max3*100))??
??????????????
????????print?("省份簡稱是:?%s"?%?PROVINCES[nProvinceIndex])執(zhí)行的時候出了以下問題:測試的時候有這句
path = "D:/tf_car_license_dataset/test_images/%s.bmp" % (n)這其中的%s.bmp是什么意思 如果我把它換成代表閩的1.bmp就會一直報錯 如果是%s.bmp就會打開測試集里的京...以下是我的文件夾的圖片 是測試集里圖片的名字問題嗎。。。求問大神原因...做在tensorflow下的車牌識別來著
測試集圖片無法測試的問題
Bubblegirl
2018-04-15 17:51:59