赞
踩
项目的初衷:虽然做二分类用SVM就基本能够满足功能需求,但因为Squeezenet网络模型足够小,所以想试一下在嵌入式运行速率和精确度是否能够比拟SVM从而尝试替代
功能实现:制作自定义的车位数据集在Pytorch上进行训练,以onnx文件形式在opencv上进行调用实现车位场景和非车位场景的二分类
首先看一下我拿到的数据集样子以及标签方式:
数据标签:有效车位场景为1,无效车位场景为-1
从上图可以看出,一开始拿到的数据集图片是大小不一的,图片名称虽然是从0开始排起,但在训练过程中,我们希望图片是按照顺序0,1,2,3…的顺序向网络依次传递数据,而这样的命名规则会导致在使用dataloader的时候,读取的顺序变为1,10,11,12,…,100,…,这种顺序是不符合我们预期的,也同时会导致和数据标签txt文件对应不上,所以第一步需要做的是:对数据集重新处理(包括图片大小和命名)以及制作图片数据集的索引文件(包含了图片的路径和该图片的类别标签)
import os import glob from PIL import Image # 1.对图片重命名 # 图片路径 file_path = 'E:\\训练集\\dataset_car_roi\\Train_folder' # 返回指定路径下的文件和文件夹列表 file_list = os.listdir(file_path) # 该路径下的文件数量 total_pic = len(file_list) # 从 -1 开始,第一次累加从0读取 k = -1 for file in file_list: k = k + 1 # 将多个路径组合后返回 old_dir = os.path.join(file_path, file) # print(old_dir) file_type = os.path.splitext(file)[1] # 得到图片后缀名(.jpg) file_number = os.path.splitext(file)[0] # 得到图片前缀名(数字) # zfill方法返回指定长度的字符串,元字符串右对齐,前面填充0 new_dir = os.path.join(file_path, str(file_number).zfill(6) + file_type) # 重命名 os.rename(old_dir, new_dir) # 2.新建一个Train_resize文件夹用于修改图片大小 Pic_path = r'E:\训练集\dataset_car_roi\Train_folder\*.jpg' IsExist = os.path.exists('E:\训练集\dataset_car_roi\Train_resize') if not IsExist: os.makedirs('E:\训练集\dataset_car_roi\Train_resize') else: print('目录已经存在') Pic_resize_path = r'E:\训练集\dataset_car_roi\Train_resize' for i in glob.glob(Pic_path): im1 = Image.open(i) # 调整为224x224的大小,根据网络输入来修改,这里是为了与Squeezenet对应 im2 = im1.resize((224, 224)) im2.save(os.path.join(Pic_resize_path, os.path.basename(i)))
import os num = -1 Lab_path = "E:\\训练集\\dataset_car_roi\\label\\" path = 'E:/训练集/dataset_car_roi/Train_resize/' files = os.listdir(path) # 列出path下的目录和文件 files.sort() # 排序,因为重命名过不会出现1,10,11,12..100... train = open('E:/训练集/dataset_car_roi/Train_resize/train.txt', 'a') test = open('E:/训练集/dataset_car_roi/Train_resize/test.txt', 'a') for file in files: num = num + 1 TxT = open(Lab_path + str(num) + '.txt') # 打开第num个txt文件 TxT_data = TxT.readline() # 只读取文本第一行的内容,以字符串的形式返回结果 # 由于我的txt标签文件存在了一个回车,所以1返回的字符串长度是2,-1则是3,根据实际修改 if len(TxT_data) == 2: b = 1 else: # 这里将非车位场景从-1修改为0,是为了Squeezenet读取标签训练计算损失时候不出错 b = 0 # 交叉熵误差的输入不能是负数,logX if num < 1630: if (num % 2) == 0: # 双数作为训练集,单数作为测试集 fileType = os.path.split(file) # print("Head of '% s:'" % path, fileType[0]) # print("Tail of '% s:'" % path, fileType[1]) # os.path.split() 将目标路径分成head和tail(head为最后一级文件前的目录 tail为末尾文件名) if fileType[1] == '.txt': continue # 如果tail尾部不是 '.txt',则跳过进入下一次循环 # 索引路径拼接 name = str(path) + file + ' ' + str(b) + '\n' train.write(name) else: fileType = os.path.split(file) if fileType[1] == '.txt': continue name = str(path) + file + ' ' + str(b) + '\n' test.write(name) test.close() train.close()
生成出来的索引txt文件如图所示:
到这一步,自定义的数据集制作就处理好了,接下来就到了模型训练部分
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。