车牌识别Python程序_第1页
车牌识别Python程序_第2页
车牌识别Python程序_第3页
车牌识别Python程序_第4页
车牌识别Python程序_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、# -*- coding: utf-8 -*-_author_ = 'd1bysj'import pymysqldb = pymysql.connect(host = '', # 远程主机的ip地址, user = '', # MySQL用户名 db = '', # database名 passwd = '', # 数据库密码 port = 3306, #数据库监听端口,默认3306 charset = "utf8") #指定utf8编码的连接cur= db.cursor()sql="

2、select * from sex"try: cur.execute(sql) re=cur.fetchall() for it in re: name = it0 num = it1 print(name,num)except Exception as e: raise efinally: db.close()import cv2import numpy as npfrom numpy.linalg import normimport sysimport osimport jsonSZ = 20 # 训练图片长宽MAX_WIDTH = 1000 # 原始图片最大宽度Min_Area

3、 = 2000 # 车牌区域允许最大面积PROVINCE_START = 1000# 读取图片文件def imreadex(filename): return cv2.imdecode(np.fromfile(filename, dtype=np.uint8), cv2.IMREAD_COLOR)def point_limit(point): if point0 < 0: point0 = 0 if point1 < 0: point1 = 0# 根据设定的阈值和图片直方图,找出波峰,用于分隔字符def find_waves(threshold, histogram): up_po

4、int = -1 # 上升点 is_peak = False if histogram0 > threshold: up_point = 0 is_peak = True wave_peaks = for i, x in enumerate(histogram): if is_peak and x < threshold: if i - up_point > 2: is_peak = False wave_peaks.append(up_point, i) elif not is_peak and x >= threshold: is_peak = True up_po

5、int = i if is_peak and up_point != -1 and i - up_point > 4: wave_peaks.append(up_point, i) return wave_peaks# 根据找出的波峰,分隔图片,从而得到逐个字符图片def seperate_card(img, waves): part_cards = for wave in waves: part_cards.append(img:, wave0:wave1) return part_cards# 来自opencv的sample,用于svm训练def deskew(img): m = c

6、v2.moments(img) if abs(m'mu02') < 1e-2: return img.copy() skew = m'mu11' / m'mu02' M = np.float32(1, skew, -0.5 * SZ * skew, 0, 1, 0) img = cv2.warpAffine(img, M, (SZ, SZ), flags=cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR) return img# 来自opencv的sample,用于svm训练def preprocess_hog

7、(digits): samples = for img in digits: gx = cv2.Sobel(img, cv2.CV_32F, 1, 0) gy = cv2.Sobel(img, cv2.CV_32F, 0, 1) mag, ang = cv2.cartToPolar(gx, gy) bin_n = 16 bin = 32(bin_n * ang / (2 * np.pi) bin_cells = bin:10, :10, bin10:, :10, bin:10, 10:, bin10:, 10: mag_cells = mag:10, :10, mag10:, :1

8、0, mag:10, 10:, mag10:, 10: hists = np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells) hist = np.hstack(hists) # transform to Hellinger kernel eps = 1e-7 hist /= hist.sum() + eps hist = np.sqrt(hist) hist /= norm(hist) + eps samples.append(hist) return np.float32(samples)

9、# 不能保证包括所有省份provinces = "zh_cuan", "川", "zh_e", "鄂", "zh_gan", "赣", "zh_gan1", "甘", "zh_gui", "贵", "zh_gui1", "桂", "zh_hei", "黑", "zh_hu", "沪&quo

10、t;, "zh_ji", "冀", "zh_jin", "津", "zh_jing", "京", "zh_jl", "吉", "zh_liao", "辽", "zh_lu", "鲁", "zh_meng", "蒙", "zh_min", "闽", "zh_ning&qu

11、ot;, "宁", "zh_qing", "靑", "zh_qiong", "琼", "zh_shan", "陕", "zh_su", "苏", "zh_sx", "晋", "zh_wan", "皖", "zh_xiang", "湘", "zh_xin", "新&quo

12、t;, "zh_yu", "豫", "zh_yu1", "渝", "zh_yue", "粤", "zh_yun", "云", "zh_zang", "藏", "zh_zhe", "浙"class StatModel(object): def load(self, fn): self.model = self.model.load(fn) def save(s

13、elf, fn): self.model.save(fn)class SVM(StatModel): def _init_(self, C=1, gamma=0.5): self.model = cv2.ml.SVM_create() self.model.setGamma(gamma) self.model.setC(C) self.model.setKernel(cv2.ml.SVM_RBF) self.model.setType(cv2.ml.SVM_C_SVC) # 训练svm def train(self, samples, responses): self.model.train(

14、samples, cv2.ml.ROW_SAMPLE, responses) # 字符识别 def predict(self, samples): r = self.model.predict(samples) return r1.ravel()class CardPredictor: def _init_(self): # 车牌识别的部分参数保存在js中,便于根据图片分辨率做调整 f = open('config.js') j = json.load(f) for c in j"config": print(c) if c"open":

15、 self.cfg = c.copy() break else: raise RuntimeError('没有设置有效配置参数') def _del_(self): self.save_traindata() def train_svm(self): # 识别英文字母和数字 self.model = SVM(C=1, gamma=0.5) # 识别中文 self.modelchinese = SVM(C=1, gamma=0.5) if os.path.exists("svm.dat"): self.model.load("svm.dat"

16、;) else: chars_train = chars_label = for root, dirs, files in os.walk("trainchars2"): if len(os.path.basename(root) > 1: continue root_int = ord(os.path.basename(root) for filename in files: filepath = os.path.join(root, filename) digit_img = cv2.imread(filepath) digit_img = cv2.cvtColo

17、r(digit_img, cv2.COLOR_BGR2GRAY) chars_train.append(digit_img) # chars_label.append(1) chars_label.append(root_int) chars_train = list(map(deskew, chars_train) chars_train = preprocess_hog(chars_train) # chars_train = chars_train.reshape(-1, 20, 20).astype(np.float32) chars_label = np.array(chars_la

18、bel) print(chars_train.shape) self.model.train(chars_train, chars_label) if os.path.exists("svmchinese.dat"): self.modelchinese.load("svmchinese.dat") else: chars_train = chars_label = for root, dirs, files in os.walk("traincharsChinese"): if not os.path.basename(root).

19、startswith("zh_"): continue pinyin = os.path.basename(root) index = provinces.index(pinyin) + PROVINCE_START + 1 # 1是拼音对应的汉字 for filename in files: filepath = os.path.join(root, filename) digit_img = cv2.imread(filepath) digit_img = cv2.cvtColor(digit_img, cv2.COLOR_BGR2GRAY) chars_train.a

20、ppend(digit_img) # chars_label.append(1) chars_label.append(index) chars_train = list(map(deskew, chars_train) chars_train = preprocess_hog(chars_train) # chars_train = chars_train.reshape(-1, 20, 20).astype(np.float32) chars_label = np.array(chars_label) print(chars_train.shape) self.modelchinese.t

21、rain(chars_train, chars_label) def save_traindata(self): if not os.path.exists("svm.dat"): self.model.save("svm.dat") if not os.path.exists("svmchinese.dat"): self.modelchinese.save("svmchinese.dat") def accurate_place(self, card_img_hsv, limit1, limit2, color

22、): row_num, col_num = card_img_hsv.shape:2 xl = col_num xr = 0 yh = 0 yl = row_num # col_num_limit = self.cfg"col_num_limit" row_num_limit = self.cfg"row_num_limit" col_num_limit = col_num * 0.8 if color != "green" else col_num * 0.5 # 绿色有渐变 for i in range(row_num): cou

23、nt = 0 for j in range(col_num): H = card_img_hsv.item(i, j, 0) S = card_img_hsv.item(i, j, 1) V = card_img_hsv.item(i, j, 2) if limit1 < H <= limit2 and 34 < S and 46 < V: count += 1 if count > col_num_limit: if yl > i: yl = i if yh < i: yh = i for j in range(col_num): count = 0

24、 for i in range(row_num): H = card_img_hsv.item(i, j, 0) S = card_img_hsv.item(i, j, 1) V = card_img_hsv.item(i, j, 2) if limit1 < H <= limit2 and 34 < S and 46 < V: count += 1 if count > row_num - row_num_limit: if xl > j: xl = j if xr < j: xr = j return xl, xr, yh, yl def pred

25、ict(self, car_pic): if type(car_pic) = type(""): img = imreadex(car_pic) else: img = car_pic pic_hight, pic_width = img.shape:2 if pic_width > MAX_WIDTH: resize_rate = MAX_WIDTH / pic_width img = cv2.resize(img, (MAX_WIDTH, int(pic_hight * resize_rate), interpolation=cv2.INTER_AREA) blu

26、r = self.cfg"blur" # 高斯去噪 if blur > 0: img = cv2.GaussianBlur(img, (blur, blur), 0) # 图片分辨率调整 oldimg = img img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # equ = cv2.equalizeHist(img) # img = np.hstack(img, equ) # 去掉图像中不会是车牌的区域 kernel = np.ones(20, 20), np.uint8) img_opening = cv2.morpholo

27、gyEx(img, cv2.MORPH_OPEN, kernel) img_opening = cv2.addWeighted(img, 1, img_opening, -1, 0); # 找到图像边缘 ret, img_thresh = cv2.threshold(img_opening, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) img_edge = cv2.Canny(img_thresh, 100, 200) # 使用开运算和闭运算让图像边缘成为一个整体 kernel = np.ones(self.cfg"morphologyr

28、", self.cfg"morphologyc"), np.uint8) img_edge1 = cv2.morphologyEx(img_edge, cv2.MORPH_CLOSE, kernel) img_edge2 = cv2.morphologyEx(img_edge1, cv2.MORPH_OPEN, kernel) # 查找图像边缘整体形成的矩形区域,可能有很多,车牌就在其中一个矩形区域中 image, contours, hierarchy = cv2.findContours(img_edge2, cv2.RETR_TREE, cv2.CHAIN_

29、APPROX_SIMPLE) contours = cnt for cnt in contours if cv2.contourArea(cnt) > Min_Area print('len(contours)', len(contours) # 一一排除不是车牌的矩形区域 car_contours = for cnt in contours: rect = cv2.minAreaRect(cnt) area_width, area_height = rect1 if area_width < area_height: area_width, area_height

30、 = area_height, area_width wh_ratio = area_width / area_height # print(wh_ratio) # 要求矩形区域长宽比在2到5.5之间,2到5.5是车牌的长宽比,其余的矩形排除 if wh_ratio > 2 and wh_ratio < 5.5: car_contours.append(rect) box = cv2.boxPoints(rect) box = 0(box) # oldimg = cv2.drawContours(oldimg, box, 0, (0, 0, 255), 2) # cv2

31、.imshow("edge4", oldimg) # print(rect) print(len(car_contours) print("精确定位") card_imgs = # 矩形区域可能是倾斜的矩形,需要矫正,以便使用颜色定位 for rect in car_contours: if rect2 > -1 and rect2 < 1: # 创造角度,使得左、高、右、低拿到正确的值 angle = 1 else: angle = rect2 rect = (rect0, (rect10 + 5, rect11 + 5), angle)

32、# 扩大范围,避免车牌边缘被排除 box = cv2.boxPoints(rect) heigth_point = right_point = 0, 0 left_point = low_point = pic_width, pic_hight for point in box: if left_point0 > point0: left_point = point if low_point1 > point1: low_point = point if heigth_point1 < point1: heigth_point = point if right_point0

33、< point0: right_point = point if left_point1 <= right_point1: # 正角度 new_right_point = right_point0, heigth_point1 pts2 = np.float32(left_point, heigth_point, new_right_point) # 字符只是高度需要改变 pts1 = np.float32(left_point, heigth_point, right_point) M = cv2.getAffineTransform(pts1, pts2) dst = cv2.

34、warpAffine(oldimg, M, (pic_width, pic_hight) point_limit(new_right_point) point_limit(heigth_point) point_limit(left_point) card_img = dstint(left_point1):int(heigth_point1), int(left_point0):int(new_right_point0) card_imgs.append(card_img) # cv2.imshow("card", card_img) # cv2.waitKey(0) e

35、lif left_point1 > right_point1: # 负角度 new_left_point = left_point0, heigth_point1 pts2 = np.float32(new_left_point, heigth_point, right_point) # 字符只是高度需要改变 pts1 = np.float32(left_point, heigth_point, right_point) M = cv2.getAffineTransform(pts1, pts2) dst = cv2.warpAffine(oldimg, M, (pic_width, p

36、ic_hight) point_limit(right_point) point_limit(heigth_point) point_limit(new_left_point) card_img = dstint(right_point1):int(heigth_point1), int(new_left_point0):int(right_point0) card_imgs.append(card_img) # cv2.imshow("card", card_img) # cv2.waitKey(0) # 开始使用颜色定位,排除不是车牌的矩形,目前只识别蓝、绿、黄车牌 c

37、olors = for card_index, card_img in enumerate(card_imgs): green = yello = blue = black = white = 0 card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV) # 有转换失败的可能,原因来自于上面矫正矩形出错 if card_img_hsv is None: continue row_num, col_num = card_img_hsv.shape:2 card_img_count = row_num * col_num for i in r

38、ange(row_num): for j in range(col_num): H = card_img_hsv.item(i, j, 0) S = card_img_hsv.item(i, j, 1) V = card_img_hsv.item(i, j, 2) if 11 < H <= 34 and S > 34: # 图片分辨率调整 yello += 1 elif 35 < H <= 99 and S > 34: # 图片分辨率调整 green += 1 elif 99 < H <= 124 and S > 34: # 图片分辨率调整

39、 blue += 1 if 0 < H < 180 and 0 < S < 255 and 0 < V < 46: black += 1 elif 0 < H < 180 and 0 < S < 43 and 221 < V < 225: white += 1 color = "no" limit1 = limit2 = 0 if yello * 2 >= card_img_count: color = "yello" limit1 = 11 limit2 = 34 # 有的图

40、片有色偏偏绿 elif green * 2 >= card_img_count: color = "green" limit1 = 35 limit2 = 99 elif blue * 2 >= card_img_count: color = "blue" limit1 = 100 limit2 = 124 # 有的图片有色偏偏紫 elif black + white >= card_img_count * 0.7: # TODO color = "bw" print(color) colors.append(col

41、or) print(blue, green, yello, black, white, card_img_count) # cv2.imshow("color", card_img) # cv2.waitKey(0) if limit1 = 0: continue # 以上为确定车牌颜色 # 以下为根据车牌颜色再定位,缩小边缘非车牌边界 xl, xr, yh, yl = self.accurate_place(card_img_hsv, limit1, limit2, color) if yl = yh and xl = xr: continue need_accurate

42、 = False if yl >= yh: yl = 0 yh = row_num need_accurate = True if xl >= xr: xl = 0 xr = col_num need_accurate = True card_imgscard_index = card_imgyl:yh, xl:xr if color != "green" or yl < (yh - yl) / 4 else card_img yl - ( yh - yl) / 4:yh, xl:xr if need_accurate: # 可能x或y方向未缩小,需要再试

43、一次 card_img = card_imgscard_index card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV) xl, xr, yh, yl = self.accurate_place(card_img_hsv, limit1, limit2, color) if yl = yh and xl = xr: continue if yl >= yh: yl = 0 yh = row_num if xl >= xr: xl = 0 xr = col_num card_imgscard_index = card_imgyl:yh, xl:xr if color != "green" or yl < (yh - yl) / 4 else card_img yl - ( yh - yl) / 4:yh, xl:xr # 以上为车牌定位 # 以下为识别车牌中的字符 predict_result = roi = None card_color = None for i, color in enumerate(colors): if color in ("bl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论