样本准备
准备三个文件夹 postdata 正样本 negdata 负样本 testdata 测试样本
所有样本 统一处理为灰度,尺寸 140*30
(文末提供一些样本,需要自取)
postdata: 准备了500个正样本
negdata:准备了500个负样本
testdata:准备了20个测试样本,车牌图片命名开头为1,非车牌开头0 用于读取标签计算准确率
训练模型
准备训练集
将读取的图片二维矩阵转为一维向量存入训练集 trainningMat
得到训练集尺寸: (trainsample_num , 4200) 数据类型:float32
#训练集
trainningMat=[]
#读取正样本加入训练集
for root, dirs, files in os.walk("postdata",-1):
post_num=len(files)
for file in files:
src = cv2.imread("postdata/" + file)
#将每个样本以一维存入训练集
Vect = np.zeros(4200)
for i in range(140):
for j in range(30):
Vect[ 30 * i + j] = src[j][i][0]
trainningMat.append(Vect)
#读取负样本加入训练集
for root, dirs, files in os.walk("negdata",-1):
neg_num=len(files)
for file in files:
src = cv2.imread("negdata/" + file)
Vect = np.zeros(4200)
for i in range(140):
for j in range(30):
Vect[ 30 * i + j] = src[j][i][0]
trainningMat.append(Vect)
trainningMat=np.array(trainningMat,dtype='float32')
准备标签
得到 label列表 尺寸: (trainsample_num , 1)
#训练样本数
trainsample_num=len(trainningMat)
#训练标签
Labels = np.zeros((trainsample_num,1),np.int32)
#前post_num个样本(正样本)标签为1,后面的(负样本)标签为-1
for i in range(trainsample_num):
if i<post_num:
Labels[i][0]=1
else:
Labels[i][0]=-1
模型训练
svm = cv2.ml.SVM_create() #创建SVM model
#属性设置
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01)
#训练
result = svm.train(trainningMat,cv2.ml.ROW_SAMPLE,Labels)
#svm.save("svmtest.mat")
可以将模型存储为 svmtest.mat
使用的时候直接加载无需再读取样本进行训练。
svm2 = cv2.ml.SVM_load("svmtest.mat")
测试
#读取测试样本
correct_count=0 #正确数
test_label=[] #测试样本标签
testMat=[] #测试集
for root, dirs, files in os.walk("testdata",-1):
test_num=len(files)
for file in files:
src = cv2.imread("testdata/" + file)
test_label.append(int(file[0])) #读取并存入标签
Vect = np.zeros(4752)
for i in range(144):
for j in range(33):
Vect[ 33 * i + j] = src[j][i][0]
testMat.append(Vect)
testMat=np.array(testMat,dtype='float32')
correct_count=0 #正确数
(par1,par2) = svm.predict(testMat)
for i in range(test_num):
if (par2[i][0]==1 and test_label[i]==1) or (par2[i][0]==-1 and test_label[i]==0):
correct_count+=1
accuracy=correct_count/test_num
print("accuracy:",accuracy)
输出正确率
完整代码:
import cv2
import os
import numpy as np
#所有样本 统一处理为灰度,尺寸 140*30
#训练集
#将读取的图片二维矩阵转为一维向量存入训练集 trainningMat
#得到训练集尺寸: (trainsample_num , 4200) 数据类型:float32
trainningMat=[]
#读取正样本加入训练集
for root, dirs, files in os.walk("postdata",-1):
post_num=len(files)
for file in files:
src = cv2.imread("postdata/" + file)
#将每个样本以一维存入训练集
Vect = np.zeros(4752)
for i in range(144):
for j in range(33):
Vect[ 33 * i + j] = src[j][i][0]
trainningMat.append(Vect)
#读取负样本加入训练集
for root, dirs, files in os.walk("negdata",-1):
neg_num=len(files)
for file in files:
src = cv2.imread("negdata/" + file)
Vect = np.zeros(4752)
for i in range(144):
for j in range(33):
Vect[ 33 * i + j] = src[j][i][0]
trainningMat.append(Vect)
trainningMat=np.array(trainningMat,dtype='float32')
#训练样本数
trainsample_num=len(trainningMat)
#训练标签
#得到 label列表 尺寸: (trainsample_num , 1)
Labels = np.zeros((trainsample_num,1),np.int32)
#前post_num个样本(正样本)标签为1,后面的(负样本)标签为-1
for i in range(trainsample_num):
if i<post_num:
Labels[i][0]=1
else:
Labels[i][0]=-1
#读取测试样本
test_label=[] #测试样本标签
testMat=[] #测试集
for root, dirs, files in os.walk("testdata",-1):
test_num=len(files)
for file in files:
src = cv2.imread("testdata/" + file)
test_label.append(int(file[0])) #读取并存入标签
Vect = np.zeros(4752)
for i in range(144):
for j in range(33):
Vect[ 33 * i + j] = src[j][i][0]
testMat.append(Vect)
testMat=np.array(testMat,dtype='float32')
svm = cv2.ml.SVM_create() #创建SVM model
#属性设置
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01)
#训练
result = svm.train(trainningMat,cv2.ml.ROW_SAMPLE,Labels)
#svm.save("svmtest.mat")
#可以将模型存储,使用的时候直接加载无需再读取样本进行训练。
correct_count=0 #正确数
(par1,par2) = svm.predict(testMat)
for i in range(test_num):
if (par2[i][0]==1 and test_label[i]==1) or (par2[i][0]==-1 and test_label[i]==0):
correct_count+=1
accuracy=correct_count/test_num
print("accuracy:",accuracy)
#用生成的模型测试
'''
import cv2
import os
import numpy as np
#读取测试样本
test_label=[] #测试样本标签
testMat=[] #测试集
for root, dirs, files in os.walk("testdata",-1):
test_num=len(files)
for file in files:
src = cv2.imread("testdata/" + file)
test_label.append(int(file[0])) #读取并存入标签
Vect = np.zeros(4752)
for i in range(144):
for j in range(33):
Vect[ 33 * i + j] = src[j][i][0]
testMat.append(Vect)
testMat=np.array(testMat,dtype='float32')
correct_count=0 #正确数
svm2 = cv2.ml.SVM_load("svmtest.mat")
(par1,par2) = svm2.predict(testMat)
for i in range(test_num):
if (par2[i][0]==1 and test_label[i]==1) or (par2[i][0]==-1 and test_label[i]==0):
correct_count+=1
accuracy=correct_count/test_num
print("accuracy:",accuracy)
'''
百度了一些车辆图片截了车牌样本:
链接:https://pan.baidu.com/s/164Dt4t9VNdPO3jWQ4ghA2w
提取码:hs6w