文章目录:
一、前言
二、训练分类器
2.1、准备训练用单字符图片
2.2、图片预处理
2.3、用opencv的preprocess_hog()处理图片
2.4、用SVM训练分类器
三、车牌定位
四、字符分割
五、字符识别
六、Mysql保存
七、总结
八、参考资料
一、 前言:
最近一直在学习机器学习,花了段时间把《机器学习实战》(【美】Peter Harrington著)看了一遍,当中讲述的几个机器学习经典算法虽说有所掌握(监督学习:k-近邻、决策树、朴素贝叶斯、Logistic回归、SVM、AdaBoost、线性回归、树回归,无监督学习:k-means,FP-Growth),但是还是觉得有点不踏实,于是就找了车牌识别的例子,算是把其中的算法用到了实际的项目中。
环境:
系统:win10
语言:Python3.6
平台:Jupyter Notebook
机器学习库:OpenCV
数据库:Mysql
机器学习算法:SVM
用到的Python库:matplotlib、numpy、opencv、sklearn,这些库通过pip install package安装即可
二、训练分类器
2.1、准备训练用单字符图片
相同字符放在一个文件夹下,文件夹名代表标签
2.2、图片预处理
读取图片、标签用于后续处理
########################################
##描述:读取图片数据集
##filename_1:图片数据集路径
##return:
## dataArr:读取到的数据集,拉伸成(4200, 1280) 4200表示有4200张图片 1280 每张图片的宽*高
## np.array(label_list) 图片对应的标签
## np.array(img_org) 原图片
########################################
def load_data_en(filename_1):
'''
这个函数用来加载数据集,其中filename_1是一个文件的绝对地址
'''
sample_number = 0 # 用来计算总的样本数
dataArr = np.zeros((4200, 1280))
label_list = []
provinces = ['京','闽','粤','苏','沪','浙']
temp_address = []
temp = []
img_org = []
for i in range(34):
## filename_1 = r'E:/Phthon/car_detect/datasets/'
with open(filename_1+str(i)+'.txt', 'r') as fr_1:
temp = [row.strip() for row in fr_1.readlines()]
temp_address.extend(temp)
length = len(temp_address)
##pattern = compile(r'\d+') # 查找数字,代表特征值
pattern_en = compile(r'datasets/train_images/training-set/(\d+)*')
pattern_zh = compile(r'datasets/train_images/training-set/chinese-characters/(\d+)*')
for j in range(length):
# print(middle_route)
# print(temp_address_2[j])
temp_img = cv2.imread(temp_address[j], cv2.COLOR_BGR2GRAY)
if temp_img is None:
# print(temp_address[j])
continue
sample_number += 1
img_org.append(temp_img)
temp_img = temp_img.reshape(1, 40 * 32)
dataArr[sample_number - 1, :] = temp_img
label = pattern_en.findall(temp_address[j])[0]
if len(label) == 0: ## 汉字字符
pass
# label = provinces[int(pattern_zh.findall(temp_address[j])[0])]
else: ## 非汉字字符
if int(label) < 10: # 数字0-9
pass
elif int(label)>=10 and int(label)<=17: # 字母A-H 没有I
label = chr(int(label)+55)
elif int(label)>=18 and int(label)<=22: # 字母J-N 没有O
label = chr(int(label)+56)
else: # 字母P-Z
label = chr(int(label)+57)
label_list.append(label)
return dataArr, np.array(label_list) , np.array(img_org)
2.3、用opencv的preprocess_hog()处理图片
由于光照明暗不同、拍摄角度不同、车牌新旧程度不同,导致拍摄的车牌差异大,并且需要训练时间长,因此需要使用opencv的preprocess_hog()处理图片,取图片的64个主要特征用于训练SVM训练
X2 = preprocess_hog(img_org)
1
2.4、使用sklearn自带的SVM算法训练分类器
对于训练数据集的训练比较耗时,因此对于训练完成的分类器,最好单独存放,使用时在做load
from sklearn.svm import SVC
svc = SVC(C = 1, gamma = 0.5)
svc.fit(X2, label_list) # 使用默认配置初始化SVM,对原始1280维像素特征的训练数据进行建模,并在测试集上做出预测
1
2
3
三、车牌定位
对于车牌定位,有多种方法可以实现,可以对原图像经过形态学处理(高斯平滑,中值滤波,Sobel算子,膨胀、腐蚀)后,再使用opencv的findContours检测物体轮廓,根据车牌宽高比这个几何特性,可找到车牌区域并进行切割
用opencv导入已训练好的分类器plate.xml,对灰度图进行车牌定位
########################
## 描述:从原始图片中定位出车牌区域,用于后续识别
## 输入:
## img:原始图片
## 输出:
## 切割出的车牌区域
## 返回值:
## 车牌区域
########################
def detect(img):
# 灰度化
image = cv2.imread(img)
image = cv2.GaussianBlur(image,(3,3),0)
resize_h = 1000
resize_w = int(image.shape[1] / image.shape[0] * resize_h)
image = cv2.resize(image , (resize_w,resize_h))
image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
clf = cv2.CascadeClassifier('plate.xml')
area = clf.detectMultiScale(image_gray)
image_copy = image.copy()
for (x,y,w,h) in area:
# print((x,y,w,h))
cv2.rectangle(image_copy,(x,y),(x+w,y+h),(0,0,255),5)
image_save = image_copy[y:y+h,x:x+w]
cv2.imwrite('result2.png', image_save)
return image_save
---------------------
【转载,仅作分享,侵删】
作者:announced1
原文:https://blog.csdn.net/announced1/article/details/87642310
版权声明:本文为博主原创文章,转载请附上博文链接!
|
|