開題:
關(guān)于車牌定位分割自己網(wǎng)上找一大堆資料總結(jié)后,發(fā)布出來還望取之于網(wǎng)友塔逃,總結(jié)后在公布給網(wǎng)友讯壶,能夠共同學習,剛接觸python沒多久湾盗,不乏有很多錯誤和不足伏蚊,還望指正。
關(guān)于本文TensorFlow模型訓練部分格粪,來源于
https://blog.csdn.net/shadown1ght/article/details/78571187#comments
也是很感謝此博主的無私開源精神躏吊,大家可以前往學習。
代碼是最好的老師帐萎,所有關(guān)于文章的全部代碼資源會再文末網(wǎng)盤給出比伏。
2019.4.25更新,更多關(guān)于多模型加載方案疆导,請前往csdn博客查看這里不做同步更新了赁项,謝謝理解
博客地址:https://blog.csdn.net/yang1159/article/details/88303461
首先說
1.python 用opencv的圖片切割
cut_img = image[y:y+h, x:x+w] # 裁剪坐標為[y0:y1, x0:x1]
image為源圖片,cut_image為切割后的圖片
坐標(x0,y0) (x1,y1)關(guān)系如圖:
?
2.python 對圖片的壓縮處理澈段,有兩種
第一種是 用的opencv 庫的threshold
cv.threshold(src_img, 100, 100, cv.THRESH_BINARY_INV, dec_img)
src_img為源圖片悠菜,dec_img為壓縮后的圖片,但我用這種方法處理后保存的圖片大小并不是100*100败富,網(wǎng)上查資料也發(fā)現(xiàn)有網(wǎng)友和我一樣的情況悔醋,或許我沒用對,有清楚的還請指正兽叮,謝謝芬骄。
第二種 用 PIL庫處理
from PIL import Image
im = Image.open("./py_car_num_tensor/num_for_car.jpg")
size = 720, 180
mmm = im.resize(size, Image.ANTIALIAS)
mmm.save("./py_car_num_tensor/num_for_car.jpg", "JPEG", quality=95)
這種方法可以直接獲取到設定大小的圖片
3.opencv對識別到車牌切割后做二值化處理
這里也嘗試了三種方法:
第一次使用
img = cv2.imread("./py_car_num_tensor/num_for_car.jpg") # 讀取圖片
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)換了灰度化
cv2.imshow('gray', img_gray) # 顯示圖片
cv2.waitKey(0)
# 2、將灰度圖像二值化鹦聪,設定閾值是100
img_thre = img_gray
# 灰點 白點 加錯
cv2.threshold(img_gray, 130, 255, cv2.THRESH_BINARY_INV, img_thre)
cv2.imshow('threshold', img_thre)
cv2.imwrite('./py_car_num_tensor/wb_img.jpg', img_thre)
cv2.waitKey(0)
src=cv2.imread("./py_car_num_tensor/wb_img.jpg")
height, width, channels = src.shape
print("width:%s,height:%s,channels:%s" % (width, height, channels))
for row in range(height):
for list in range(width):
for c in range(channels):
pv = src[row, list, c]
src[row, list, c] = 255 - pv
cv2.imshow("AfterDeal", src)
在車牌整潔账阻、光照角度合適理想情況下確實可以,但遇到一些帶泥水椎麦、曝光角度不對時宰僧,二值化后會有很多干擾源如:
?
第二次使用opencv文檔說自動閾值 調(diào)節(jié)的
# 二值化處理 自適應閾值 效果不理想
img_thre = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
效果同樣不太理想
第三次使用高斯除噪后在處理,效果堪稱完美
# 高斯除噪 二值化處理
blur = cv2.GaussianBlur(img_gray,(5,5),0)
ret3,img_thre = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
?
更多opencv 圖片處理見opencv中文社區(qū)文檔(翻譯后)http://www.cnblogs.com/Undo-self-blog/p/8423851.html
4.對單個字符的剪切观挎、壓縮稱制定比例
壓縮上面已經(jīng)將介紹了怎么壓縮成指定大小琴儿,重點是識別字符坐標后的剪切,這一點在代碼里也有很詳細說明嘁捷。
全部代碼如下: 關(guān)于cascade.xml 獲取 見下方網(wǎng)盤
'''
車牌框的識別 剪切保存
'''
# 使用的是HyperLPR已經(jīng)訓練好了的分類器
import os
import cv2
from PIL import Image
import test_province
import test_letters
import test_digits
import time
import numpy as np
import tensorflow as tf
from pip._vendor.distlib._backport import shutil
def find_car_num_brod():
watch_cascade = cv2.CascadeClassifier('D:\PyCharm\Test213\py_car_num_tensor\cascade.xml')
# 先讀取圖片
image = cv2.imread("D:\PyCharm\Test213\py_car_num_tensor\capture_img\car31.jpg")
resize_h = 1000
height = image.shape[0]
scale = image.shape[1] / float(image.shape[0])
image = cv2.resize(image, (int(scale * resize_h), resize_h))
image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
watches = watch_cascade.detectMultiScale(image_gray, 1.2, 2, minSize=(36, 9), maxSize=(36 * 40, 9 * 40))
print("檢測到車牌數(shù)", len(watches))
for (x, y, w, h) in watches:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 1)
cut_img = image[y + 5:y - 5 + h, x + 8:x - 15 + w] # 裁剪坐標為[y0:y1, x0:x1]
cut_gray = cv2.cvtColor(cut_img, cv2.COLOR_RGB2GRAY)
cv2.imwrite("D:\PyCharm\Test213\py_car_num_tensor\\num_for_car.jpg", cut_gray)
im = Image.open("D:\PyCharm\Test213\py_car_num_tensor\\num_for_car.jpg")
size = 720, 180
mmm = im.resize(size, Image.ANTIALIAS)
mmm.save("D:\PyCharm\Test213\py_car_num_tensor\\num_for_car.jpg", "JPEG", quality=95)
break
'''
剪切后車牌的字符單個拆分保存處理
'''
def cut_car_num_for_chart():
# 1造成、讀取圖像,并把圖像轉(zhuǎn)換為灰度圖像并顯示
img = cv2.imread("D:\PyCharm\Test213\py_car_num_tensor\\num_for_car.jpg") # 讀取圖片
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)換了灰度化
cv2.imshow('gray', img_gray) # 顯示圖片
cv2.waitKey(0)
# 2雄嚣、將灰度圖像二值化晒屎,設定閾值是100 轉(zhuǎn)換后 白底黑字 ---》 目標黑底白字
img_thre = img_gray
# 灰點 白點 加錯
# cv2.threshold(img_gray, 130, 255, cv2.THRESH_BINARY_INV, img_thre)
# 二值化處理 自適應閾值 效果不理想
# th3 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# 高斯除噪 二值化處理
blur = cv2.GaussianBlur(img_gray, (5, 5), 0)
ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow('threshold', th3)
cv2.imwrite('D:\PyCharm\Test213\py_car_num_tensor\wb_img.jpg', th3)
cv2.waitKey(0)
# src = cv2.imread("D:\PyCharm\Test213\py_car_num_tensor\wb_img.jpg")
# height, width, channels = src.shape
# print("width:%s,height:%s,channels:%s" % (width, height, channels))
# for row in range(height):
# for list in range(width):
# for c in range(channels):
# pv = src[row, list, c]
# src[row, list, c] = 255 - pv
# cv2.imshow("AfterDeal", src)
# cv2.waitKey(0)
#
# # 3喘蟆、保存黑白圖片
# cv2.imwrite('D:\PyCharm\Test213\py_car_num_tensor\wb_img.jpg', src)
# img = cv2.imread("D:\PyCharm\Test213\py_car_num_tensor\wb_img.jpg") # 讀取圖片
# src_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)換了灰度化
# src_img = src_gray
# 4、分割字符
white = [] # 記錄每一列的白色像素總和
black = [] # ..........黑色.......
height = th3.shape[0]
width = th3.shape[1]
white_max = 0
black_max = 0
# 計算每一列的黑白色像素總和
for i in range(width):
s = 0 # 這一列白色總數(shù)
t = 0 # 這一列黑色總數(shù)
for j in range(height):
if th3[j][i] == 255:
s += 1
if th3[j][i] == 0:
t += 1
white_max = max(white_max, s)
black_max = max(black_max, t)
white.append(s)
black.append(t)
print(str(s) + "---------------" + str(t))
print("blackmax ---->" + str(black_max) + "------whitemax ------> " + str(white_max))
arg = False # False表示白底黑字鼓鲁;True表示黑底白字
if black_max > white_max:
arg = True
n = 1
start = 1
end = 2
temp = 1
while n < width - 2:
n += 1
if (white[n] if arg else black[n]) > (0.05 * white_max if arg else 0.05 * black_max):
# 上面這些判斷用來辨別是白底黑字還是黑底白字
# 0.05這個參數(shù)請多調(diào)整蕴轨,對應上面的0.95
start = n
end = find_end(start, white, black, arg, white_max, black_max, width)
n = end
# 車牌框檢測分割 二值化處理后 可以看到明顯的左右邊框 畢竟用的是網(wǎng)絡開放資源 所以車牌框定位角度真的不準,
# 所以我在這里截取單個字符時做處理骇吭,就當亡羊補牢吧
# 思路就是從左開始檢測匹配字符橙弱,若寬度(end - start)小與20則認為是左側(cè)白條 pass掉 繼續(xù)向右識別,否則說明是
# 省份簡稱燥狰,剪切棘脐,壓縮 保存,還有一個當后五位有數(shù)字 1 時龙致,他的寬度也是很窄的蛀缝,所以就直接認為是數(shù)字 1 不需要再
# 做預測了(不然很窄的 1 截切 壓縮后寬度是被拉伸的),shutil.copy(A,B)這個函數(shù)就是當檢測 #到1時目代,從訓練圖片集里面復制一張標準的1的圖片給當前這個temp位置的字符屈梁,不用再做壓縮處理了
if end - start > 5: # 車牌左邊白條移除
print(" end - start" + str(end - start))
if temp == 1 and end - start < 20:
pass
elif temp > 3 and end - start < 20:
# 認為這個字符是數(shù)字1 copy 一個 32*40的 1 作為 temp.bmp
shutil.copy(os.path.join("D:\\PyCharm\\Test213\\py_car_num_tensor\\tf_car_license_dataset\\train_images\\"
"training-set\\1", "111.bmp"),
os.path.join("D:\PyCharm\Test213\py_car_num_tensor\img_cut", str(temp)+'.bmp'))
pass
else:
cj = th3[1:height, start:end]
cv2.imwrite("D:\PyCharm\Test213\py_car_num_tensor\img_cut_not_3240\\" + str(temp) + ".jpg", cj)
im = Image.open("D:\PyCharm\Test213\py_car_num_tensor\img_cut_not_3240\\" + str(temp) + ".jpg")
size = 32, 40
mmm = im.resize(size, Image.ANTIALIAS)
mmm.save("D:\PyCharm\Test213\py_car_num_tensor\img_cut\\" + str(temp) + ".bmp", quality=95)
# cv2.imshow('裁剪后:', mmm)
# cv2.imwrite("./py_car_num_tensor/img_cut/"+str(temp)+".bmp", cj)
temp = temp + 1
# cv2.waitKey(0)
# 分割圖像
def find_end(start_, white, black, arg, white_max, black_max, width):
end_ = start_ + 1
for m in range(start_ + 1, width - 1):
if (black[m] if arg else white[m]) > (0.95 * black_max if arg else 0.95 * white_max): # 0.95這個參數(shù)請多調(diào)整,對應下面的0.05
end_ = m
break
return end_
'''
車牌號碼 省份檢測:粵 [粵G .SB250]
'''
SIZE = 1280
WIDTH = 32
HEIGHT = 40
# NUM_CLASSES = 7
PROVINCES = ("京", "閩", "粵", "蘇", "滬", "浙", "豫")
nProvinceIndex = 0
time_begin = time.time()
# 定義輸入節(jié)點榛了,對應于圖片像素值矩陣集合和圖片標簽(即所代表的數(shù)字)
x = tf.placeholder(tf.float32, shape=[None, SIZE])
y_ = tf.placeholder(tf.float32, shape=[None, 7])
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)
def province_test():
saver_p = tf.train.import_meta_graph(
"D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\province\\car_province.ckpt.meta")
with tf.Session() as sess_p:
model_file = tf.train.latest_checkpoint("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\province")
saver_p.restore(sess_p, model_file)
# 第一個卷積層
W_conv1 = sess_p.graph.get_tensor_by_name("W_conv1:0")
b_conv1 = sess_p.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_p.graph.get_tensor_by_name("W_conv2:0")
b_conv2 = sess_p.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_p.graph.get_tensor_by_name("W_fc1:0")
b_fc1 = sess_p.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_p.graph.get_tensor_by_name("W_fc2:0")
b_fc2 = sess_p.graph.get_tensor_by_name("b_fc2:0")
# 定義優(yōu)化器和訓練op
conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
for n in range(1, 2):
path = "D:\\PyCharm\\Test213\\py_car_num_tensor\\img_cut\\%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_p.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(7):
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))
sess_p.close()
print("省份簡稱是: %s" % PROVINCES[nProvinceIndex])
'''
車牌號碼第二個字符識別:G [粵G .SB250]
'''
SIZE = 1280
WIDTH = 32
HEIGHT = 40
# NUM_CLASSES = 24
LETTERS_DIGITS = (
"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",
"Z")
time_begin = time.time()
# 定義輸入節(jié)點俘闯,對應于圖片像素值矩陣集合和圖片標簽(即所代表的數(shù)字)
x = tf.placeholder(tf.float32, shape=[None, SIZE])
y_ = tf.placeholder(tf.float32, shape=[None, 24])
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)
def province_letter_test():
license_num = ""
saver = tf.train.import_meta_graph("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\letters\\model.ckpt.meta")
with tf.Session() as sess:
model_file = tf.train.latest_checkpoint("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\letters")
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)化器和訓練op
conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
for n in range(2, 3):
path = "D:\\PyCharm\\Test213\\py_car_num_tensor\\img_cut\\%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(24):
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
if n == 3:
license_num += "-"
license_num = license_num + LETTERS_DIGITS[max1_index]
print("概率: [%s %0.2f%%] [%s %0.2f%%] [%s %0.2f%%]" % (
LETTERS_DIGITS[max1_index], max1 * 100, LETTERS_DIGITS[max2_index], max2 * 100,
LETTERS_DIGITS[max3_index],
max3 * 100))
sess.close()
print("城市代號是: 【%s】" % license_num)
'''
車牌號碼 后五位識別 SB250 [粵G .SB250]
'''
SIZE = 1280
WIDTH = 32
HEIGHT = 40
# NUM_CLASSES = 34
LETTERS_DIGITS = (
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N",
"P",
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
time_begin = time.time()
# 定義輸入節(jié)點,對應于圖片像素值矩陣集合和圖片標簽(即所代表的數(shù)字)
x = tf.placeholder(tf.float32, shape=[None, SIZE])
y_ = tf.placeholder(tf.float32, shape=[None, 34])
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)
def last_5_num_test():
license_num = ""
saver = tf.train.import_meta_graph("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\digits\\model.ckpt.meta")
print("main2")
with tf.Session() as sess:
model_file = tf.train.latest_checkpoint("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\digits")
print("main3")
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)化器和訓練op
conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
for n in range(4, 9):
path = "D:\\PyCharm\\Test213\\py_car_num_tensor\\img_cut\\%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(34):
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
license_num = license_num + LETTERS_DIGITS[max1_index]
print("概率: [%s %0.2f%%] [%s %0.2f%%] [%s %0.2f%%]" % (
LETTERS_DIGITS[max1_index], max1 * 100, LETTERS_DIGITS[max2_index], max2 * 100,
LETTERS_DIGITS[max3_index],
max3 * 100))
sess.close()
print("車牌編號是: 【%s】" % license_num)
if __name__ == '__main__':
find_car_num_brod() #車牌定位裁剪
cut_car_num_for_chart() #二值化處理裁剪成單個字符
province_test()
#last_5_num_test() 同時加載兩個模型還有問題忽冻,還望解決過的指明方向
資源鏈接:鏈接:https://pan.baidu.com/s/1iE__t08BBt5QbhLOUytOlA
提取碼:8c21
復制這段內(nèi)容后打開百度網(wǎng)盤手機App,操作更方便哦
遺留問題:
目前還有很大的問題就是只能一次加載1個預測模型此疹,加載兩個的話會說graph問題僧诚,我也按照網(wǎng)上說的一個模型一個graph處理但仍舊不行,這里提供下我的兩模型加載代碼蝗碎,還望多多指正問題湖笨,我的多模型加載:
import tensorflow as tf
import numpy as np
g1 = tf.Graph()
g2 = tf.Graph()
sess2 = tf.Session(graph=g2)
sess = tf.Session(graph=g1)
# 定義輸入節(jié)點,對應于圖片像素值矩陣集合和圖片標簽(即所代表的數(shù)字)
x = tf.placeholder(tf.float32, shape=[None, 1280])
y_ = tf.placeholder(tf.float32, shape=[None, 7])
x_image = tf.reshape(x, [-1, 32, 40, 1])
# 定義卷積函數(shù)
def conv_layer(inputs, W, b, conv_strides, kernel_size, pool_strides, padding):
print("inputs-----",inputs)
print("w ---------",W)
print("b ----------",b)
print("conv_strides ---------" ,conv_strides)
print("kernel_size ----------",kernel_size)
print("pool_strides ----------------",pool_strides)
print("padding-----------------",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)
def load_model():
print("graph1 ---------------------", g1)
with sess.as_default():
with sess.graph.as_default():
graph = tf.get_default_graph()
saver1 = tf.train.import_meta_graph(
"D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\province\\model.ckpt.meta")
model_file = tf.train.latest_checkpoint("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\province")
saver1.restore(sess, model_file)
print("-------------------------------------------------------------------", graph)
print('Successfully load the pre-trained model!')
# 第一個卷積層
W_conv1 = graph.get_tensor_by_name("W_conv1:0")
b_conv1 = 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 = graph.get_tensor_by_name("W_conv2:0")
b_conv2 = 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 = graph.get_tensor_by_name("W_fc1:0")
b_fc1 = 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 = graph.get_tensor_by_name("W_fc2:0")
b_fc2 = graph.get_tensor_by_name("b_fc2:0")
# 定義優(yōu)化器和訓練op
conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
print('Successfully load the pre-trained model!')
predict(keep_prob, conv)
from PIL import Image
def predict(keep_prob, conv):
PROVINCES = ("京", "閩", "粵", "蘇", "滬", "浙", "豫")
nProvinceIndex = 0
for n in range(1, 2):
path = "D:\\PyCharm\\Test213\\py_car_num_tensor\\img_cut\\%s.bmp" % (n)
img = Image.open(path)
width = img.size[0]
height = img.size[1]
img_data = [[0] * 1280 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(7):
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])
def load_model2():
with sess2.as_default():
with sess2.graph.as_default():
print("sess2 .graph -------->", sess2.graph)
graph = tf.get_default_graph()
print("get default graph --------------------------------------",graph)
saver2 = tf.train.import_meta_graph(
"D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\letters\\model.ckpt.meta")
model_file = tf.train.latest_checkpoint("D:\\PyCharm\\Test213\\py_car_num_tensor\\train-saver\\letters")
saver2.restore(sess2, model_file)
print('Successfully load the pre-trained model!')
# 第一個卷積層
W_conv1 = graph.get_tensor_by_name("W_conv1:0")
b_conv1 = 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 = graph.get_tensor_by_name("W_conv2:0")
b_conv2 = 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 = graph.get_tensor_by_name("W_fc1:0")
b_fc1 = 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 = graph.get_tensor_by_name("W_fc2:0")
b_fc2 = graph.get_tensor_by_name("b_fc2:0")
# 定義優(yōu)化器和訓練op
conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
print('Successfully load the pre-trained model!')
predict2(keep_prob, conv)
def predict2(keep_prob, conv):
LETTERS_DIGITS = (
"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
"Y", "Z")
for n in range(1, 2):
path = "D:\\PyCharm\\Test213\\py_car_num_tensor\\img_cut\\%s.bmp" % (n)
img = Image.open(path)
width = img.size[0]
height = img.size[1]
img_data = [[0] * 1280 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 = sess2.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(7):
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%%]" % (
LETTERS_DIGITS[max1_index], max1 * 100, LETTERS_DIGITS[max2_index], max2 * 100, LETTERS_DIGITS[max3_index],
max3 * 100))
print("省份簡稱是: %s" % LETTERS_DIGITS[nProvinceIndex])
if __name__ == '__main__':
load_model()
print("load module 2)
load_model2()
錯誤類型:ValueError: Tensor("W_conv1:0", shape=(8, 8, 1, 16), dtype=float32_ref) must be from the same graph as Tensor("Reshape:0", shape=(?, 32, 40, 1), dtype=float32).