本文目的:实验用CCD采集到5个视频,需在5个视频中采集有效图片,并将这些图片利用LableImg软件进行标注,用来制备VOC格式的目标检测训练数据集。
第一步:有效视频截取
将采集到的视频利用bandicut软件进行无损视频截取,将所需的视频片段采集出来并放在一个文件夹中。(bandicut需要注册激活,网上所能下载的破解版软件试用有问题,最后还是使用正版软件,想办法将视频后带有水印的部分去掉即可)
第二步:从视频中提取视频帧作为训练图像
使用python opencv提取视频帧。每隔1s提取一帧保存到一个文件夹中,文件夹命名:ImageSets,注意:(高质量保存jpg文件,路径中不能出现中文)。代码如下:
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import cv2
import os
import sys
# input_path = sys.argv[1] # 第一个输入参数是包含视频片段的路径
input_path = "G:\\videos\\videos" # 第一个输入参数是包含视频片段的路径
# frame_interval = int(sys.argv[2]) # 第二个输入参数是设定每隔多少帧截取一帧
frame_interval = 35 # 第二个输入参数是设定每隔多少帧截取一帧
filenames = os.listdir(input_path) # 列出文件夹下所有的视频文件
video_prefix = input_path.split(os.sep)[-1] # 获取文件夹名称
frame_path = '{}_frames_highQ'.format(input_path) # 新建文件夹,名称为原名加上_frames
if not os.path.exists(frame_path):
os.mkdir(frame_path)
cap = cv2.VideoCapture() # 初始化一个VideoCapture对象
for filename in filenames:
filepath = os.sep.join([input_path, filename])
cap.open(filepath) # VideoCapture::open函数可以从文件获取视频
n_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 获取视频帧数
for i in range(42): # 为了避免视频头几帧质量低下,黑屏或者无关等
cap.read()
for i in range(n_frames):
ret, frame = cap.read()
# 每隔frame_interval帧进行一次截屏操作
if i % frame_interval == 0:
imagename = '{}_{}_{:0>6d}.jpg'.format(video_prefix, filename.split('.')[0], i)
imagepath = os.sep.join([frame_path, imagename])
print('exported {}!'.format(imagepath))
cv2.imwrite(imagepath, frame, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
cap.release() # 执行结束释放资源
第三步:将上诉提取的视频帧重命名,按照VOC格式。
windows下能运行的代码如下:
import os
import argparse as ap
def rename(path, num, start_index):
filelist = os.listdir(path)
filelist = sorted(filelist)
# print(filelist)
img = start_index
Newdir = os.path.join(path, '../JPEGImages')
if not os.path.exists(Newdir):
os.makedirs(Newdir)
for files in filelist:
Olddir = os.path.join(path, files)
if os.path.isdir(Olddir):
continue
filename = os.path.splitext(files)[0]
filetype = os.path.splitext(files)[1]
# print(filename, img)
if str(img).zfill(num) == filename:
img = img + 1
continue
New_name = str(img).zfill(num) + filetype
# os.system("cp " + Olddir + ' ' + os.path.join(Newdir, New_name))
New_name_path = os.path.join(path, New_name)
os.rename(Olddir, New_name_path)
img = img + 1
print("Rename Done.")
if __name__ == "__main__":
# Argument Parser
parser = ap.ArgumentParser()
parser.add_argument("--images", help="Path to images",
default="G:\\videos\\videos_frames_highQ_rename")
parser.add_argument("--start", help="Path to images",
default=1)
args = vars(parser.parse_args())
images_path = args["images"]
start_index = args["start"]
rename(images_path, 6, start_index)
第四步:对训练图像进行标注。
使用LabelImg软件进行标注,可在GITHUB上直接下载LabelImg的压缩包(windows环境).
得到标注的文件夹Annotations
第五步:利用标注好的XML文件生成trainval.txt,test.txt等文件。
import os
import argparse as ap
import random
import math
if __name__ == "__main__":
# Argument Parser
parser = ap.ArgumentParser()
parser.add_argument("--images", help="Path to images",
default="JPEGImages/")
parser.add_argument("--output", help="Path to output directory",
default="ImageSets/Main/")
args = vars(parser.parse_args())
images_path = args["images"]
output_dir = args["output"]
trainval_rate = 0.8
train_rate = 0.7
if not os.path.exists(output_dir):
os.makedirs(output_dir)
images_names = os.listdir(images_path)
images_list = []
for img in images_names:
images_list.append(img.split('.')[0])
random.shuffle(images_list)
annotation_num = len(images_list)
trainval_num = int(math.ceil(trainval_rate * annotation_num))
train_num = int(math.ceil(trainval_num * train_rate))
trainval = images_list[0:trainval_num]
test = images_list[trainval_num:]
train = trainval[0:train_num]
val = trainval[train_num:trainval_num]
trainval = sorted(trainval)
train = sorted(train)
val = sorted(val)
test = sorted(test)
fout = open(os.path.join(output_dir, "trainval.txt"), 'w')
for line in trainval:
fout.write(line + "\n")
fout.close()
fout = open(os.path.join(output_dir, "train.txt"), 'w')
for line in train:
fout.write(line + "\n")
fout.close()
fout = open(os.path.join(output_dir, "val.txt"), 'w')
for line in val:
fout.write(line + "\n")
fout.close()
fout = open(os.path.join(output_dir, "test.txt"), 'w')
for line in test:
fout.write(line + "\n")
fout.close()
print(annotation_num, len(trainval), len(test), len(train), len(val))
第六步:完成数据制备
将以上产生的ImageSets文件夹,Annotations文件夹,JPEGImages文件夹放在VOCdevkit文件夹中,完成数据集制备。