最近由于我的一个模型需要Widerface格式的数据集,所以我对手里的数据集进行处理。
首先想要制作Widerface格式数据集,就要有一个包含所有图片标注信息的txt文件。而这个代码就是帮助我们制作这个文件的。
我手里的数据是每个数据有单独的标注信息txt文件,txt文件里的信息格式也和Widerface格式不一样,下面是我手里的数据标注信息(除开头0以外的第一和第三个数除以图片的宽,第二和第四个数除以图片的高):
0 0.317357512953 0.3515625 0.0336787564767 0.072265625
0 0.0738341968912 0.412109375 0.020725388601 0.0390625
0 0.411917098446 0.376953125 0.020725388601 0.03125
0 0.891191709845 0.388671875 0.0272020725389 0.029296875
而Widerface的格式如下:
File name #文件名称
Number of bounding box #框个数
x1, y1, w, h, #框中心点坐标(x,y),宽,高
知道了上面的信息后,我们可以设计代码逻辑:
- 读取图片,获取图片的名称和宽、高。
- 寻找同名的标注txt文件,并将每行存入列表,并用count记录行数作为框的个数。
- 将列表转换成数组,打开新的空白txt文件,首先写入名称和count。
- 用for循环依次读入每个数字,并在读入的同时乘以相应的放大倍数,注意每行要从第二个数字开始,不选取0。
- 对整个代码实现批量化编程。
具体代码如下所示:
import os
import cv2
import numpy
dir_path = '/../../../datasets/wider_face'
for file in os.listdir(dir_path): # file为current_dir当前目录下图片名
if file.endswith(".jpg"): # 如果file以jpg结尾
image = cv2.imread(os.path.join(dir_path) + '/' + file)
image_name = str(file)
size = image.shape
w = size[1]
h = size[0]
fp = open((os.path.join(dir_path) + '/' + os.path.splitext(file)[0]) + '.txt', 'r')
ls = []
count = 0
for line in fp:
count += 1
line = line.strip('\n') # 将\n去掉
ls.append(line.split(' ')) # 将空格作为分隔符将一个字符切割成一个字符数组
fp.close()
ls = numpy.array(ls, dtype=float) # 将其转换成numpy的数组,并定义数据类型为float
file = open('test.txt', 'a') # 参数a是追加写,w是覆写。打开一个新的文件
file.write(image_name + "\n")
file.write(str(count) + "\n")
for i in range(ls.shape[0]): # 循环每一行
for j in range(1, ls.shape[1]): # 循环每一列
if j % 2 == 1:
file.write(str(int(ls[i][j] * w)) + " ") # 写入单个数值并换行
else:
file.write(str(int(ls[i][j] * h)) + " ") # 写入单个数值并换行
file.write("\n")
file.close() # 关闭文件