From 715249db170df2ed721d231ed45a55dddd3a86f8 Mon Sep 17 00:00:00 2001 From: Json Shen Date: Wed, 22 Nov 2017 22:38:59 +0800 Subject: [PATCH] Added Python3 support --- hyperlpr_py3/__init__.py | 0 hyperlpr_py3/cache.py | 11 + hyperlpr_py3/colourDetection.py | 103 +++++++++ hyperlpr_py3/config.py | 6 + hyperlpr_py3/deskew.py | 100 +++++++++ hyperlpr_py3/detect.py | 76 +++++++ hyperlpr_py3/e2e.py | 63 ++++++ hyperlpr_py3/e2emodel.py | 34 +++ hyperlpr_py3/finemapping.py | 130 ++++++++++++ hyperlpr_py3/finemapping_vertical.py | 92 ++++++++ hyperlpr_py3/niblack_thresholding.py | 18 ++ hyperlpr_py3/pipline.py | 246 +++++++++++++++++++++ hyperlpr_py3/plateStructure.py | 0 hyperlpr_py3/precise.py | 0 hyperlpr_py3/recognizer.py | 154 ++++++++++++++ hyperlpr_py3/segmentation.py | 307 +++++++++++++++++++++++++++ hyperlpr_py3/typeDistinguish.py | 56 +++++ 17 files changed, 1396 insertions(+) create mode 100644 hyperlpr_py3/__init__.py create mode 100644 hyperlpr_py3/cache.py create mode 100644 hyperlpr_py3/colourDetection.py create mode 100644 hyperlpr_py3/config.py create mode 100644 hyperlpr_py3/deskew.py create mode 100644 hyperlpr_py3/detect.py create mode 100644 hyperlpr_py3/e2e.py create mode 100644 hyperlpr_py3/e2emodel.py create mode 100644 hyperlpr_py3/finemapping.py create mode 100644 hyperlpr_py3/finemapping_vertical.py create mode 100644 hyperlpr_py3/niblack_thresholding.py create mode 100644 hyperlpr_py3/pipline.py create mode 100644 hyperlpr_py3/plateStructure.py create mode 100644 hyperlpr_py3/precise.py create mode 100644 hyperlpr_py3/recognizer.py create mode 100644 hyperlpr_py3/segmentation.py create mode 100644 hyperlpr_py3/typeDistinguish.py diff --git a/hyperlpr_py3/__init__.py b/hyperlpr_py3/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hyperlpr_py3/cache.py b/hyperlpr_py3/cache.py new file mode 100644 index 0000000..80a2953 --- /dev/null +++ b/hyperlpr_py3/cache.py @@ -0,0 +1,11 @@ +import cv2 +import os +import hashlib + +def verticalMappingToFolder(image): + name = hashlib.md5(image.data).hexdigest()[:8] + print(name) + + cv2.imwrite("./cache/finemapping/"+name+".png",image) + + diff --git a/hyperlpr_py3/colourDetection.py b/hyperlpr_py3/colourDetection.py new file mode 100644 index 0000000..78c5854 --- /dev/null +++ b/hyperlpr_py3/colourDetection.py @@ -0,0 +1,103 @@ +# -- coding: UTF-8 +import cv2 +import matplotlib.pyplot as plt +from sklearn.cluster import KMeans +import os + +boundaries = [ + ([100,80,0],[240,220,110]), # yellow + ([0,40,50],[110,180,250]), # blue + ([0,60,0],[60,160,70]), # green +] +color_attr = ["黄牌","蓝牌",'绿牌','白牌','黑牌'] + +threhold_green = 13 +threhold_blue = 13 +threhold_yellow1 = 50 +threhold_yellow2 = 70 + +# plt.figure() +# plt.axis("off") +# plt.imshow(image) +# plt.show() + +import numpy as np +def centroid_histogram(clt): + numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1) + (hist, _) = np.histogram(clt.labels_, bins=numLabels) + + # normalize the histogram, such that it sums to one + hist = hist.astype("float") + hist /= hist.sum() + + # return the histogram + return hist + + +def plot_colors(hist, centroids): + bar = np.zeros((50, 300, 3), dtype="uint8") + startX = 0 + + for (percent, color) in zip(hist, centroids): + + endX = startX + (percent * 300) + cv2.rectangle(bar, (int(startX), 0), (int(endX), 50), + color.astype("uint8").tolist(), -1) + startX = endX + + # return the bar chart + return bar + +def search_boundaries(color): + for i,color_bound in enumerate(boundaries): + if np.all(color >= color_bound[0]) and np.all(color <= color_bound[1]): + return i + return -1 + +def judge_color(color): + r = color[0] + g = color[1] + b = color[2] + if g - r >= threhold_green and g - b >= threhold_green: + return 2 + if b - r >= threhold_blue and b - g >= threhold_blue: + return 1 + if r- b > threhold_yellow2 and g - b > threhold_yellow2: + return 0 + if r > 200 and b > 200 and g > 200: + return 3 + if r < 50 and b < 50 and g < 50: + return 4 + return -1 + +def judge_plate_color(img): + image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + image = image.reshape((image.shape[0] * image.shape[1], 3)) + clt = KMeans(n_clusters=2) + clt.fit(image) + + hist = centroid_histogram(clt) + index = np.argmax(hist) + #print clt.cluster_centers_[index] + #color_index = search_boundaries(clt.cluster_centers_[index]) + color_index = judge_color(clt.cluster_centers_[index]) + if color_index == -1: + if index == 0: + secound_index = 1 + else: + secound_index = 0 + color_index = judge_color(clt.cluster_centers_[secound_index]) + + if color_index == -1: + print(clt.cluster_centers_) + bar = plot_colors(hist, clt.cluster_centers_) + # show our color bart + plt.figure() + plt.axis("off") + plt.imshow(bar) + plt.show() + + if color_index != -1: + return color_attr[color_index],clt.cluster_centers_[index] + else: + return None,clt.cluster_centers_[index] \ No newline at end of file diff --git a/hyperlpr_py3/config.py b/hyperlpr_py3/config.py new file mode 100644 index 0000000..40f2099 --- /dev/null +++ b/hyperlpr_py3/config.py @@ -0,0 +1,6 @@ +import json + + + +with open("/Users/universe/ProgramUniverse/zeusees/HyperLPR/config.json") as f: + configuration = json.load(f) diff --git a/hyperlpr_py3/deskew.py b/hyperlpr_py3/deskew.py new file mode 100644 index 0000000..1a5ea42 --- /dev/null +++ b/hyperlpr_py3/deskew.py @@ -0,0 +1,100 @@ +#coding=utf-8 +import numpy as np +import cv2 +import time +from matplotlib import pyplot as plt +import math + +from scipy.ndimage import filters +# +# def strokeFiter(): +# pass; + +def angle(x,y): + return int(math.atan2(float(y),float(x))*180.0/3.1415) + + +def h_rot(src, angle, scale=1.0): + w = src.shape[1] + h = src.shape[0] + rangle = np.deg2rad(angle) + nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale + nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale + rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale) + rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0])) + rot_mat[0,2] += rot_move[0] + rot_mat[1,2] += rot_move[1] + return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4) + pass + + +def v_rot(img, angel, shape, max_angel): + size_o = [shape[1],shape[0]] + size = (shape[1]+ int(shape[0]*np.cos((float(max_angel )/180) * 3.14)),shape[0]) + interval = abs( int( np.sin((float(angel) /180) * 3.14)* shape[0])) + pts1 = np.float32([[0,0],[0,size_o[1]],[size_o[0],0],[size_o[0],size_o[1]]]) + if(angel>0): + pts2 = np.float32([[interval,0],[0,size[1] ],[size[0],0 ],[size[0]-interval,size_o[1]]]) + else: + pts2 = np.float32([[0,0],[interval,size[1] ],[size[0]-interval,0 ],[size[0],size_o[1]]]) + + M = cv2.getPerspectiveTransform(pts1,pts2) + dst = cv2.warpPerspective(img,M,size) + return dst,M + + +def skew_detection(image_gray): + h, w = image_gray.shape[:2] + eigen = cv2.cornerEigenValsAndVecs(image_gray,12, 5) + angle_sur = np.zeros(180,np.uint) + eigen = eigen.reshape(h, w, 3, 2) + flow = eigen[:,:,2] + vis = image_gray.copy() + vis[:] = (192 + np.uint32(vis)) / 2 + d = 12 + points = np.dstack( np.mgrid[d/2:w:d, d/2:h:d] ).reshape(-1, 2) + for x, y in points: + vx, vy = np.int32(flow[int(y), int(x)]*d) + # cv2.line(rgb, (x-vx, y-vy), (x+vx, y+vy), (0, 355, 0), 1, cv2.LINE_AA) + ang = angle(vx,vy) + angle_sur[(ang+180)%180] +=1 + + # torr_bin = 30 + angle_sur = angle_sur.astype(np.float) + angle_sur = (angle_sur-angle_sur.min())/(angle_sur.max()-angle_sur.min()) + angle_sur = filters.gaussian_filter1d(angle_sur,5) + skew_v_val = angle_sur[20:180-20].max() + skew_v = angle_sur[30:180-30].argmax() + 30 + skew_h_A = angle_sur[0:30].max() + skew_h_B = angle_sur[150:180].max() + skew_h = 0 + if (skew_h_A > skew_v_val*0.3 or skew_h_B > skew_v_val*0.3): + if skew_h_A>=skew_h_B: + skew_h = angle_sur[0:20].argmax() + else: + skew_h = - angle_sur[160:180].argmax() + return skew_h,skew_v + + +def fastDeskew(image): + image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) + skew_h,skew_v = skew_detection(image_gray) + print("校正角度 h ",skew_h,"v",skew_v) + deskew,M = v_rot(image,int((90-skew_v)*1.5),image.shape,60) + return deskew,M + + + +if __name__ == '__main__': + fn = './dataset/0.jpg' + + img = cv2.imread(fn) + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + skew_h,skew_v = skew_detection(gray) + img = v_rot(img,(90-skew_v ),img.shape,60) + # img = h_rot(img,skew_h) + # if img.shape[0]>img.shape[1]: + # img = h_rot(img, -90) + + plt.show() + cv2.waitKey() diff --git a/hyperlpr_py3/detect.py b/hyperlpr_py3/detect.py new file mode 100644 index 0000000..c4bc4ad --- /dev/null +++ b/hyperlpr_py3/detect.py @@ -0,0 +1,76 @@ + +import cv2 +import numpy as np + + + +watch_cascade = cv2.CascadeClassifier('./model/cascade.xml') + + +def computeSafeRegion(shape,bounding_rect): + top = bounding_rect[1] # y + bottom = bounding_rect[1] + bounding_rect[3] # y + h + left = bounding_rect[0] # x + right = bounding_rect[0] + bounding_rect[2] # x + w + + min_top = 0 + max_bottom = shape[0] + min_left = 0 + max_right = shape[1] + + # print "computeSateRegion input shape",shape + if top < min_top: + top = min_top + # print "tap top 0" + if left < min_left: + left = min_left + # print "tap left 0" + + if bottom > max_bottom: + bottom = max_bottom + #print "tap max_bottom max" + if right > max_right: + right = max_right + #print "tap max_right max" + + # print "corr",left,top,right,bottom + return [left,top,right-left,bottom-top] + + +def cropped_from_image(image,rect): + x, y, w, h = computeSafeRegion(image.shape,rect) + return image[y:y+h,x:x+w] + + +def detectPlateRough(image_gray,resize_h = 720,en_scale =1.08 ,top_bottom_padding_rate = 0.05): + print(image_gray.shape) + + if top_bottom_padding_rate>0.2: + print("error:top_bottom_padding_rate > 0.2:",top_bottom_padding_rate) + exit(1) + + height = image_gray.shape[0] + padding = int(height*top_bottom_padding_rate) + scale = image_gray.shape[1]/float(image_gray.shape[0]) + + image = cv2.resize(image_gray, (int(scale*resize_h), resize_h)) + + image_color_cropped = image[padding:resize_h-padding,0:image_gray.shape[1]] + + image_gray = cv2.cvtColor(image_color_cropped,cv2.COLOR_RGB2GRAY) + + watches = watch_cascade.detectMultiScale(image_gray, en_scale, 2, minSize=(36, 9),maxSize=(36*40, 9*40)) + + cropped_images = [] + for (x, y, w, h) in watches: + cropped_origin = cropped_from_image(image_color_cropped, (int(x), int(y), int(w), int(h))) + x -= w * 0.14 + w += w * 0.28 + y -= h * 0.6 + h += h * 1.1; + + cropped = cropped_from_image(image_color_cropped, (int(x), int(y), int(w), int(h))) + + + cropped_images.append([cropped,[x, y+padding, w, h],cropped_origin]) + return cropped_images diff --git a/hyperlpr_py3/e2e.py b/hyperlpr_py3/e2e.py new file mode 100644 index 0000000..d5d1159 --- /dev/null +++ b/hyperlpr_py3/e2e.py @@ -0,0 +1,63 @@ +#coding=utf-8 +from keras import backend as K +from keras.models import load_model +from keras.layers import * +import numpy as np +import random +import string + +import cv2 +from . import e2emodel as model +chars = ["京", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", + "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "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","港","学","使","警","澳","挂","军","北","南","广","沈","兰","成","济","海","民","航","空" + ]; +pred_model = model.construct_model("./model/ocr_plate_all_w_rnn_2.h5",) +import time + + + +def fastdecode(y_pred): + results = "" + confidence = 0.0 + table_pred = y_pred.reshape(-1, len(chars)+1) + + res = table_pred.argmax(axis=1) + + for i,one in enumerate(res): + if one=2: + [vx, vy, x, y] = cv2.fitLine(pts, cv2.DIST_HUBER, 0, 0.01, 0.01) + lefty = int((-x * vy / vx) + y) + righty = int(((136- x) * vy / vx) + y) + return lefty+30+zero_add,righty+30+zero_add + return 0,0 + + + +#精定位算法 +def findContoursAndDrawBoundingBox(image_rgb): + + + line_upper = []; + line_lower = []; + + line_experiment = [] + grouped_rects = [] + gray_image = cv2.cvtColor(image_rgb,cv2.COLOR_BGR2GRAY) + + # for k in np.linspace(-1.5, -0.2,10): + for k in np.linspace(-50, 0, 15): + + # thresh_niblack = threshold_niblack(gray_image, window_size=21, k=k) + # binary_niblack = gray_image > thresh_niblack + # binary_niblack = binary_niblack.astype(np.uint8) * 255 + + binary_niblack = cv2.adaptiveThreshold(gray_image,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,17,k) + # cv2.imshow("image1",binary_niblack) + # cv2.waitKey(0) + imagex, contours, hierarchy = cv2.findContours(binary_niblack.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) + for contour in contours: + bdbox = cv2.boundingRect(contour) + if (bdbox[3]/float(bdbox[2])>0.7 and bdbox[3]*bdbox[2]>100 and bdbox[3]*bdbox[2]<1200) or (bdbox[3]/float(bdbox[2])>3 and bdbox[3]*bdbox[2]<100): + # cv2.rectangle(rgb,(bdbox[0],bdbox[1]),(bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]),(255,0,0),1) + line_upper.append([bdbox[0],bdbox[1]]) + line_lower.append([bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]]) + + line_experiment.append([bdbox[0],bdbox[1]]) + line_experiment.append([bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]]) + # grouped_rects.append(bdbox) + + rgb = cv2.copyMakeBorder(image_rgb,30,30,0,0,cv2.BORDER_REPLICATE) + leftyA, rightyA = fitLine_ransac(np.array(line_lower),3) + rows,cols = rgb.shape[:2] + + # rgb = cv2.line(rgb, (cols - 1, rightyA), (0, leftyA), (0, 0, 255), 1,cv2.LINE_AA) + + leftyB, rightyB = fitLine_ransac(np.array(line_upper),-3) + + rows,cols = rgb.shape[:2] + + # rgb = cv2.line(rgb, (cols - 1, rightyB), (0, leftyB), (0,255, 0), 1,cv2.LINE_AA) + pts_map1 = np.float32([[cols - 1, rightyA], [0, leftyA],[cols - 1, rightyB], [0, leftyB]]) + pts_map2 = np.float32([[136,36],[0,36],[136,0],[0,0]]) + mat = cv2.getPerspectiveTransform(pts_map1,pts_map2) + image = cv2.warpPerspective(rgb,mat,(136,36),flags=cv2.INTER_CUBIC) + image,M = deskew.fastDeskew(image) + + return image + + + +#多级 +def findContoursAndDrawBoundingBox2(image_rgb): + + + line_upper = []; + line_lower = []; + + line_experiment = [] + + grouped_rects = [] + + gray_image = cv2.cvtColor(image_rgb,cv2.COLOR_BGR2GRAY) + + for k in np.linspace(-1.6, -0.2,10): + # for k in np.linspace(-15, 0, 15): + # # + # thresh_niblack = threshold_niblack(gray_image, window_size=21, k=k) + # binary_niblack = gray_image > thresh_niblack + # binary_niblack = binary_niblack.astype(np.uint8) * 255 + + binary_niblack = nt.niBlackThreshold(gray_image,19,k) + # cv2.imshow("binary_niblack_opencv",binary_niblack_) + # cv2.imshow("binary_niblack_skimage", binary_niblack) + + # cv2.waitKey(0) + imagex, contours, hierarchy = cv2.findContours(binary_niblack.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) + + for contour in contours: + bdbox = cv2.boundingRect(contour) + if (bdbox[3]/float(bdbox[2])>0.7 and bdbox[3]*bdbox[2]>100 and bdbox[3]*bdbox[2]<1000) or (bdbox[3]/float(bdbox[2])>3 and bdbox[3]*bdbox[2]<100): + # cv2.rectangle(rgb,(bdbox[0],bdbox[1]),(bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]),(255,0,0),1) + line_upper.append([bdbox[0],bdbox[1]]) + line_lower.append([bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]]) + + line_experiment.append([bdbox[0],bdbox[1]]) + line_experiment.append([bdbox[0]+bdbox[2],bdbox[1]+bdbox[3]]) + # grouped_rects.append(bdbox) + + rgb = cv2.copyMakeBorder(image_rgb,30,30,0,0,cv2.BORDER_REPLICATE) + leftyA, rightyA = fitLine_ransac(np.array(line_lower),2) + rows,cols = rgb.shape[:2] + + # rgb = cv2.line(rgb, (cols - 1, rightyA), (0, leftyA), (0, 0, 255), 1,cv2.LINE_AA) + + leftyB, rightyB = fitLine_ransac(np.array(line_upper),-4) + + rows,cols = rgb.shape[:2] + + # rgb = cv2.line(rgb, (cols - 1, rightyB), (0, leftyB), (0,255, 0), 1,cv2.LINE_AA) + pts_map1 = np.float32([[cols - 1, rightyA], [0, leftyA],[cols - 1, rightyB], [0, leftyB]]) + pts_map2 = np.float32([[136,36],[0,36],[136,0],[0,0]]) + mat = cv2.getPerspectiveTransform(pts_map1,pts_map2) + image = cv2.warpPerspective(rgb,mat,(136,36),flags=cv2.INTER_CUBIC) + image,M= deskew.fastDeskew(image) + + + return image diff --git a/hyperlpr_py3/finemapping_vertical.py b/hyperlpr_py3/finemapping_vertical.py new file mode 100644 index 0000000..83cbcf4 --- /dev/null +++ b/hyperlpr_py3/finemapping_vertical.py @@ -0,0 +1,92 @@ +#coding=utf-8 +from keras.layers import Conv2D, Input,MaxPool2D, Reshape,Activation,Flatten, Dense +from keras.models import Model, Sequential +from keras.layers.advanced_activations import PReLU +from keras.optimizers import adam +import numpy as np + +import cv2 + +def getModel(): + input = Input(shape=[16, 66, 3]) # change this shape to [None,None,3] to enable arbitraty shape input + x = Conv2D(10, (3, 3), strides=1, padding='valid', name='conv1')(input) + x = Activation("relu", name='relu1')(x) + x = MaxPool2D(pool_size=2)(x) + x = Conv2D(16, (3, 3), strides=1, padding='valid', name='conv2')(x) + x = Activation("relu", name='relu2')(x) + x = Conv2D(32, (3, 3), strides=1, padding='valid', name='conv3')(x) + x = Activation("relu", name='relu3')(x) + x = Flatten()(x) + output = Dense(2,name = "dense")(x) + output = Activation("relu", name='relu4')(output) + model = Model([input], [output]) + return model + + + +model = getModel() +model.load_weights("./model/model12.h5") + + +def getmodel(): + return model + +def gettest_model(): + input = Input(shape=[16, 66, 3]) # change this shape to [None,None,3] to enable arbitraty shape input + A = Conv2D(10, (3, 3), strides=1, padding='valid', name='conv1')(input) + B = Activation("relu", name='relu1')(A) + C = MaxPool2D(pool_size=2)(B) + x = Conv2D(16, (3, 3), strides=1, padding='valid', name='conv2')(C) + x = Activation("relu", name='relu2')(x) + x = Conv2D(32, (3, 3), strides=1, padding='valid', name='conv3')(x) + K = Activation("relu", name='relu3')(x) + + + x = Flatten()(K) + dense = Dense(2,name = "dense")(x) + output = Activation("relu", name='relu4')(dense) + x = Model([input], [output]) + x.load_weights("./model/model12.h5") + ok = Model([input], [dense]) + + for layer in ok.layers: + print(layer) + + return ok + + + + +def finemappingVertical(image): + resized = cv2.resize(image,(66,16)) + resized = resized.astype(np.float)/255 + res= model.predict(np.array([resized]))[0] + print("keras_predict",res) + res =res*image.shape[1] + res = res.astype(np.int) + H,T = res + H-=3 + #3 79.86 + #4 79.3 + #5 79.5 + #6 78.3 + + + #T + #T+1 80.9 + #T+2 81.75 + #T+3 81.75 + + + + if H<0: + H=0 + T+=2; + + if T>= image.shape[1]-1: + T= image.shape[1]-1 + + image = image[0:35,H:T+2] + + image = cv2.resize(image, (int(136), int(36))) + return image \ No newline at end of file diff --git a/hyperlpr_py3/niblack_thresholding.py b/hyperlpr_py3/niblack_thresholding.py new file mode 100644 index 0000000..652bae0 --- /dev/null +++ b/hyperlpr_py3/niblack_thresholding.py @@ -0,0 +1,18 @@ +import cv2 +import numpy as np + + + +def niBlackThreshold( src, blockSize, k, binarizationMethod= 0 ): + mean = cv2.boxFilter(src,cv2.CV_32F,(blockSize, blockSize),borderType=cv2.BORDER_REPLICATE) + sqmean = cv2.sqrBoxFilter(src, cv2.CV_32F, (blockSize, blockSize), borderType = cv2.BORDER_REPLICATE) + variance = sqmean - (mean*mean) + stddev = np.sqrt(variance) + thresh = mean + stddev * float(-k) + thresh = thresh.astype(src.dtype) + k = (src>thresh)*255 + k = k.astype(np.uint8) + return k + + +# cv2.imshow() \ No newline at end of file diff --git a/hyperlpr_py3/pipline.py b/hyperlpr_py3/pipline.py new file mode 100644 index 0000000..3a37dd3 --- /dev/null +++ b/hyperlpr_py3/pipline.py @@ -0,0 +1,246 @@ +#coding=utf-8 +from . import detect +from . import finemapping as fm + +from . import segmentation +import cv2 + +import time +import numpy as np + +from PIL import ImageFont +from PIL import Image +from PIL import ImageDraw +import json + +import sys +from . import typeDistinguish as td +import imp + + +imp.reload(sys) +fontC = ImageFont.truetype("./Font/platech.ttf", 14, 0); + +from . import e2e +#寻找车牌左右边界 + +def find_edge(image): + sum_i = image.sum(axis=0) + sum_i = sum_i.astype(np.float) + sum_i/=image.shape[0]*255 + # print sum_i + + start= 0 ; + end = image.shape[1]-1 + + for i,one in enumerate(sum_i): + if one>0.4: + start = i; + if start-3<0: + start = 0 + else: + start -=3 + + break; + for i,one in enumerate(sum_i[::-1]): + + if one>0.4: + end = end - i; + if end+4>image.shape[1]-1: + end = image.shape[1]-1 + else: + end+=4 + break + return start,end + + +#垂直边缘检测 +def verticalEdgeDetection(image): + image_sobel = cv2.Sobel(image.copy(),cv2.CV_8U,1,0) + # image = auto_canny(image_sobel) + + # img_sobel, CV_8U, 1, 0, 3, 1, 0, BORDER_DEFAULT + # canny_image = auto_canny(image) + flag,thres = cv2.threshold(image_sobel,0,255,cv2.THRESH_OTSU|cv2.THRESH_BINARY) + print(flag) + flag,thres = cv2.threshold(image_sobel,int(flag*0.7),255,cv2.THRESH_BINARY) + # thres = simpleThres(image_sobel) + kernal = np.ones(shape=(3,15)) + thres = cv2.morphologyEx(thres,cv2.MORPH_CLOSE,kernal) + return thres + + +#确定粗略的左右边界 +def horizontalSegmentation(image): + + thres = verticalEdgeDetection(image) + # thres = thres*image + head,tail = find_edge(thres) + # print head,tail + # cv2.imshow("edge",thres) + tail = tail+5 + if tail>135: + tail = 135 + image = image[0:35,head:tail] + image = cv2.resize(image, (int(136), int(36))) + return image + + +#打上boundingbox和标签 +def drawRectBox(image,rect,addText): + cv2.rectangle(image, (int(rect[0]), int(rect[1])), (int(rect[0] + rect[2]), int(rect[1] + rect[3])), (0,0, 255), 2, cv2.LINE_AA) + cv2.rectangle(image, (int(rect[0]-1), int(rect[1])-16), (int(rect[0] + 115), int(rect[1])), (0, 0, 255), -1, cv2.LINE_AA) + + img = Image.fromarray(image) + draw = ImageDraw.Draw(img) + #draw.text((int(rect[0]+1), int(rect[1]-16)), addText.decode("utf-8"), (255, 255, 255), font=fontC) + draw.text((int(rect[0]+1), int(rect[1]-16)), addText, (255, 255, 255), font=fontC) + imagex = np.array(img) + + return imagex + + +from . import cache +from . import finemapping_vertical as fv + +def RecognizePlateJson(image): + images = detect.detectPlateRough(image,image.shape[0],top_bottom_padding_rate=0.1) + jsons = [] + for j,plate in enumerate(images): + plate,rect,origin_plate =plate + res, confidence = e2e.recognizeOne(origin_plate) + print("res",res) + + cv2.imwrite("./"+str(j)+"_rough.jpg",plate) + + # print "车牌类型:",ptype + # plate = cv2.cvtColor(plate, cv2.COLOR_RGB2GRAY) + plate =cv2.resize(plate,(136,int(36*2.5))) + t1 = time.time() + + ptype = td.SimplePredict(plate) + if ptype>0 and ptype<4: + plate = cv2.bitwise_not(plate) + # demo = verticalEdgeDetection(plate) + + image_rgb = fm.findContoursAndDrawBoundingBox(plate) + image_rgb = fv.finemappingVertical(image_rgb) + cache.verticalMappingToFolder(image_rgb) + # print time.time() - t1,"校正" + print("e2e:",e2e.recognizeOne(image_rgb)[0]) + image_gray = cv2.cvtColor(image_rgb,cv2.COLOR_BGR2GRAY) + + cv2.imwrite("./"+str(j)+".jpg",image_gray) + # image_gray = horizontalSegmentation(image_gray) + + t2 = time.time() + res, confidence = e2e.recognizeOne(image_rgb) + res_json = {} + if confidence > 0.6: + res_json["Name"] = res + res_json["Type"] = td.plateType[ptype] + res_json["Confidence"] = confidence; + res_json["x"] = int(rect[0]) + res_json["y"] = int(rect[1]) + res_json["w"] = int(rect[2]) + res_json["h"] = int(rect[3]) + jsons.append(res_json) + print(json.dumps(jsons,ensure_ascii=False,encoding="gb2312")) + + return json.dumps(jsons,ensure_ascii=False,encoding="gb2312") + + + + +def SimpleRecognizePlateByE2E(image): + t0 = time.time() + images = detect.detectPlateRough(image,image.shape[0],top_bottom_padding_rate=0.1) + res_set = [] + for j,plate in enumerate(images): + plate, rect, origin_plate =plate + # plate = cv2.cvtColor(plate, cv2.COLOR_RGB2GRAY) + plate =cv2.resize(plate,(136,36*2)) + res,confidence = e2e.recognizeOne(origin_plate) + print("res",res) + + t1 = time.time() + ptype = td.SimplePredict(plate) + if ptype>0 and ptype<5: + # pass + plate = cv2.bitwise_not(plate) + image_rgb = fm.findContoursAndDrawBoundingBox(plate) + image_rgb = fv.finemappingVertical(image_rgb) + image_rgb = fv.finemappingVertical(image_rgb) + cache.verticalMappingToFolder(image_rgb) + cv2.imwrite("./"+str(j)+".jpg",image_rgb) + res,confidence = e2e.recognizeOne(image_rgb) + print(res,confidence) + res_set.append([[],res,confidence]) + + if confidence>0.7: + image = drawRectBox(image, rect, res+" "+str(round(confidence,3))) + return image,res_set + + +def SimpleRecognizePlate(image): + t0 = time.time() + images = detect.detectPlateRough(image,image.shape[0],top_bottom_padding_rate=0.1) + res_set = [] + for j,plate in enumerate(images): + plate, rect, origin_plate =plate + # plate = cv2.cvtColor(plate, cv2.COLOR_RGB2GRAY) + plate =cv2.resize(plate,(136,36*2)) + t1 = time.time() + + ptype = td.SimplePredict(plate) + if ptype>0 and ptype<5: + plate = cv2.bitwise_not(plate) + + image_rgb = fm.findContoursAndDrawBoundingBox(plate) + + image_rgb = fv.finemappingVertical(image_rgb) + cache.verticalMappingToFolder(image_rgb) + print("e2e:", e2e.recognizeOne(image_rgb)) + image_gray = cv2.cvtColor(image_rgb,cv2.COLOR_RGB2GRAY) + + # image_gray = horizontalSegmentation(image_gray) + cv2.imshow("image_gray",image_gray) + # cv2.waitKey() + + cv2.imwrite("./"+str(j)+".jpg",image_gray) + # cv2.imshow("image",image_gray) + # cv2.waitKey(0) + print("校正",time.time() - t1,"s") + # cv2.imshow("image,",image_gray) + # cv2.waitKey(0) + t2 = time.time() + val = segmentation.slidingWindowsEval(image_gray) + # print val + print("分割和识别",time.time() - t2,"s") + if len(val)==3: + blocks, res, confidence = val + if confidence/7>0.7: + image = drawRectBox(image,rect,res) + res_set.append(res) + for i,block in enumerate(blocks): + + block_ = cv2.resize(block,(25,25)) + block_ = cv2.cvtColor(block_,cv2.COLOR_GRAY2BGR) + image[j * 25:(j * 25) + 25, i * 25:(i * 25) + 25] = block_ + if image[j*25:(j*25)+25,i*25:(i*25)+25].shape == block_.shape: + pass + + + if confidence>0: + print("车牌:",res,"置信度:",confidence/7) + else: + pass + + # print "不确定的车牌:", res, "置信度:", confidence + + print(time.time() - t0,"s") + return image,res_set + + + + diff --git a/hyperlpr_py3/plateStructure.py b/hyperlpr_py3/plateStructure.py new file mode 100644 index 0000000..e69de29 diff --git a/hyperlpr_py3/precise.py b/hyperlpr_py3/precise.py new file mode 100644 index 0000000..e69de29 diff --git a/hyperlpr_py3/recognizer.py b/hyperlpr_py3/recognizer.py new file mode 100644 index 0000000..72171b3 --- /dev/null +++ b/hyperlpr_py3/recognizer.py @@ -0,0 +1,154 @@ +#coding=utf-8 +from keras.models import Sequential +from keras.layers import Dense, Dropout, Activation, Flatten +from keras.layers import Conv2D,MaxPool2D +from keras.optimizers import SGD +from keras import backend as K + +K.set_image_dim_ordering('tf') + + +import cv2 +import numpy as np + + + +index = {"京": 0, "沪": 1, "津": 2, "渝": 3, "冀": 4, "晋": 5, "蒙": 6, "辽": 7, "吉": 8, "黑": 9, "苏": 10, "浙": 11, "皖": 12, + "闽": 13, "赣": 14, "鲁": 15, "豫": 16, "鄂": 17, "湘": 18, "粤": 19, "桂": 20, "琼": 21, "川": 22, "贵": 23, "云": 24, + "藏": 25, "陕": 26, "甘": 27, "青": 28, "宁": 29, "新": 30, "0": 31, "1": 32, "2": 33, "3": 34, "4": 35, "5": 36, + "6": 37, "7": 38, "8": 39, "9": 40, "A": 41, "B": 42, "C": 43, "D": 44, "E": 45, "F": 46, "G": 47, "H": 48, + "J": 49, "K": 50, "L": 51, "M": 52, "N": 53, "P": 54, "Q": 55, "R": 56, "S": 57, "T": 58, "U": 59, "V": 60, + "W": 61, "X": 62, "Y": 63, "Z": 64,"港":65,"学":66 ,"O":67 ,"使":68,"警":69,"澳":70,"挂":71}; + +chars = ["京", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", + "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "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","港","学","O","使","警","澳","挂" ]; + + + +def Getmodel_tensorflow(nb_classes): + # nb_classes = len(charset) + + img_rows, img_cols = 23, 23 + # number of convolutional filters to use + nb_filters = 32 + # size of pooling area for max pooling + nb_pool = 2 + # convolution kernel size + nb_conv = 3 + + # x = np.load('x.npy') + + # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes) + # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3 + # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先 + + model = Sequential() + model.add(Conv2D(32, (5, 5),input_shape=(img_rows, img_cols,1))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Dropout(0.25)) + model.add(Conv2D(32, (3, 3))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Dropout(0.25)) + model.add(Conv2D(512, (3, 3))) + # model.add(Activation('relu')) + # model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool))) + # model.add(Dropout(0.25)) + model.add(Flatten()) + model.add(Dense(512)) + model.add(Activation('relu')) + model.add(Dropout(0.5)) + model.add(Dense(nb_classes)) + model.add(Activation('softmax')) + model.compile(loss='categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + return model + + + + +def Getmodel_ch(nb_classes): + # nb_classes = len(charset) + + img_rows, img_cols = 23, 23 + # number of convolutional filters to use + nb_filters = 32 + # size of pooling area for max pooling + nb_pool = 2 + # convolution kernel size + nb_conv = 3 + + # x = np.load('x.npy') + # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes) + # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3 + # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先 + + model = Sequential() + model.add(Conv2D(32, (5, 5),input_shape=(img_rows, img_cols,1))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Dropout(0.25)) + model.add(Conv2D(32, (3, 3))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Dropout(0.25)) + model.add(Conv2D(512, (3, 3))) + # model.add(Activation('relu')) + # model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool))) + # model.add(Dropout(0.25)) + model.add(Flatten()) + model.add(Dense(756)) + model.add(Activation('relu')) + model.add(Dropout(0.5)) + model.add(Dense(nb_classes)) + model.add(Activation('softmax')) + model.compile(loss='categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + return model + + + +model = Getmodel_tensorflow(65) +#构建网络 + +model_ch = Getmodel_ch(31) + +model_ch.load_weights("./model/char_chi_sim.h5") +# model_ch.save_weights("./model/char_chi_sim.h5") +model.load_weights("./model/char_rec.h5") +# model.save("./model/char_rec.h5") + + +def SimplePredict(image,pos): + image = cv2.resize(image, (23, 23)) + image = cv2.equalizeHist(image) + image = image.astype(np.float) / 255 + image -= image.mean() + image = np.expand_dims(image, 3) + if pos!=0: + res = np.array(model.predict(np.array([image]))[0]) + else: + res = np.array(model_ch.predict(np.array([image]))[0]) + + zero_add = 0 ; + + if pos==0: + res = res[:31] + elif pos==1: + res = res[31+10:65] + zero_add = 31+10 + else: + res = res[31:] + zero_add = 31 + + max_id = res.argmax() + + + return res.max(),chars[max_id+zero_add],max_id+zero_add + diff --git a/hyperlpr_py3/segmentation.py b/hyperlpr_py3/segmentation.py new file mode 100644 index 0000000..3e9c335 --- /dev/null +++ b/hyperlpr_py3/segmentation.py @@ -0,0 +1,307 @@ +#coding=utf-8 +import cv2 +import numpy as np + +# from matplotlib import pyplot as plt +import scipy.ndimage.filters as f +import scipy + +import time +import scipy.signal as l + + + + + +from keras.models import Sequential +from keras.layers import Dense, Dropout, Activation, Flatten +from keras.layers import Conv2D, MaxPool2D +from keras.optimizers import SGD +from keras import backend as K + +K.set_image_dim_ordering('tf') + + +def Getmodel_tensorflow(nb_classes): + # nb_classes = len(charset) + img_rows, img_cols = 23, 23 + # number of convolutional filters to use + nb_filters = 16 + # size of pooling area for max pooling + nb_pool = 2 + # convolution kernel size + nb_conv = 3 + # x = np.load('x.npy') + # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes) + # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3 + # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先 + + model = Sequential() + model.add(Conv2D(nb_filters, (nb_conv, nb_conv),input_shape=(img_rows, img_cols,1))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Conv2D(nb_filters, (nb_conv, nb_conv))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Flatten()) + model.add(Dense(256)) + model.add(Dropout(0.5)) + + model.add(Activation('relu')) + model.add(Dense(nb_classes)) + model.add(Activation('softmax')) + model.compile(loss='categorical_crossentropy', + optimizer='sgd', + metrics=['accuracy']) + return model + + + +def Getmodel_tensorflow_light(nb_classes): + # nb_classes = len(charset) + img_rows, img_cols = 23, 23 + # number of convolutional filters to use + nb_filters = 8 + # size of pooling area for max pooling + nb_pool = 2 + # convolution kernel size + nb_conv = 3 + # x = np.load('x.npy') + # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes) + # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3 + # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先 + + model = Sequential() + model.add(Conv2D(nb_filters, (nb_conv, nb_conv),input_shape=(img_rows, img_cols, 1))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Conv2D(nb_filters, (nb_conv * 2, nb_conv * 2))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Flatten()) + model.add(Dense(32)) + # model.add(Dropout(0.25)) + + model.add(Activation('relu')) + model.add(Dense(nb_classes)) + model.add(Activation('softmax')) + model.compile(loss='categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + return model + + + + +model = Getmodel_tensorflow_light(3) +model2 = Getmodel_tensorflow(3) + +import os +model.load_weights("./model/char_judgement1.h5") +# model.save("./model/char_judgement1.h5") +model2.load_weights("./model/char_judgement.h5") +# model2.save("./model/char_judgement.h5") + + +model = model2 +def get_median(data): + data = sorted(data) + size = len(data) + # print size + + if size % 2 == 0: # 判断列表长度为偶数 + median = (data[size//2]+data[size//2-1])/2 + data[0] = median + if size % 2 == 1: # 判断列表长度为奇数 + median = data[(size-1)//2] + data[0] = median + return data[0] +import time + +def searchOptimalCuttingPoint(rgb,res_map,start,width_boundingbox,interval_range): + t0 = time.time() + # + # for x in xrange(10): + # res_map = np.vstack((res_map,res_map[-1])) + length = res_map.shape[0] + refine_s = -2; + + if width_boundingbox>20: + refine_s = -9 + score_list = [] + interval_big = int(width_boundingbox * 0.3) # + p = 0 + for zero_add in range(start,start+50,3): + # for interval_small in xrange(-0,width_boundingbox/2): + for i in range(-8,int(width_boundingbox/1)-8): + for refine in range(refine_s, int(width_boundingbox/2+3)): + p1 = zero_add# this point is province + p2 = p1 + width_boundingbox +refine # + p3 = p2 + width_boundingbox + interval_big+i+1 + p4 = p3 + width_boundingbox +refine + p5 = p4 + width_boundingbox +refine + p6 = p5 + width_boundingbox +refine + p7 = p6 + width_boundingbox +refine + if p7>=length: + continue + score = res_map[p1][2]*3 -(res_map[p3][1]+res_map[p4][1]+res_map[p5][1]+res_map[p6][1]+res_map[p7][1])+7 + # print score + score_list.append([score,[p1,p2,p3,p4,p5,p6,p7]]) + p+=1 + print(p) + + score_list = sorted(score_list , key=lambda x:x[0]) + # for one in score_list[-1][1]: + # cv2.line(debug,(one,0),(one,36),(255,0,0),1) + # # + # cv2.imshow("one",debug) + # cv2.waitKey(0) + # + print("寻找最佳点",time.time()-t0) + return score_list[-1] + + +import sys + +sys.path.append('../') +from . import recognizer as cRP +from . import niblack_thresholding as nt + +def refineCrop(sections,width=16): + new_sections = [] + for section in sections: + # cv2.imshow("section¡",section) + + # cv2.blur(section,(3,3),3) + + sec_center = np.array([section.shape[1]/2,section.shape[0]/2]) + binary_niblack = nt.niBlackThreshold(section,17,-0.255) + imagex, contours, hierarchy = cv2.findContours(binary_niblack,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) + boxs = [] + for contour in contours: + x,y,w,h = cv2.boundingRect(contour) + + ratio = w/float(h) + if ratio<1 and h>36*0.4 and y<16\ + : + box = [x,y,w,h] + + boxs.append([box,np.array([x+w/2,y+h/2])]) + # cv2.rectangle(section,(x,y),(x+w,y+h),255,1) + + + + + # print boxs + + dis_ = np.array([ ((one[1]-sec_center)**2).sum() for one in boxs]) + if len(dis_)==0: + kernal = [0, 0, section.shape[1], section.shape[0]] + else: + kernal = boxs[dis_.argmin()][0] + + center_c = (kernal[0]+kernal[2]/2,kernal[1]+kernal[3]/2) + w_2 = int(width/2) + h_2 = kernal[3]/2 + + if center_c[0] - w_2< 0: + w_2 = center_c[0] + new_box = [center_c[0] - w_2,kernal[1],width,kernal[3]] + # print new_box[2]/float(new_box[3]) + if new_box[2]/float(new_box[3])>0.5: + # print "异常" + h = int((new_box[2]/0.35 )/2) + if h>35: + h = 35 + new_box[1] = center_c[1]- h + if new_box[1]<0: + new_box[1] = 1 + new_box[3] = h*2 + + section = section[int(new_box[1]):int(new_box[1]+new_box[3]), int(new_box[0]):int(new_box[0]+new_box[2])] + # cv2.imshow("section",section) + # cv2.waitKey(0) + new_sections.append(section) + # print new_box + return new_sections + + +def slidingWindowsEval(image): + windows_size = 16; + stride = 1 + height= image.shape[0] + t0 = time.time() + data_sets = [] + + for i in range(0,image.shape[1]-windows_size+1,stride): + data = image[0:height,i:i+windows_size] + data = cv2.resize(data,(23,23)) + # cv2.imshow("image",data) + data = cv2.equalizeHist(data) + data = data.astype(np.float)/255 + data= np.expand_dims(data,3) + data_sets.append(data) + + res = model2.predict(np.array(data_sets)) + print("分割",time.time() - t0) + + pin = res + p = 1 - (res.T)[1] + p = f.gaussian_filter1d(np.array(p,dtype=np.float),3) + lmin = l.argrelmax(np.array(p),order = 3)[0] + interval = [] + for i in range(len(lmin)-1): + interval.append(lmin[i+1]-lmin[i]) + + if(len(interval)>3): + mid = get_median(interval) + else: + return [] + pin = np.array(pin) + res = searchOptimalCuttingPoint(image,pin,0,mid,3) + + cutting_pts = res[1] + last = cutting_pts[-1] + mid + if last < image.shape[1]: + cutting_pts.append(last) + else: + cutting_pts.append(image.shape[1]-1) + name = "" + confidence =0.00 + seg_block = [] + for x in range(1,len(cutting_pts)): + if x != len(cutting_pts)-1 and x!=1: + section = image[0:36,cutting_pts[x-1]-2:cutting_pts[x]+2] + elif x==1: + c_head = cutting_pts[x - 1]- 2 + if c_head<0: + c_head=0 + c_tail = cutting_pts[x] + 2 + section = image[0:36, c_head:c_tail] + elif x==len(cutting_pts)-1: + end = cutting_pts[x] + diff = image.shape[1]-end + c_head = cutting_pts[x - 1] + c_tail = cutting_pts[x] + if diff<7 : + section = image[0:36, c_head-5:c_tail+5] + else: + diff-=1 + section = image[0:36, c_head - diff:c_tail + diff] + elif x==2: + section = image[0:36, cutting_pts[x - 1] - 3:cutting_pts[x-1]+ mid] + else: + section = image[0:36,cutting_pts[x-1]:cutting_pts[x]] + seg_block.append(section) + refined = refineCrop(seg_block,mid-1) + + t0 = time.time() + for i,one in enumerate(refined): + res_pre = cRP.SimplePredict(one, i ) + # cv2.imshow(str(i),one) + # cv2.waitKey(0) + confidence+=res_pre[0] + name+= res_pre[1] + print("字符识别",time.time() - t0) + + return refined,name,confidence diff --git a/hyperlpr_py3/typeDistinguish.py b/hyperlpr_py3/typeDistinguish.py new file mode 100644 index 0000000..d3e538a --- /dev/null +++ b/hyperlpr_py3/typeDistinguish.py @@ -0,0 +1,56 @@ +#coding=utf-8 +from keras.models import Sequential +from keras.layers import Dense, Dropout, Activation, Flatten +from keras.layers import Conv2D, MaxPool2D +from keras.optimizers import SGD +from keras import backend as K + +K.set_image_dim_ordering('tf') + + +import cv2 +import numpy as np + + +plateType = ["蓝牌","单层黄牌","新能源车牌","白色","黑色-港澳"] +def Getmodel_tensorflow(nb_classes): + # nb_classes = len(charset) + + img_rows, img_cols = 9, 34 + # number of convolutional filters to use + nb_filters = 32 + # size of pooling area for max pooling + nb_pool = 2 + # convolution kernel size + nb_conv = 3 + + # x = np.load('x.npy') + # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes) + # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3 + # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先 + + model = Sequential() + model.add(Conv2D(16, (5, 5),input_shape=(img_rows, img_cols,3))) + model.add(Activation('relu')) + model.add(MaxPool2D(pool_size=(nb_pool, nb_pool))) + model.add(Flatten()) + model.add(Dense(64)) + model.add(Activation('relu')) + model.add(Dropout(0.5)) + model.add(Dense(nb_classes)) + model.add(Activation('softmax')) + model.compile(loss='categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) + return model + +model = Getmodel_tensorflow(5) +model.load_weights("./model/plate_type.h5") +model.save("./model/plate_type.h5") +def SimplePredict(image): + image = cv2.resize(image, (34, 9)) + image = image.astype(np.float) / 255 + res = np.array(model.predict(np.array([image]))[0]) + return res.argmax() + +