You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

segmentation.py 9.8 kB

7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #coding=utf-8
  2. import cv2
  3. import numpy as np
  4. # from matplotlib import pyplot as plt
  5. import scipy.ndimage.filters as f
  6. import scipy
  7. import time
  8. import scipy.signal as l
  9. from keras.models import Sequential
  10. from keras.layers import Dense, Dropout, Activation, Flatten
  11. from keras.layers import Convolution2D, MaxPooling2D
  12. from keras.optimizers import SGD
  13. from keras import backend as K
  14. K.set_image_dim_ordering('tf')
  15. def Getmodel_tensorflow(nb_classes):
  16. # nb_classes = len(charset)
  17. img_rows, img_cols = 23, 23
  18. # number of convolutional filters to use
  19. nb_filters = 16
  20. # size of pooling area for max pooling
  21. nb_pool = 2
  22. # convolution kernel size
  23. nb_conv = 3
  24. # x = np.load('x.npy')
  25. # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes)
  26. # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3
  27. # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先
  28. model = Sequential()
  29. model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
  30. border_mode='valid',
  31. input_shape=(img_rows, img_cols,1)))
  32. model.add(Activation('relu'))
  33. model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
  34. model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
  35. model.add(Activation('relu'))
  36. model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
  37. model.add(Flatten())
  38. model.add(Dense(256))
  39. model.add(Dropout(0.5))
  40. model.add(Activation('relu'))
  41. model.add(Dense(nb_classes))
  42. model.add(Activation('softmax'))
  43. model.compile(loss='categorical_crossentropy',
  44. optimizer='sgd',
  45. metrics=['accuracy'])
  46. return model
  47. def Getmodel_tensorflow_light(nb_classes):
  48. # nb_classes = len(charset)
  49. img_rows, img_cols = 23, 23
  50. # number of convolutional filters to use
  51. nb_filters = 8
  52. # size of pooling area for max pooling
  53. nb_pool = 2
  54. # convolution kernel size
  55. nb_conv = 3
  56. # x = np.load('x.npy')
  57. # y = np_utils.to_categorical(range(3062)*45*5*2, nb_classes)
  58. # weight = ((type_class - np.arange(type_class)) / type_class + 1) ** 3
  59. # weight = dict(zip(range(3063), weight / weight.mean())) # 调整权重,高频字优先
  60. model = Sequential()
  61. model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
  62. border_mode='valid',
  63. input_shape=(img_rows, img_cols, 1)))
  64. model.add(Activation('relu'))
  65. model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
  66. model.add(Convolution2D(nb_filters, nb_conv * 2, nb_conv * 2))
  67. model.add(Activation('relu'))
  68. model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
  69. model.add(Flatten())
  70. model.add(Dense(32))
  71. # model.add(Dropout(0.25))
  72. model.add(Activation('relu'))
  73. model.add(Dense(nb_classes))
  74. model.add(Activation('softmax'))
  75. model.compile(loss='categorical_crossentropy',
  76. optimizer='adam',
  77. metrics=['accuracy'])
  78. return model
  79. model = Getmodel_tensorflow_light(3)
  80. model2 = Getmodel_tensorflow(3)
  81. import os
  82. model.load_weights("./model/char_judgement1.h5")
  83. model2.load_weights("./model/char_judgement.h5")
  84. model = model2
  85. def get_median(data):
  86. data = sorted(data)
  87. size = len(data)
  88. # print size
  89. if size % 2 == 0: # 判断列表长度为偶数
  90. median = (data[size//2]+data[size//2-1])/2
  91. data[0] = median
  92. if size % 2 == 1: # 判断列表长度为奇数
  93. median = data[(size-1)//2]
  94. data[0] = median
  95. return data[0]
  96. import time
  97. def searchOptimalCuttingPoint(rgb,res_map,start,width_boundingbox,interval_range):
  98. t0 = time.time()
  99. #
  100. # for x in xrange(10):
  101. # res_map = np.vstack((res_map,res_map[-1]))
  102. length = res_map.shape[0]
  103. refine_s = -2;
  104. if width_boundingbox>20:
  105. refine_s = -9
  106. score_list = []
  107. interval_big = int(width_boundingbox * 0.3) #
  108. p = 0
  109. for zero_add in xrange(start,start+50,3):
  110. # for interval_small in xrange(-0,width_boundingbox/2):
  111. for i in xrange(-8,int(width_boundingbox/1)-8):
  112. for refine in xrange(refine_s,width_boundingbox/2+3):
  113. p1 = zero_add# this point is province
  114. p2 = p1 + width_boundingbox +refine #
  115. p3 = p2 + width_boundingbox + interval_big+i+1
  116. p4 = p3 + width_boundingbox +refine
  117. p5 = p4 + width_boundingbox +refine
  118. p6 = p5 + width_boundingbox +refine
  119. p7 = p6 + width_boundingbox +refine
  120. if p7>=length:
  121. continue
  122. 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
  123. # print score
  124. score_list.append([score,[p1,p2,p3,p4,p5,p6,p7]])
  125. p+=1
  126. print p
  127. score_list = sorted(score_list , key=lambda x:x[0])
  128. # for one in score_list[-1][1]:
  129. # cv2.line(debug,(one,0),(one,36),(255,0,0),1)
  130. # #
  131. # cv2.imshow("one",debug)
  132. # cv2.waitKey(0)
  133. #
  134. print "寻找最佳点",time.time()-t0
  135. return score_list[-1]
  136. import sys
  137. sys.path.append('../')
  138. import recognizer as cRP
  139. from skimage.filters import (threshold_otsu, threshold_niblack,
  140. threshold_sauvola)
  141. import niblack_thresholding as nt
  142. def refineCrop(sections,width=16):
  143. new_sections = []
  144. for section in sections:
  145. # cv2.imshow("section¡",section)
  146. # cv2.blur(section,(3,3),3)
  147. sec_center = np.array([section.shape[1]/2,section.shape[0]/2])
  148. binary_niblack = nt.niBlackThreshold(section,17,-0.255)
  149. imagex, contours, hierarchy = cv2.findContours(binary_niblack,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
  150. boxs = []
  151. for contour in contours:
  152. x,y,w,h = cv2.boundingRect(contour)
  153. ratio = w/float(h)
  154. if ratio<1 and h>36*0.4 and y<16\
  155. :
  156. box = [x,y,w,h]
  157. boxs.append([box,np.array([x+w/2,y+h/2])])
  158. # cv2.rectangle(section,(x,y),(x+w,y+h),255,1)
  159. # print boxs
  160. dis_ = np.array([ ((one[1]-sec_center)**2).sum() for one in boxs])
  161. if len(dis_)==0:
  162. kernal = [0, 0, section.shape[1], section.shape[0]]
  163. else:
  164. kernal = boxs[dis_.argmin()][0]
  165. center_c = (kernal[0]+kernal[2]/2,kernal[1]+kernal[3]/2)
  166. w_2 = int(width/2)
  167. h_2 = kernal[3]/2
  168. if center_c[0] - w_2< 0:
  169. w_2 = center_c[0]
  170. new_box = [center_c[0] - w_2,kernal[1],width,kernal[3]]
  171. # print new_box[2]/float(new_box[3])
  172. if new_box[2]/float(new_box[3])>0.5:
  173. # print "异常"
  174. h = int((new_box[2]/0.35 )/2)
  175. if h>35:
  176. h = 35
  177. new_box[1] = center_c[1]- h
  178. if new_box[1]<0:
  179. new_box[1] = 1
  180. new_box[3] = h*2
  181. section = section[new_box[1]:new_box[1]+new_box[3],new_box[0]:new_box[0]+new_box[2]]
  182. # cv2.imshow("section",section)
  183. # cv2.waitKey(0)
  184. new_sections.append(section)
  185. # print new_box
  186. return new_sections
  187. def slidingWindowsEval(image):
  188. windows_size = 16;
  189. stride = 1
  190. height= image.shape[0]
  191. t0 = time.time()
  192. data_sets = []
  193. for i in range(0,image.shape[1]-windows_size+1,stride):
  194. data = image[0:height,i:i+windows_size]
  195. data = cv2.resize(data,(23,23))
  196. # cv2.imshow("image",data)
  197. data = cv2.equalizeHist(data)
  198. data = data.astype(np.float)/255
  199. data= np.expand_dims(data,3)
  200. data_sets.append(data)
  201. res = model.predict(np.array(data_sets))
  202. print "分割",time.time() - t0
  203. pin = res
  204. p = 1 - (res.T)[1]
  205. p = f.gaussian_filter1d(np.array(p,dtype=np.float),3)
  206. lmin = l.argrelmax(np.array(p),order = 3)[0]
  207. interval = []
  208. for i in xrange(len(lmin)-1):
  209. interval.append(lmin[i+1]-lmin[i])
  210. if(len(interval)>3):
  211. mid = get_median(interval)
  212. else:
  213. return []
  214. pin = np.array(pin)
  215. res = searchOptimalCuttingPoint(image,pin,0,mid,3)
  216. cutting_pts = res[1]
  217. last = cutting_pts[-1] + mid
  218. if last < image.shape[1]:
  219. cutting_pts.append(last)
  220. else:
  221. cutting_pts.append(image.shape[1]-1)
  222. name = ""
  223. confidence =0.00
  224. seg_block = []
  225. for x in xrange(1,len(cutting_pts)):
  226. if x != len(cutting_pts)-1 and x!=1:
  227. section = image[0:36,cutting_pts[x-1]-2:cutting_pts[x]+2]
  228. elif x==1:
  229. c_head = cutting_pts[x - 1]- 2
  230. if c_head<0:
  231. c_head=0
  232. c_tail = cutting_pts[x] + 2
  233. section = image[0:36, c_head:c_tail]
  234. elif x==len(cutting_pts)-1:
  235. end = cutting_pts[x]
  236. diff = image.shape[1]-end
  237. c_head = cutting_pts[x - 1]
  238. c_tail = cutting_pts[x]
  239. if diff<7 :
  240. section = image[0:36, c_head-5:c_tail+5]
  241. else:
  242. diff-=1
  243. section = image[0:36, c_head - diff:c_tail + diff]
  244. elif x==2:
  245. section = image[0:36, cutting_pts[x - 1] - 3:cutting_pts[x-1]+ mid]
  246. else:
  247. section = image[0:36,cutting_pts[x-1]:cutting_pts[x]]
  248. seg_block.append(section)
  249. refined = refineCrop(seg_block,mid-1)
  250. t0 = time.time()
  251. for i,one in enumerate(refined):
  252. res_pre = cRP.SimplePredict(one, i )
  253. # cv2.imshow(str(i),one)
  254. # cv2.waitKey(0)
  255. confidence+=res_pre[0]
  256. name+= res_pre[1]
  257. print "字符识别",time.time() - t0
  258. return refined,name,confidence

高性能开源中文车牌识别框架