X-ray铸件缺陷检测(YOLOV3网络)
在暑假阶段老师给布置给我的实验任务是铸件的缺陷检测(x-ray)。我选择的网络是yolov3别人已经使用发展成熟的网络进行目标检测。我将本次实验分为数据集的处理+数据在yolov3网络下进行训练和验证。
本次实验我参考的是GitHub中eriklindernoren的
https://github.com/eriklindernoren/PyTorch-YOLOv3
1.数据集的处理
按照GitHub上的要求,原始的数据集是肯定无法直接输入网络之中,必须对数据集进行二次加工重新处理,具体的思路如下:
- 需要使用python来批量化处理这些图片与ground_truth文件,人工处理的效率低、容易犯错;
- 对C0001到C0067的全部文件进行区分,如果有ground_truth则可以作为训练集/验证集,如果没有ground_truth文件可以直接作为测试集;
- 将含有ground_truth文件的文件夹中没有真实标签的图片丢入测试集,留下含有ground_truth的图片(例如:C0002中ground_truth中1-60图片含有真实标签,而C0002中有90张图片,剩下30张图片就作为测试集);
- 将所有训练/测试集数据按照要求重新命名 (例如:label_name = labels_path + ‘train&val_’ + “%05d” % int(z) + ‘.txt’),同时按照网络要求得到新的label.txt文件(例如:label_idx x_center y_center width height),并对其数值进行归一化。
- 最后按照9比1的比例随机分配出训练集与验证集
images、labels和python代码具体如下:
import os
import cv2 as cv2
from random import sample
train_images_path = "E:\data\defect_detection\Castings_clean"
train_files = os.listdir(train_images_path)
txt_root_path = "E:\data\defect_detection\Castings_txt"
test_path = "E:\data\defect_detection/test/train&val"
txts = os.listdir(txt_root_path)
labels_path = "E:\data\defect_detection\\test\images"
labels = os.listdir(labels_path)
images_path = "E:\data\defect_detection\\test\labels"
images = os.listdir(images_path)
def compare(j, i):
d = str(j[6:-4])
d = int(d)
txt_file = os.path.join(txt_root_path + os.sep + i, 'ground_truth.txt')
list_first = []
f_1 = open(txt_file, 'r')
line = f_1.readline()
while line:
a = line.split()
b = a[0]
b = int(float(b))
list_first.append(b)
line = f_1.readline()
f_1.close()
list_first = list(set(list_first))
if d in list_first:
oldpath = train_images_path + os.sep + i + os.sep + j
newpath = test_path + os.sep + i + os.sep + j
os.rename(oldpath, newpath)
def label_rename(i,v,width,height,z):
m = str(v[6:-4])
v = m
m = int(m)
txt_file = os.path.join(txt_root_path + os.sep + i, 'ground_truth.txt')
f_2 = open(txt_file, 'r')
line = f_2.readline()
while line:
a = line.split()
label_id = a[0]
label_id = int(float(label_id))
x_1 = a[1]
x_1 = float(x_1)
x_2 = a[2]
x_2 = float(x_2)
y_1 = a[3]
y_1 = float(y_1)
y_2 = a[4]
y_2 = float(y_2)
kuan = x_2 - x_1
gaoo = y_2 - y_1
x_center = (x_2 + x_1)/2
y_center = (y_2 + y_1)/2
if label_id == m:
labels_path = "E:\data\defect_detection\label_txt\\"
label_name = labels_path + 'train&val_' + "%05d" % int(z) + '.txt'
label = open(label_name, 'a')
label_list = str(0)+" " +\
str(x_center/width)+" " +\
str(y_center/height)+" " +\
str(kuan/width)+" " +\
str(gaoo/height)+"\n"
label.write(label_list)
label.close()
line = f_2.readline()
f_2.close
def images_rename(v, z, i):
images_path = train_images_path + os.sep + i + os.sep + v
new_images_path = "E:\data\defect_detection\\test\images\\" + os.sep + 'train&val_' + "%05d" % int(z) + '.png'
os.rename(images_path, new_images_path)
z = 0
for i in train_files:
# print(i) i-->C0001~C0065
images_path = train_images_path + os.sep + i
images = os.listdir(images_path)
for j in images:
print(j)
j -->C0065_0010.png
抽取
compare(j, i)
for v in images:
z += 1
im = cv2.imread(os.path.join(images_path, v))
height, width, _ = im.shape
label_rename(i, v, width, height, z)
images_rename(v, z, i)
做完这些并确认正确之后,就可以愉快的使用yolov3进行训练了。
利用自己所做的数据集训练网络并验证结果
修改train.py、detect.py与yolov3-custom.cfg等文件
在训练过程中我踩到了这样一个坑我遇到的错误
其他的错误,可以根据训练错误提示一个一个解决
训练/检测的结果
训练硬件条件:使用的实验室的单根1080ti,32g内存,i7-8700k
train.py设置:epoch=9000 batch_size = 8 n_cpu = 8 img_size = 416
使用test.py算出 mAP = 0.74
检测出了连续的肉眼可见/不可见缺陷
实验后的展望
1.尝到了使用python的甜头,需要继续加强自己的代码能力,多进行编程做到熟能生巧;
2.yolo是成熟的别人方法,在解决我们问题上如果不能达到完美的效果,我们就要着手改进,多读其他人改进模型的优秀论文,为后续工作积累理论知识。