關(guān)于python 對車牌檢測識別切割+TensorFlow預測

開題:

關(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.gif

image為源圖片,cut_image為切割后的圖片

坐標(x0,y0) (x1,y1)關(guān)系如圖:

image

?

image.gif

2.python 對圖片的壓縮處理澈段,有兩種

第一種是 用的opencv 庫的threshold

cv.threshold(src_img, 100, 100, cv.THRESH_BINARY_INV, dec_img)
image.gif

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)
image.gif

這種方法可以直接獲取到設定大小的圖片

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)
image.gif

在車牌整潔账阻、光照角度合適理想情況下確實可以,但遇到一些帶泥水椎麦、曝光角度不對時宰僧,二值化后會有很多干擾源如:

image
image.gif

?
image
image.gif

?

第二次使用opencv文檔說自動閾值 調(diào)節(jié)的

# 二值化處理 自適應閾值   效果不理想
img_thre = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
image.gif

效果同樣不太理想

第三次使用高斯除噪后在處理,效果堪稱完美

# 高斯除噪 二值化處理
blur = cv2.GaussianBlur(img_gray,(5,5),0)
ret3,img_thre = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
image.gif
image
image.gif

?
image
image.gif

?

更多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()  同時加載兩個模型還有問題忽冻,還望解決過的指明方向

image.gif

資源鏈接:鏈接: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()

image.gif

錯誤類型: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).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹦骑,一起剝皮案震驚了整個濱河市慈省,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眠菇,老刑警劉巖边败,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捎废,居然都是意外死亡笑窜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門登疗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來排截,“玉大人嫌蚤,你說我怎么就攤上這事《习粒” “怎么了脱吱?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長认罩。 經(jīng)常有香客問我箱蝠,道長,這世上最難降的妖魔是什么猜年? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任抡锈,我火速辦了婚禮,結(jié)果婚禮上乔外,老公的妹妹穿的比我還像新娘床三。我一直安慰自己,他們只是感情好杨幼,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布撇簿。 她就那樣靜靜地躺著,像睡著了一般差购。 火紅的嫁衣襯著肌膚如雪四瘫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天欲逃,我揣著相機與錄音找蜜,去河邊找鬼。 笑死稳析,一個胖子當著我的面吹牛洗做,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播彰居,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诚纸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陈惰?” 一聲冷哼從身側(cè)響起畦徘,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抬闯,沒想到半個月后井辆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡溶握,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年掘剪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奈虾。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡夺谁,死狀恐怖廉赔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情匾鸥,我是刑警寧澤蜡塌,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站勿负,受9級特大地震影響馏艾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奴愉,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一琅摩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锭硼,春花似錦房资、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至暑始,卻和暖如春搭独,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背廊镜。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工牙肝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嗤朴。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓惊奇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親播赁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容