This commit is contained in:
jackyu
2017-09-25 11:23:13 +08:00
parent e4e9edd51a
commit 088171eaae
2875 changed files with 14384 additions and 1 deletions
View File
Binary file not shown.
+11
View File
@@ -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)
Binary file not shown.
+111
View File
@@ -0,0 +1,111 @@
#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.):
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;
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[y, 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 = v_rot(image,int((90-skew_v)*1.5),image.shape,60)
return deskew
if __name__ == '__main__':
fn = 'test_data/test4.png'
img = cv2.imread(fn)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
skew_h,skew_v = skew_detection(img,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()
Binary file not shown.
+76
View File
@@ -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
Binary file not shown.
+130
View File
@@ -0,0 +1,130 @@
#coding=utf-8
import cv2
import numpy as np
from skimage.filters import (threshold_otsu, threshold_niblack,
threshold_sauvola)
import niblack_thresholding as nt
import deskew
def fitLine_ransac(pts,zero_add = 0 ):
if len(pts)>=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 = 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 = deskew.fastDeskew(image)
return image
Binary file not shown.
+39
View File
@@ -0,0 +1,39 @@
#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=[12, 50, 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 = PReLU(shared_axes=[1, 2], name='prelu1')(x)
x = MaxPool2D(pool_size=2)(x)
x = Conv2D(16, (3, 3), strides=1, padding='valid', name='conv2')(x)
x = PReLU(shared_axes=[1, 2], name='prelu2')(x)
x = Conv2D(32, (3, 3), strides=1, padding='valid', name='conv3')(x)
x = PReLU(shared_axes=[1, 2], name='prelu3')(x)
x = Flatten()(x)
output = Dense(2)(x)
output = PReLU(name='prelu4')(output)
model = Model([input], [output])
return model
model = getModel()
model.load_weights("./model/model12.h5")
def finemappingVertical(image):
resized = cv2.resize(image,(50,12))
resized = resized.astype(np.float)/255
res= model.predict(np.array([resized]))[0]
res =res*image.shape[1]
res = res.astype(np.int)
image = image[0:35,res[0]+4:res[1]]
image = cv2.resize(image, (int(136), int(36)))
return image
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
import cv2
import numpy as np
from skimage.filters import (threshold_otsu, threshold_niblack,
threshold_sauvola)
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()
Binary file not shown.
+247
View File
@@ -0,0 +1,247 @@
#coding=utf-8
import detect
import finemapping as fm
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
import typeDistinguish as td
reload(sys)
sys.setdefaultencoding("utf-8")
fontC = ImageFont.truetype("./Font/platech.ttf", 14, 0);
#寻找车牌左右边界
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] + 80), 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)
imagex = np.array(img)
return imagex
import cache
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
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<5:
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,"校正"
image_gray = cv2.cvtColor(image_rgb,cv2.COLOR_BGR2GRAY)
cv2.imwrite("./"+str(j)+".jpg",image_gray)
# image_gray = horizontalSegmentation(image_gray)
t2 = time.time()
val = segmentation.slidingWindowsEval(image_gray)
if len(val)==3:
blocks, res, confidence = val
if confidence/7>0.0:
image = drawRectBox(image,rect,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
plate_name = res
res_json = {}
if confidence/7>0.0:
res_json["Name"] = plate_name.decode()
res_json["Type"] = td.plateType[ptype]
res_json["Confidence"] = confidence/7;
res_json["x"] = int(rect[0])
res_json["y"] = int(rect[1])
res_json["w"] = int(rect[2])
res_json["h"] = int(rect[3])
# print "车牌:",res,"置信度:",confidence/7
jsons.append(res_json)
else:
pass
# print "不确定的车牌:", res, "置信度:", confidence
print jsons
print json.dumps(jsons,ensure_ascii=False,encoding="gb2312")
return json.dumps(jsons,ensure_ascii=False,encoding="gb2312")
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)
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
Binary file not shown.
View File
+156
View File
@@ -0,0 +1,156 @@
#coding=utf-8
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
from keras import backend as K
K.set_image_dim_ordering('tf')
import cv2
import numpy as np
index = {u"": 0, u"": 1, u"": 2, u"": 3, u"": 4, u"": 5, u"": 6, u"": 7, u"": 8, u"": 9, u"": 10, u"": 11, u"": 12,
u"": 13, u"": 14, u"": 15, u"": 16, u"": 17, u"": 18, u"": 19, u"": 20, u"": 21, u"": 22, u"": 23, u"": 24,
u"": 25, u"": 26, u"": 27, u"": 28, u"": 29, u"": 30, u"0": 31, u"1": 32, u"2": 33, u"3": 34, u"4": 35, u"5": 36,
u"6": 37, u"7": 38, u"8": 39, u"9": 40, u"A": 41, u"B": 42, u"C": 43, u"D": 44, u"E": 45, u"F": 46, u"G": 47, u"H": 48,
u"J": 49, u"K": 50, u"L": 51, u"M": 52, u"N": 53, u"P": 54, u"Q": 55, u"R": 56, u"S": 57, u"T": 58, u"U": 59, u"V": 60,
u"W": 61, u"X": 62, u"Y": 63, u"Z": 64,u"":65,u"":66 ,u"O":67 ,u"使":68,u"":69,u"":70,u"":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(Convolution2D(32, 5, 5,
border_mode='valid',
input_shape=(img_rows, img_cols,1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))
model.add(Convolution2D(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(Convolution2D(32, 5, 5,
border_mode='valid',
input_shape=(img_rows, img_cols,1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))
model.add(Convolution2D(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.load_weights("./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
Binary file not shown.
+323
View File
@@ -0,0 +1,323 @@
#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 Convolution2D, MaxPooling2D
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(Convolution2D(nb_filters, nb_conv, nb_conv,
border_mode='valid',
input_shape=(img_rows, img_cols,1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
model.add(Activation('relu'))
model.add(MaxPooling2D(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(Convolution2D(nb_filters, nb_conv, nb_conv,
border_mode='valid',
input_shape=(img_rows, img_cols, 1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Convolution2D(nb_filters, nb_conv * 2, nb_conv * 2))
model.add(Activation('relu'))
model.add(MaxPooling2D(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")
model2.load_weights("./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 xrange(start,start+50,3):
# for interval_small in xrange(-0,width_boundingbox/2):
for i in xrange(-8,int(width_boundingbox/1)-8):
for refine in xrange(refine_s,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('../')
import recognizer as cRP
from skimage.filters import (threshold_otsu, threshold_niblack,
threshold_sauvola)
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[new_box[1]:new_box[1]+new_box[3],new_box[0]: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 = model.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 xrange(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 xrange(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
Binary file not shown.
+57
View File
@@ -0,0 +1,57 @@
#coding=utf-8
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
from keras import backend as K
K.set_image_dim_ordering('tf')
import cv2
import numpy as np
plateType = [u"蓝牌",u"单层黄牌",u"新能源车牌",u"白色",u"黑色-港澳"]
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(Convolution2D(16, 5, 5,
border_mode='valid',
input_shape=(img_rows, img_cols,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(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")
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()
Binary file not shown.