本篇文章包含内容涉及:
1.数据清洗整理(特定分辨率数据不符合要求,选择剔除、OpenCV下的resize方法)
2.写数据集格式转换脚本代码
3.可能遇到的问题
目录
前言:
任务背景
目前要使用ultra fast lane detection算法做训练,这个算法本身使用culane数据集和tusimple数据集做训练,在代码dataloader的configs部分至提供了这两个数据集的读取方法,但考虑到后续使用多种不同的数据集才能使网络更加健壮,取得良好的泛华性,因此决定将算法与数据集格式转换任务分开,即算法按照tusimple格式读取数据集,而将其他所有的数据集统一转为tusimple格式,而curvelanes数据集作为为数不多的弯道数据集,其中弯道数据占比达总数据的60%以上,因此能够时模型更好的识别弯道,提高多场景下的识别能力。
Ultra-Fast-Lane-Detection(超快速车道线识别算法)GitHub链接
基础环境
- ubuntu18.04
- IDE:vscode
- 服务器:
提示:以下是本篇文章正文内容,下面案例可供参考
一、任务
使用windows的文件资源管理器对curvelanes数据集中train和valid部分做数据数量统计,不同分辨率的图片数量及占比如下图:
其中要求输入的图片为1280×720,因此需要将1570×660的图片进行剔除
二、过程分析
1 思路
先将curvelanes数据集中的images和labels转换为tusimple格式,再进行resize,过程中可以选择转换之前对于不符合分辨率要求的图片直接剔除
2 必要性
1.对1570*660的数据直接做resize,会导致图像尺寸发生畸变,而且其对应的labels文件中的json采用点的形式,将会使labels文件难以处理
2.对于非tusimple这类规范的数据集,那么采取数据清洗的重要性显然不言而喻
数据清洗:数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。
3 实施
3.1 少量数据实验
先在curvelanes数据集中,选中20张2560×1440图片,2张1560×660图片,1张1280×720图片及其对应的labels,分别放入两个不同的文件夹中(curvelanes数据集也是这样处理)
3.2 两个要点
- 图片进行resize时需要将其labels文件一起resize,不然只把图片resize是没有用的,传入模型还是无法训练;这里不建议使用各种软件进行resize,因为你也不知道它采用的是哪种resize方法,而且这种软件可能无法识别PNG图片格式的labels,会提示你“文件不存在”;
- 剔除1570*660分辨率的图片,由于数据本身的分辨率分布很整齐,采用遍历的方式,判断图片的
width
或height
,只要宽度为1570或者高度为660,直接删除
3.3 方案
最终确定:转格式时进行剔除,然后进行resize,防止畸变发生
部分代码:
(1)剔除不符合要求分辨率的图片
for each_bmp in files:#遍历图片,进行筛选
each_bmp_root =os.path.join(dir,each_bmp)#得到每个图片路径
img = Image.open(each_bmp_root)#打开每个图片
width = img.size[0]#获取图像的宽
if width == 1570:#判断图片的宽为1570直接删除其本身及其label
if os.path.exists(each_bmp_root):
os.remove(each_bmp_root)
else:
print("The file does not exist")
lablename= each_bmp.split("/")[-1]
lablename = lablename.split(".")[0]
# print(each_bmp_root)
labelpath = os.path.join(mLabelPath,lablename)
print(labelpath+'.lines.json')
if os.path.exists(labelpath+'.lines.json'):
os.remove(labelpath+'.lines.json')#remove的用法 chmod +x *可执行权限问题
else:
print("The file does not exist")
print(each_bmp + ' ' + lablename+'.lines.json' + " deletefinished")
(2)图片resize后再进行保存
mPath = os.path.join(mSavePath, "20.jpg")#保存图片
img = cv.resize(img,(1280,720))
cv.imwrite(mPath,img) #openCV保存
mString += mPath + " "
mPath = os.path.join(mSavePath, "20.png")#保存标签
img_gray = cv.resize(img_gray,(1280,720))
cv.imwrite(mPath,img_gray)
3.4 问题解决
- resize方法如何选择?
(1)利用OpenCV包中的resize方法
改变图像大小意味着改变尺寸,无论是单独的高或宽,还是两者。也可以按比例调整图像大小。
语法:
函数原型
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
参数:
参数 | 描述 |
---|---|
src | 【必需】原图像 |
dsize | 【必需】输出图像所需大小 |
fx | 【可选】沿水平轴的比例因子 |
fy | 【可选】沿垂直轴的比例因子 |
interpolation | 【可选】插值方式 |
【可选】插值方式
其中插值方式有很多种:
cv.INTER | 插值方法 |
---|---|
cv.INTER_NEAREST | 最近邻插值 |
cv.INTER_LINEAR | 双线性插值 |
cv.INTER_CUBIC | 双线性插值 |
cv.INTER_AREA | 使用像素区域关系重新采样,它可能是图像抽取的首选方法,因为它可以提供无莫尔条纹的结果。但是当图像被缩放时,它类似于INTER_NEAREST方法 |
通常的,缩小使用cv.INTER_AREA,放缩使用cv.INTER_CUBIC(较慢)和cv.INTER_LINEAR(较快效果也不错)。默认情况下,所有的放缩都使用cv.INTER_LINEAR。
(2)利用PIL包中的resize方法
Pillow包里面的resize函数的参数,插值方式有以下四种:
PIL.Image函数 |
---|
PIL.Image.NEAREST |
PIL.Image.BILINEAR |
PIL.Image.BICUBIC |
PIL.Image.ANTIALIAS |
我们在处理图像的时候尽可能的从头至尾采用一种图像处理模块,要么全部OpenCv,要么就是Pillow或者matplotlib,最好不要打开图像用OpenCv,crop图像又用Pillow之类的操作,会出现一些意想不到的错误。
- 如何通过设置在vscode中查看连接远程服务器的运行日志?
在VSCode的配置文件settings.json中添加如下参数:
"remote.SSH.showLoginTerminal": true,
由于真正进行数据处理的时候数据量一般都比较大,添加这行防止服务器断连的时候查看数据是否处理完毕,断开时间等,博主还没试过,非必须
- remove函数使用
(1)删除文件
要删除文件,必须导入OS模块并运行os.remove()函数:
eg:
import os
if os.path.exists("demofile.txt"):
os.remove("demofile.txt")
else:
print("This file no found!")
(2)删除文件夹
remove函数无法直接删除文件夹,使用其删除文件夹将会报错:
因为函数本质上不是对文件进行删除,remove只是通过迭代器的指针向前移动来删除,将没有被删除的元素放在链表的前面,并返回一个指向新的超尾值的迭代器。由于remove()函数不是成员,因此不能调整链表的长度。remove()函数并不是真正的删除,要想真正删除元素则可以使用erase()或者resize()函数。用法如下:
eg:
string str1 = "Text with some spaces";
str1.erase(std::remove(str1.begin(), str1.end(), ' '), str1.end()); // "Textwithsomespaces"
要删除整个文件夹,使用os.rmdir()方法:
eg:
#只能删除空文件夹
import os
os.rmdir("folder")
- 服务器端执行报错:No module named ‘path’:
sudo apt install path
- 服务器端执行报错:No module named ‘matplotlib’:
pip install matplotlib
总结
代码经过本地实验数据测试没问题后,在服务器端进行数据处理,20000张图片中剔除分辨率为1570*660的,用时约6分钟,valid中的20000张图片格式转换完成约用时65分钟。
参考链接: