最近做毕业设计,发现导出的数据集格式出了点问题,label本来只有80类,但中间夹杂着10行空行,就导致训练集和测试集内的label是0~90,超过网络的范围了。
因此便动手把txt的内容替换下。
格式如下:
0 E:/data3/img/train2017/000000391895.jpg 640 360 4 359.17 146.17 471.62 359.74 1 339.88 22.16 493.76 322.89 1 471.64 172.82 507.56 220.92 2 486.01 183.31 516.64 218.29
1 E:/data3/img/train2017/000000522418.jpg 640 480 1 382.48 0.00 639.28 474.31 49 234.06 406.61 454.00 449.28 61 0.00 316.04 406.65 473.53 81 305.45 172.05 362.81 249.35
Pandas
首先考虑是将数据用pandas处理下,但出现一些错误:
error_bad_lines
ParserError: Error tokenizing data. C error: Expected 5 fields in line 3, saw 6
error_bad_lines : boolean, default True
如果一行包含太多的列,那么默认不会返回DataFrame ,如果设置成False,那么会将该行剔除(只能在C解析器下使用)。
剔除后会发出警告:Skipping line 3: expected 5 fields, saw 6
warn_bad_lines
warn_bad_lines : boolean, default True
如果error_bad_lines =False,并且warn_bad_lines =True 那么所有的“bad lines”将会被输出(只能在C解析器下使用)。
参考:这里
Python
pandas走不通那就老老实实用python
f = open('train.txt', 'r') # 读取训练集
f_write = open('train_new.txt', 'w') # 将替换后的写到新文本内
for j in f:
s = j.strip().split(' ')
#assert len(s) > 8, 'Annotation error! Please check your annotation file. Make sure there is at least one target object in each image.'
line_idx = int(s[0]) # 第一个数据是图片索引
pic_path = s[1] # 第二个数据是图片的路径
img_width = int(s[2]) # 宽
img_height = int(s[3]) # 高
s = s[4:]
assert len(s) % 5 == 0, 'Annotation error! Please check your annotation file. Maybe partially missing some coordinates?'
box_cnt = len(s) // 5 # 每五个元素组成一个box
boxes = []
for i in range(box_cnt):
label, x_min, y_min, x_max, y_max = int(s[i * 5]), float(s[i * 5 + 1]), float(s[i * 5 + 2]), float(s[i * 5 + 3]), float(s[i * 5 + 4])
if label >= 13 and label <= 25:
print(label, '->', end=' ')
label -= 1
print(label)
elif label >= 27 and label <= 28:
print(label, '->', end=' ')
label -= 2
print(label)
elif label >= 31 and label <= 44:
print(label, '->', end=' ')
label -= 4
print(label)
elif label >= 46 and label <= 65:
print(label, '->', end=' ')
label -= 5
print(label)
elif label == 67:
print(label, '->', end=' ')
label -= 6
print(label)
elif label == 70:
print(label, '->', end=' ')
label -= 8
print(label)
elif label >= 72 and label <= 82:
print(label, '->', end=' ')
label -= 9
print(label)
elif label >= 84 and label <=90:
print(label, '->', end=' ')
label -= 10
print(label)
boxes.append(label)
boxes.append(x_min)
boxes.append(y_min)
boxes.append(x_max)
boxes.append(y_max) # 将替换好的box放进列表里,以空格分隔
strBox = ' '.join('%s' %id for id in boxes) # 将列表转成字符串
strNew = str(line_idx)+' '+str(pic_path)+' '+str(img_width)+' '+str(img_height)+' '+strBox+'\n'
f_write.write(strNew) # 写入
其中遇到的一些错误:
list转换字符串报错:TypeError: sequence item 0: expected str instance, int found
原因是:list包含数字,不能直接转化成字符串。
解决办法:’ ‘.join(’%s’ %id for id in boxes)
即遍历列表元素转成字符串
字符串连接报错:TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
原因:数字和字符串不能直接用+相连。
解决办法:str()将数字转为字符串