黑马程序员技术交流社区

标题: 【上海校区】python+opencv实现车牌识别 [打印本页]

作者: 不二晨    时间: 2019-2-25 13:08
标题: 【上海校区】python+opencv实现车牌识别
文章目录:

    一、前言
    二、训练分类器
        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
版权声明:本文为博主原创文章,转载请附上博文链接!


作者: 不二晨    时间: 2019-2-26 15:23
奈斯,感谢分享




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2