更换文档检测模型
This commit is contained in:
@@ -0,0 +1,386 @@
|
||||
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import glob
|
||||
import os
|
||||
import os.path as osp
|
||||
import cv2
|
||||
import random
|
||||
import numpy as np
|
||||
import argparse
|
||||
import tqdm
|
||||
import json
|
||||
|
||||
|
||||
def mkdir_if_missing(d):
|
||||
if not osp.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
|
||||
def bdd2mot_tracking(img_dir, label_dir, save_img_dir, save_label_dir):
|
||||
label_jsons = os.listdir(label_dir)
|
||||
for label_json in tqdm(label_jsons):
|
||||
with open(os.path.join(label_dir, label_json)) as f:
|
||||
labels_json = json.load(f)
|
||||
for label_json in labels_json:
|
||||
img_name = label_json['name']
|
||||
video_name = label_json['videoName']
|
||||
labels = label_json['labels']
|
||||
txt_string = ""
|
||||
for label in labels:
|
||||
category = label['category']
|
||||
x1 = label['box2d']['x1']
|
||||
x2 = label['box2d']['x2']
|
||||
y1 = label['box2d']['y1']
|
||||
y2 = label['box2d']['y2']
|
||||
width = x2 - x1
|
||||
height = y2 - y1
|
||||
x_center = (x1 + x2) / 2. / args.width
|
||||
y_center = (y1 + y2) / 2. / args.height
|
||||
width /= args.width
|
||||
height /= args.height
|
||||
identity = int(label['id'])
|
||||
# [class] [identity] [x_center] [y_center] [width] [height]
|
||||
txt_string += "{} {} {} {} {} {}\n".format(
|
||||
attr_id_dict[category], identity, x_center, y_center,
|
||||
width, height)
|
||||
|
||||
fn_label = os.path.join(save_label_dir, img_name[:-4] + '.txt')
|
||||
source_img = os.path.join(img_dir, video_name, img_name)
|
||||
target_img = os.path.join(save_img_dir, img_name)
|
||||
with open(fn_label, 'w') as f:
|
||||
f.write(txt_string)
|
||||
os.system('cp {} {}'.format(source_img, target_img))
|
||||
|
||||
|
||||
def transBbox(bbox):
|
||||
# bbox --> cx cy w h
|
||||
bbox = list(map(lambda x: float(x), bbox))
|
||||
bbox[0] = (bbox[0] - bbox[2] / 2) * 1280
|
||||
bbox[1] = (bbox[1] - bbox[3] / 2) * 720
|
||||
bbox[2] = bbox[2] * 1280
|
||||
bbox[3] = bbox[3] * 720
|
||||
|
||||
bbox = list(map(lambda x: str(x), bbox))
|
||||
return bbox
|
||||
|
||||
|
||||
def genSingleImageMot(inputPath, classes=[]):
|
||||
labelPaths = glob.glob(inputPath + '/*.txt')
|
||||
labelPaths = sorted(labelPaths)
|
||||
allLines = []
|
||||
result = {}
|
||||
for labelPath in labelPaths:
|
||||
frame = str(int(labelPath.split('-')[-1].replace('.txt', '')))
|
||||
with open(labelPath, 'r') as labelPathFile:
|
||||
lines = labelPathFile.readlines()
|
||||
for line in lines:
|
||||
line = line.replace('\n', '')
|
||||
lineArray = line.split(' ')
|
||||
if len(classes) > 0:
|
||||
if lineArray[0] in classes:
|
||||
lineArray.append(frame)
|
||||
allLines.append(lineArray)
|
||||
else:
|
||||
lineArray.append(frame)
|
||||
allLines.append(lineArray)
|
||||
resultMap = {}
|
||||
for line in allLines:
|
||||
if line[1] not in resultMap.keys():
|
||||
resultMap[line[1]] = []
|
||||
resultMap[line[1]].append(line)
|
||||
mot_gt = []
|
||||
id_idx = 0
|
||||
for rid in resultMap.keys():
|
||||
id_idx += 1
|
||||
for id_line in resultMap[rid]:
|
||||
mot_line = []
|
||||
mot_line.append(id_line[-1])
|
||||
mot_line.append(str(id_idx))
|
||||
id_line_temp = transBbox(id_line[2:6])
|
||||
mot_line.extend(id_line_temp)
|
||||
mot_line.append('1') # origin class: id_line[0]
|
||||
mot_line.append('1') # permanent class => 1
|
||||
mot_line.append('1')
|
||||
mot_gt.append(mot_line)
|
||||
|
||||
result = list(map(lambda line: str.join(',', line), mot_gt))
|
||||
resultStr = str.join('\n', result)
|
||||
return resultStr
|
||||
|
||||
|
||||
def writeGt(inputPath, outPath, classes=[]):
|
||||
singleImageResult = genSingleImageMot(inputPath, classes=classes)
|
||||
outPathFile = outPath + '/gt.txt'
|
||||
mkdir_if_missing(outPath)
|
||||
with open(outPathFile, 'w') as gtFile:
|
||||
gtFile.write(singleImageResult)
|
||||
|
||||
|
||||
def genSeqInfo(seqInfoPath):
|
||||
name = seqInfoPath.split('/')[-2]
|
||||
img1Path = osp.join(str.join('/', seqInfoPath.split('/')[0:-1]), 'img1')
|
||||
seqLength = len(glob.glob(img1Path + '/*.jpg'))
|
||||
seqInfoStr = f'''[Sequence]\nname={name}\nimDir=img1\nframeRate=30\nseqLength={seqLength}\nimWidth=1280\nimHeight=720\nimExt=.jpg'''
|
||||
with open(seqInfoPath, 'w') as seqFile:
|
||||
seqFile.write(seqInfoStr)
|
||||
|
||||
|
||||
def genMotGt(dataDir, classes=[]):
|
||||
seqLists = sorted(glob.glob(dataDir))
|
||||
for seqList in seqLists:
|
||||
inputPath = osp.join(seqList, 'img1')
|
||||
outputPath = seqList.replace('labels_with_ids', 'images')
|
||||
outputPath = osp.join(outputPath, 'gt')
|
||||
mkdir_if_missing(outputPath)
|
||||
print('processing...', outputPath)
|
||||
writeGt(inputPath, outputPath, classes=classes)
|
||||
seqList = seqList.replace('labels_with_ids', 'images')
|
||||
seqInfoPath = osp.join(seqList, 'seqinfo.ini')
|
||||
genSeqInfo(seqInfoPath)
|
||||
|
||||
|
||||
def updateSeqInfo(dataDir, phase):
|
||||
seqPath = osp.join(dataDir, 'labels_with_ids', phase)
|
||||
seqList = glob.glob(seqPath + '/*')
|
||||
for seqName in seqList:
|
||||
print('seqName=>', seqName)
|
||||
seqName_img1_dir = osp.join(seqName, 'img1')
|
||||
txtLength = glob.glob(seqName_img1_dir + '/*.txt')
|
||||
name = seqName.split('/')[-1].replace('.jpg', '').replace('.txt', '')
|
||||
seqLength = len(txtLength)
|
||||
seqInfoStr = f'''[Sequence]\nname={name}\nimDir=img1\nframeRate=30\nseqLength={seqLength}\nimWidth=1280\nimHeight=720\nimExt=.jpg'''
|
||||
seqInfoPath = seqName_img1_dir.replace('labels_with_ids', 'images')
|
||||
seqInfoPath = seqInfoPath.replace('/img1', '')
|
||||
seqInfoPath = seqInfoPath + '/seqinfo.ini'
|
||||
with open(seqInfoPath, 'w') as seqFile:
|
||||
seqFile.write(seqInfoStr)
|
||||
|
||||
|
||||
def VisualDataset(datasetPath, phase='train', seqName='', frameId=1):
|
||||
trainPath = osp.join(datasetPath, 'labels_with_ids', phase)
|
||||
seq1Paths = osp.join(trainPath, seqName)
|
||||
seq_img1_path = osp.join(seq1Paths, 'img1')
|
||||
label_with_idPath = osp.join(seq_img1_path, seqName + '-' + '%07d' %
|
||||
frameId) + '.txt'
|
||||
image_path = label_with_idPath.replace('labels_with_ids', 'images').replace(
|
||||
'.txt', '.jpg')
|
||||
|
||||
seqInfoPath = str.join('/', image_path.split('/')[:-2])
|
||||
seqInfoPath = seqInfoPath + '/seqinfo.ini'
|
||||
seq_info = open(seqInfoPath).read()
|
||||
width = int(seq_info[seq_info.find('imWidth=') + 8:seq_info.find(
|
||||
'\nimHeight')])
|
||||
height = int(seq_info[seq_info.find('imHeight=') + 9:seq_info.find(
|
||||
'\nimExt')])
|
||||
|
||||
with open(label_with_idPath, 'r') as label:
|
||||
allLines = label.readlines()
|
||||
images = cv2.imread(image_path)
|
||||
print('image_path => ', image_path)
|
||||
for line in allLines:
|
||||
line = line.split(' ')
|
||||
line = list(map(lambda x: float(x), line))
|
||||
c1, c2, w, h = line[2:6]
|
||||
x1 = c1 - w / 2
|
||||
x2 = c2 - h / 2
|
||||
x3 = c1 + w / 2
|
||||
x4 = c2 + h / 2
|
||||
cv2.rectangle(
|
||||
images, (int(x1 * width), int(x2 * height)),
|
||||
(int(x3 * width), int(x4 * height)), (255, 0, 0),
|
||||
thickness=2)
|
||||
cv2.imwrite('test.jpg', images)
|
||||
|
||||
|
||||
def VisualGt(dataPath, phase='train'):
|
||||
seqList = sorted(glob.glob(osp.join(dataPath, 'images', phase) + '/*'))
|
||||
seqIndex = random.randint(0, len(seqList) - 1)
|
||||
seqPath = seqList[seqIndex]
|
||||
gt_path = osp.join(seqPath, 'gt', 'gt.txt')
|
||||
img_list_path = sorted(glob.glob(osp.join(seqPath, 'img1', '*.jpg')))
|
||||
imgIndex = random.randint(0, len(img_list_path))
|
||||
img_Path = img_list_path[imgIndex]
|
||||
|
||||
frame_value = img_Path.split('/')[-1].replace('.jpg', '')
|
||||
frame_value = frame_value.split('-')[-1]
|
||||
frame_value = int(frame_value)
|
||||
seqNameStr = img_Path.split('/')[-1].replace('.jpg', '').replace('img', '')
|
||||
frame_value = int(seqNameStr.split('-')[-1])
|
||||
print('frame_value => ', frame_value)
|
||||
gt_value = np.loadtxt(gt_path, dtype=float, delimiter=',')
|
||||
gt_value = gt_value[gt_value[:, 0] == frame_value]
|
||||
|
||||
get_list = gt_value.tolist()
|
||||
img = cv2.imread(img_Path)
|
||||
|
||||
colors = [[255, 0, 0], [255, 255, 0], [255, 0, 255], [0, 255, 0],
|
||||
[0, 255, 255], [0, 0, 255]]
|
||||
for seq, _id, pl, pt, w, h, _, bbox_class, _ in get_list:
|
||||
pl, pt, w, h = int(pl), int(pt), int(w), int(h)
|
||||
print('pl,pt,w,h => ', pl, pt, w, h)
|
||||
cv2.putText(img,
|
||||
str(bbox_class), (pl, pt), cv2.FONT_HERSHEY_PLAIN, 2,
|
||||
colors[int(bbox_class - 1)])
|
||||
cv2.rectangle(
|
||||
img, (pl, pt), (pl + w, pt + h),
|
||||
colors[int(bbox_class - 1)],
|
||||
thickness=2)
|
||||
cv2.imwrite('testGt.jpg', img)
|
||||
print(seqPath, frame_value)
|
||||
return seqPath.split('/')[-1], frame_value
|
||||
|
||||
|
||||
def gen_image_list(dataPath, datType):
|
||||
inputPath = f'{dataPath}/labels_with_ids/{datType}'
|
||||
pathList = sorted(glob.glob(inputPath + '/*'))
|
||||
print(pathList)
|
||||
allImageList = []
|
||||
for pathSingle in pathList:
|
||||
imgList = sorted(glob.glob(osp.join(pathSingle, 'img1', '*.txt')))
|
||||
for imgPath in imgList:
|
||||
imgPath = imgPath.replace('labels_with_ids', 'images').replace(
|
||||
'.txt', '.jpg')
|
||||
allImageList.append(imgPath)
|
||||
with open(f'{dataPath}.{datType}', 'w') as image_list_file:
|
||||
allImageListStr = str.join('\n', allImageList)
|
||||
image_list_file.write(allImageListStr)
|
||||
|
||||
|
||||
def formatOrigin(datapath, phase):
|
||||
label_with_idPath = osp.join(datapath, 'labels_with_ids', phase)
|
||||
print(label_with_idPath)
|
||||
for txtList in sorted(glob.glob(label_with_idPath + '/*.txt')):
|
||||
print(txtList)
|
||||
seqName = txtList.split('/')[-1]
|
||||
seqName = str.join('-', seqName.split('-')[0:-1]).replace('.txt', '')
|
||||
seqPath = osp.join(label_with_idPath, seqName, 'img1')
|
||||
mkdir_if_missing(seqPath)
|
||||
os.system(f'mv {txtList} {seqPath}')
|
||||
|
||||
|
||||
def copyImg(fromRootPath, toRootPath, phase):
|
||||
fromPath = osp.join(fromRootPath, 'images', phase)
|
||||
toPathSeqPath = osp.join(toRootPath, 'labels_with_ids', phase)
|
||||
seqList = sorted(glob.glob(toPathSeqPath + '/*'))
|
||||
for seqPath in seqList:
|
||||
seqName = seqPath.split('/')[-1]
|
||||
imgTxtList = sorted(glob.glob(osp.join(seqPath, 'img1') + '/*.txt'))
|
||||
img_toPathSeqPath = osp.join(seqPath, 'img1')
|
||||
img_toPathSeqPath = img_toPathSeqPath.replace('labels_with_ids',
|
||||
'images')
|
||||
mkdir_if_missing(img_toPathSeqPath)
|
||||
|
||||
for imgTxt in imgTxtList:
|
||||
imgName = imgTxt.split('/')[-1].replace('.txt', '.jpg')
|
||||
imgfromPath = osp.join(fromPath, seqName, imgName)
|
||||
print(f'cp {imgfromPath} {img_toPathSeqPath}')
|
||||
os.system(f'cp {imgfromPath} {img_toPathSeqPath}')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='BDD100K to MOT format')
|
||||
parser.add_argument("--data_path", default='bdd100k')
|
||||
parser.add_argument("--phase", default='train')
|
||||
parser.add_argument("--classes", default='2,3,4,9,10')
|
||||
|
||||
parser.add_argument("--img_dir", default="bdd100k/images/track/")
|
||||
parser.add_argument("--label_dir", default="bdd100k/labels/box_track_20/")
|
||||
parser.add_argument("--save_path", default="bdd100kmot_vehicle")
|
||||
parser.add_argument("--height", default=720)
|
||||
parser.add_argument("--width", default=1280)
|
||||
args = parser.parse_args()
|
||||
|
||||
attr_dict = dict()
|
||||
attr_dict["categories"] = [{
|
||||
"supercategory": "none",
|
||||
"id": 0,
|
||||
"name": "pedestrian"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 1,
|
||||
"name": "rider"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 2,
|
||||
"name": "car"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 3,
|
||||
"name": "truck"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 4,
|
||||
"name": "bus"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 5,
|
||||
"name": "train"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 6,
|
||||
"name": "motorcycle"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 7,
|
||||
"name": "bicycle"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 8,
|
||||
"name": "other person"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 9,
|
||||
"name": "trailer"
|
||||
}, {
|
||||
"supercategory": "none",
|
||||
"id": 10,
|
||||
"name": "other vehicle"
|
||||
}]
|
||||
attr_id_dict = {i['name']: i['id'] for i in attr_dict['categories']}
|
||||
|
||||
# create bdd100kmot_vehicle training set in MOT format
|
||||
print('Loading and converting training set...')
|
||||
train_img_dir = os.path.join(args.img_dir, 'train')
|
||||
train_label_dir = os.path.join(args.label_dir, 'train')
|
||||
save_img_dir = os.path.join(args.save_path, 'images', 'train')
|
||||
save_label_dir = os.path.join(args.save_path, 'labels_with_ids', 'train')
|
||||
if not os.path.exists(save_img_dir): os.makedirs(save_img_dir)
|
||||
if not os.path.exists(save_label_dir): os.makedirs(save_label_dir)
|
||||
bdd2mot_tracking(train_img_dir, train_label_dir, save_img_dir,
|
||||
save_label_dir)
|
||||
|
||||
# create bdd100kmot_vehicle validation set in MOT format
|
||||
print('Loading and converting validation set...')
|
||||
val_img_dir = os.path.join(args.img_dir, 'val')
|
||||
val_label_dir = os.path.join(args.label_dir, 'val')
|
||||
save_img_dir = os.path.join(args.save_path, 'images', 'val')
|
||||
save_label_dir = os.path.join(args.save_path, 'labels_with_ids', 'val')
|
||||
if not os.path.exists(save_img_dir): os.makedirs(save_img_dir)
|
||||
if not os.path.exists(save_label_dir): os.makedirs(save_label_dir)
|
||||
bdd2mot_tracking(val_img_dir, val_label_dir, save_img_dir, save_label_dir)
|
||||
|
||||
# gen gt file
|
||||
dataPath = args.data_path
|
||||
phase = args.phase
|
||||
classes = args.classes.split(',')
|
||||
formatOrigin(osp.join(dataPath, 'bdd100kmot_vehicle'), phase)
|
||||
dataDir = osp.join(
|
||||
osp.join(dataPath, 'bdd100kmot_vehicle'), 'labels_with_ids',
|
||||
phase) + '/*'
|
||||
genMotGt(dataDir, classes=classes)
|
||||
copyImg(dataPath, osp.join(dataPath, 'bdd100kmot_vehicle'), phase)
|
||||
updateSeqInfo(osp.join(dataPath, 'bdd100kmot_vehicle'), phase)
|
||||
gen_image_list(osp.join(dataPath, 'bdd100kmot_vehicle'), phase)
|
||||
os.system(f'rm -r {dataPath}/bdd100kmot_vehicle/images/' + phase + '/*.jpg')
|
||||
@@ -0,0 +1,16 @@
|
||||
data_path=bdd100k
|
||||
img_dir=${data_path}/images/track
|
||||
label_dir=${data_path}/labels/box_track_20
|
||||
save_path=${data_path}/bdd100kmot_vehicle
|
||||
|
||||
phasetrain=train
|
||||
phaseval=val
|
||||
classes=2,3,4,9,10
|
||||
|
||||
# gen mot dataset
|
||||
python bdd100k2mot.py --data_path=${data_path} --phase=${phasetrain} --classes=${classes} --img_dir=${img_dir} --label_dir=${label_dir} --save_path=${save_path}
|
||||
python bdd100k2mot.py --data_path=${data_path} --phase=${phaseval} --classes=${classes} --img_dir=${img_dir} --label_dir=${label_dir} --save_path=${save_path}
|
||||
|
||||
# gen new labels_with_ids
|
||||
python gen_labels_MOT.py --mot_data=${data_path} --phase=${phasetrain}
|
||||
python gen_labels_MOT.py --mot_data=${data_path} --phase=${phaseval}
|
||||
@@ -0,0 +1,72 @@
|
||||
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import os.path as osp
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
|
||||
def mkdirs(d):
|
||||
if not osp.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='BDD100K to MOT format')
|
||||
parser.add_argument(
|
||||
"--mot_data", default='./bdd100k')
|
||||
parser.add_argument("--phase", default='train')
|
||||
args = parser.parse_args()
|
||||
|
||||
MOT_data = args.mot_data
|
||||
phase = args.phase
|
||||
seq_root = osp.join(MOT_data, 'bdd100kmot_vehicle', 'images', phase)
|
||||
label_root = osp.join(MOT_data, 'bdd100kmot_vehicle', 'labels_with_ids',
|
||||
phase)
|
||||
mkdirs(label_root)
|
||||
seqs = [s for s in os.listdir(seq_root)]
|
||||
tid_curr = 0
|
||||
tid_last = -1
|
||||
|
||||
os.system(f'rm -r {MOT_data}/bdd100kmot_vehicle/labels_with_ids')
|
||||
for seq in seqs:
|
||||
print('seq => ', seq)
|
||||
seq_info = open(osp.join(seq_root, seq, 'seqinfo.ini')).read()
|
||||
seq_width = int(seq_info[seq_info.find('imWidth=') + 8:seq_info.find(
|
||||
'\nimHeight')])
|
||||
seq_height = int(seq_info[seq_info.find('imHeight=') + 9:seq_info.find(
|
||||
'\nimExt')])
|
||||
|
||||
gt_txt = osp.join(seq_root, seq, 'gt', 'gt.txt')
|
||||
gt = np.loadtxt(gt_txt, dtype=np.float64, delimiter=',')
|
||||
|
||||
seq_label_root = osp.join(label_root, seq, 'img1')
|
||||
mkdirs(seq_label_root)
|
||||
|
||||
for fid, tid, x, y, w, h, mark, label, _ in gt:
|
||||
fid = int(fid)
|
||||
tid = int(tid)
|
||||
if not tid == tid_last:
|
||||
tid_curr += 1
|
||||
tid_last = tid
|
||||
x += w / 2
|
||||
y += h / 2
|
||||
label_fpath = osp.join(seq_label_root,
|
||||
seq + '-' + '{:07d}.txt'.format(fid))
|
||||
label_str = '0 {:d} {:.6f} {:.6f} {:.6f} {:.6f}\n'.format(
|
||||
tid_curr, x / seq_width, y / seq_height, w / seq_width,
|
||||
h / seq_height)
|
||||
with open(label_fpath, 'a') as f:
|
||||
f.write(label_str)
|
||||
@@ -0,0 +1,295 @@
|
||||
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import glob
|
||||
import os
|
||||
import os.path as osp
|
||||
import cv2
|
||||
import argparse
|
||||
import numpy as np
|
||||
import random
|
||||
|
||||
# The object category indicates the type of annotated object,
|
||||
# (i.e., ignored regions(0), pedestrian(1), people(2), bicycle(3), car(4), van(5), truck(6), tricycle(7), awning-tricycle(8), bus(9), motor(10),others(11))
|
||||
|
||||
# Extract single class or multi class
|
||||
isExtractMultiClass = False
|
||||
# The sequence is excluded because there are too few vehicles
|
||||
exclude_seq = ["uav0000086_00000_v"]
|
||||
|
||||
|
||||
def mkdir_if_missing(d):
|
||||
if not osp.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
|
||||
def genGtFile(seqPath, outPath, classes=[]):
|
||||
id_idx = 0
|
||||
old_idx = -1
|
||||
with open(seqPath, 'r') as singleSeqFile:
|
||||
motLine = []
|
||||
allLines = singleSeqFile.readlines()
|
||||
for line in allLines:
|
||||
line = line.replace('\n', '')
|
||||
line = line.split(',')
|
||||
# exclude occlusion!='2'
|
||||
if line[-1] != '2' and line[7] in classes:
|
||||
if old_idx != int(line[1]):
|
||||
id_idx += 1
|
||||
old_idx = int(line[1])
|
||||
newLine = line[0:6]
|
||||
newLine[1] = str(id_idx)
|
||||
newLine.append('1')
|
||||
if (len(classes) > 1 and isExtractMultiClass):
|
||||
class_index = str(classes.index(line[7]) + 1)
|
||||
newLine.append(class_index)
|
||||
else:
|
||||
newLine.append('1') # use permanent class '1'
|
||||
newLine.append('1')
|
||||
motLine.append(newLine)
|
||||
mkdir_if_missing(outPath)
|
||||
gtFilePath = osp.join(outPath, 'gt.txt')
|
||||
with open(gtFilePath, 'w') as gtFile:
|
||||
motLine = list(map(lambda x: str.join(',', x), motLine))
|
||||
motLineStr = str.join('\n', motLine)
|
||||
gtFile.write(motLineStr)
|
||||
|
||||
|
||||
def genSeqInfo(img1Path, seqName):
|
||||
imgPaths = glob.glob(img1Path + '/*.jpg')
|
||||
seqLength = len(imgPaths)
|
||||
if seqLength > 0:
|
||||
image1 = cv2.imread(imgPaths[0])
|
||||
imgHeight = image1.shape[0]
|
||||
imgWidth = image1.shape[1]
|
||||
else:
|
||||
imgHeight = 0
|
||||
imgWidth = 0
|
||||
seqInfoStr = f'''[Sequence]\nname={seqName}\nimDir=img1\nframeRate=30\nseqLength={seqLength}\nimWidth={imgWidth}\nimHeight={imgHeight}\nimExt=.jpg'''
|
||||
seqInfoPath = img1Path.replace('/img1', '')
|
||||
with open(seqInfoPath + '/seqinfo.ini', 'w') as seqFile:
|
||||
seqFile.write(seqInfoStr)
|
||||
|
||||
|
||||
def copyImg(img1Path, gtTxtPath, outputFileName):
|
||||
with open(gtTxtPath, 'r') as gtFile:
|
||||
allLines = gtFile.readlines()
|
||||
imgList = []
|
||||
for line in allLines:
|
||||
imgIdx = int(line.split(',')[0])
|
||||
if imgIdx not in imgList:
|
||||
imgList.append(imgIdx)
|
||||
seqName = gtTxtPath.replace('./{}/'.format(outputFileName),
|
||||
'').replace('/gt/gt.txt', '')
|
||||
sourceImgPath = osp.join('./sequences', seqName,
|
||||
'{:07d}.jpg'.format(imgIdx))
|
||||
os.system(f'cp {sourceImgPath} {img1Path}')
|
||||
|
||||
|
||||
def genMotLabels(datasetPath, outputFileName, classes=['2']):
|
||||
mkdir_if_missing(osp.join(datasetPath, outputFileName))
|
||||
annotationsPath = osp.join(datasetPath, 'annotations')
|
||||
annotationsList = glob.glob(osp.join(annotationsPath, '*.txt'))
|
||||
for annotationPath in annotationsList:
|
||||
seqName = annotationPath.split('/')[-1].replace('.txt', '')
|
||||
if seqName in exclude_seq:
|
||||
continue
|
||||
mkdir_if_missing(osp.join(datasetPath, outputFileName, seqName, 'gt'))
|
||||
mkdir_if_missing(osp.join(datasetPath, outputFileName, seqName, 'img1'))
|
||||
genGtFile(annotationPath,
|
||||
osp.join(datasetPath, outputFileName, seqName, 'gt'), classes)
|
||||
img1Path = osp.join(datasetPath, outputFileName, seqName, 'img1')
|
||||
gtTxtPath = osp.join(datasetPath, outputFileName, seqName, 'gt/gt.txt')
|
||||
copyImg(img1Path, gtTxtPath, outputFileName)
|
||||
genSeqInfo(img1Path, seqName)
|
||||
|
||||
|
||||
def deleteFileWhichImg1IsEmpty(mot16Path, dataType='train'):
|
||||
path = mot16Path
|
||||
data_images_train = osp.join(path, 'images', f'{dataType}')
|
||||
data_images_train_seqs = glob.glob(data_images_train + '/*')
|
||||
if (len(data_images_train_seqs) == 0):
|
||||
print('dataset is empty!')
|
||||
for data_images_train_seq in data_images_train_seqs:
|
||||
data_images_train_seq_img1 = osp.join(data_images_train_seq, 'img1')
|
||||
if len(glob.glob(data_images_train_seq_img1 + '/*.jpg')) == 0:
|
||||
print(f"os.system(rm -rf {data_images_train_seq})")
|
||||
os.system(f'rm -rf {data_images_train_seq}')
|
||||
|
||||
|
||||
def formatMot16Path(dataPath, pathType='train'):
|
||||
train_path = osp.join(dataPath, 'images', pathType)
|
||||
mkdir_if_missing(train_path)
|
||||
os.system(f'mv {dataPath}/* {train_path}')
|
||||
|
||||
|
||||
def VisualGt(dataPath, phase='train'):
|
||||
seqList = sorted(glob.glob(osp.join(dataPath, 'images', phase) + '/*'))
|
||||
seqIndex = random.randint(0, len(seqList) - 1)
|
||||
seqPath = seqList[seqIndex]
|
||||
gt_path = osp.join(seqPath, 'gt', 'gt.txt')
|
||||
img_list_path = sorted(glob.glob(osp.join(seqPath, 'img1', '*.jpg')))
|
||||
imgIndex = random.randint(0, len(img_list_path))
|
||||
img_Path = img_list_path[imgIndex]
|
||||
frame_value = int(img_Path.split('/')[-1].replace('.jpg', ''))
|
||||
gt_value = np.loadtxt(gt_path, dtype=int, delimiter=',')
|
||||
gt_value = gt_value[gt_value[:, 0] == frame_value]
|
||||
get_list = gt_value.tolist()
|
||||
img = cv2.imread(img_Path)
|
||||
colors = [[255, 0, 0], [255, 255, 0], [255, 0, 255], [0, 255, 0],
|
||||
[0, 255, 255], [0, 0, 255]]
|
||||
for seq, _id, pl, pt, w, h, _, bbox_class, _ in get_list:
|
||||
cv2.putText(img,
|
||||
str(bbox_class), (pl, pt), cv2.FONT_HERSHEY_PLAIN, 2,
|
||||
colors[bbox_class - 1])
|
||||
cv2.rectangle(
|
||||
img, (pl, pt), (pl + w, pt + h),
|
||||
colors[bbox_class - 1],
|
||||
thickness=2)
|
||||
cv2.imwrite('testGt.jpg', img)
|
||||
|
||||
|
||||
def VisualDataset(datasetPath, phase='train', seqName='', frameId=1):
|
||||
trainPath = osp.join(datasetPath, 'labels_with_ids', phase)
|
||||
seq1Paths = osp.join(trainPath, seqName)
|
||||
seq_img1_path = osp.join(seq1Paths, 'img1')
|
||||
label_with_idPath = osp.join(seq_img1_path, '%07d' % frameId) + '.txt'
|
||||
image_path = label_with_idPath.replace('labels_with_ids', 'images').replace(
|
||||
'.txt', '.jpg')
|
||||
seqInfoPath = str.join('/', image_path.split('/')[:-2])
|
||||
seqInfoPath = seqInfoPath + '/seqinfo.ini'
|
||||
seq_info = open(seqInfoPath).read()
|
||||
width = int(seq_info[seq_info.find('imWidth=') + 8:seq_info.find(
|
||||
'\nimHeight')])
|
||||
height = int(seq_info[seq_info.find('imHeight=') + 9:seq_info.find(
|
||||
'\nimExt')])
|
||||
|
||||
with open(label_with_idPath, 'r') as label:
|
||||
allLines = label.readlines()
|
||||
images = cv2.imread(image_path)
|
||||
for line in allLines:
|
||||
line = line.split(' ')
|
||||
line = list(map(lambda x: float(x), line))
|
||||
c1, c2, w, h = line[2:6]
|
||||
x1 = c1 - w / 2
|
||||
x2 = c2 - h / 2
|
||||
x3 = c1 + w / 2
|
||||
x4 = c2 + h / 2
|
||||
cv2.rectangle(
|
||||
images, (int(x1 * width), int(x2 * height)),
|
||||
(int(x3 * width), int(x4 * height)), (255, 0, 0),
|
||||
thickness=2)
|
||||
cv2.imwrite('test.jpg', images)
|
||||
|
||||
|
||||
def gen_image_list(dataPath, datType):
|
||||
inputPath = f'{dataPath}/images/{datType}'
|
||||
pathList = glob.glob(inputPath + '/*')
|
||||
pathList = sorted(pathList)
|
||||
allImageList = []
|
||||
for pathSingle in pathList:
|
||||
imgList = sorted(glob.glob(osp.join(pathSingle, 'img1', '*.jpg')))
|
||||
for imgPath in imgList:
|
||||
allImageList.append(imgPath)
|
||||
with open(f'{dataPath}.{datType}', 'w') as image_list_file:
|
||||
allImageListStr = str.join('\n', allImageList)
|
||||
image_list_file.write(allImageListStr)
|
||||
|
||||
|
||||
def gen_labels_mot(MOT_data, phase='train'):
|
||||
seq_root = './{}/images/{}'.format(MOT_data, phase)
|
||||
label_root = './{}/labels_with_ids/{}'.format(MOT_data, phase)
|
||||
mkdir_if_missing(label_root)
|
||||
seqs = [s for s in os.listdir(seq_root)]
|
||||
print('seqs => ', seqs)
|
||||
tid_curr = 0
|
||||
tid_last = -1
|
||||
for seq in seqs:
|
||||
seq_info = open(osp.join(seq_root, seq, 'seqinfo.ini')).read()
|
||||
seq_width = int(seq_info[seq_info.find('imWidth=') + 8:seq_info.find(
|
||||
'\nimHeight')])
|
||||
seq_height = int(seq_info[seq_info.find('imHeight=') + 9:seq_info.find(
|
||||
'\nimExt')])
|
||||
|
||||
gt_txt = osp.join(seq_root, seq, 'gt', 'gt.txt')
|
||||
gt = np.loadtxt(gt_txt, dtype=np.float64, delimiter=',')
|
||||
|
||||
seq_label_root = osp.join(label_root, seq, 'img1')
|
||||
mkdir_if_missing(seq_label_root)
|
||||
|
||||
for fid, tid, x, y, w, h, mark, label, _ in gt:
|
||||
# if mark == 0 or not label == 1:
|
||||
# continue
|
||||
fid = int(fid)
|
||||
tid = int(tid)
|
||||
if not tid == tid_last:
|
||||
tid_curr += 1
|
||||
tid_last = tid
|
||||
x += w / 2
|
||||
y += h / 2
|
||||
label_fpath = osp.join(seq_label_root, '{:07d}.txt'.format(fid))
|
||||
label_str = '0 {:d} {:.6f} {:.6f} {:.6f} {:.6f}\n'.format(
|
||||
tid_curr, x / seq_width, y / seq_height, w / seq_width,
|
||||
h / seq_height)
|
||||
with open(label_fpath, 'a') as f:
|
||||
f.write(label_str)
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description='input method')
|
||||
parser.add_argument("--transMot", type=bool, default=False)
|
||||
parser.add_argument("--genMot", type=bool, default=False)
|
||||
parser.add_argument("--formatMotPath", type=bool, default=False)
|
||||
parser.add_argument("--deleteEmpty", type=bool, default=False)
|
||||
parser.add_argument("--genLabelsMot", type=bool, default=False)
|
||||
parser.add_argument("--genImageList", type=bool, default=False)
|
||||
parser.add_argument("--visualImg", type=bool, default=False)
|
||||
parser.add_argument("--visualGt", type=bool, default=False)
|
||||
parser.add_argument("--data_name", type=str, default='visdrone_vehicle')
|
||||
parser.add_argument("--phase", type=str, default='train')
|
||||
parser.add_argument("--classes", type=str, default='4,5,6,9')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_arguments()
|
||||
classes = args.classes.split(',')
|
||||
datasetPath = './'
|
||||
dataName = args.data_name
|
||||
phase = args.phase
|
||||
if args.transMot:
|
||||
genMotLabels(datasetPath, dataName, classes)
|
||||
formatMot16Path(dataName, pathType=phase)
|
||||
mot16Path = f'./{dataName}'
|
||||
deleteFileWhichImg1IsEmpty(mot16Path, dataType=phase)
|
||||
gen_labels_mot(dataName, phase=phase)
|
||||
gen_image_list(dataName, phase)
|
||||
if args.genMot:
|
||||
genMotLabels(datasetPath, dataName, classes)
|
||||
if args.formatMotPath:
|
||||
formatMot16Path(dataName, pathType=phase)
|
||||
if args.deleteEmpty:
|
||||
mot16Path = f'./{dataName}'
|
||||
deleteFileWhichImg1IsEmpty(mot16Path, dataType=phase)
|
||||
if args.genLabelsMot:
|
||||
gen_labels_mot(dataName, phase=phase)
|
||||
if args.genImageList:
|
||||
gen_image_list(dataName, phase)
|
||||
if args.visualGt:
|
||||
VisualGt(f'./{dataName}', phase)
|
||||
if args.visualImg:
|
||||
seqName = 'uav0000137_00458_v'
|
||||
frameId = 43
|
||||
VisualDataset(
|
||||
f'./{dataName}', phase=phase, seqName=seqName, frameId=frameId)
|
||||
Reference in New Issue
Block a user