- 比赛介绍我选择的赛题二,打算做同一个目标跟踪的东西
简介:
在线的物体检测分割,该项目是cvpr2021年提出的,使用了先进的一种用于多目标跟踪的算法。该算法结合了目标检测、语义分割和运动预测等技术,可以同时对多个目标进行跟踪,并在跟踪的过程中实时地对目标进行检测和分割
模型结构
该算法的模型结构主要包括三个组成部分:
目标检测器:采用现有的目标检测算法,如 Faster R-CNN 或 YOLOv3 等,来检测出图像中的目标物体。
语义分割器:采用现有的语义分割算法,如 Mask R-CNN 等,来对图像中的目标进行像素级别的分割。
运动预测器:利用卡尔曼滤波器等技术,对目标的运动轨迹进行预测。
思想
该算法的主要思想是将目标检测、语义分割和运动预测等技术相结合,实现对多个目标的实时跟踪。具体步骤如下:
利用目标检测器对图像中的目标进行检测,并将检测结果作为初始跟踪框。
利用语义分割器对每个目标进行像素级别的分割,得到目标的精确位置信息。
利用运动预测器对每个目标的运动轨迹进行预测,得到目标在下一帧图像中的位置信息。
根据预测的位置信息,对跟踪框进行更新和修正,实现对目标的实时跟踪。
- 模型训练模型结构如下:
- 模型测试
测试代码如下:
class PrefetchDataset(torch.utils.data.Dataset):
def __init__(self, opt, dataset, pre_process_func):
self.images = dataset.images
self.load_image_func = dataset.coco.loadImgs
self.img_dir = dataset.img_dir
self.pre_process_func = pre_process_func
self.get_default_calib = dataset.get_default_calib
self.opt = opt
def __getitem__(self, index):
img_id = self.images[index]
img_info = self.load_image_func(ids=[img_id])[0]
img_path = os.path.join(self.img_dir, img_info['file_name'])
image = cv2.imread(img_path)
images, meta = {}, {}
for scale in opt.test_scales:
input_meta = {}
calib = img_info['calib'] if 'calib' in img_info \
else self.get_default_calib(image.shape[1], image.shape[0])
input_meta['calib'] = calib
images[scale], meta[scale] = self.pre_process_func(
image, scale, input_meta)
ret = {'images': images, 'image': image, 'meta': meta}
if 'frame_id' in img_info and img_info['frame_id'] == 1:
ret['is_first_frame'] = 1
ret['video_id'] = img_info['video_id']
return img_id, ret
def __len__(self):
return len(self.images)
def prefetch_test(opt):
if not opt.not_set_cuda_env:
os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str
Dataset = dataset_factory[opt.test_dataset]
opt = opts().update_dataset_info_and_set_heads(opt, Dataset)
print(opt)
Logger(opt)
split = 'val' if not opt.trainval else 'test'
dataset = Dataset(opt, split)
detector = Detector(opt)
if opt.load_results != '':
load_results = json.load(open(opt.load_results, 'r'))
for img_id in load_results:
for k in range(len(load_results[img_id])):
if load_results[img_id][k]['class'] - 1 in opt.ignore_loaded_cats:
load_results[img_id][k]['score'] = -1
else:
load_results = {}
data_loader = torch.utils.data.DataLoader(
PrefetchDataset(opt, dataset, detector.pre_process),
batch_size=1, shuffle=False, num_workers=1, pin_memory=True)
results = {}
num_iters = len(data_loader) if opt.num_iters < 0 else opt.num_iters
bar = Bar('{}'.format(opt.exp_id), max=num_iters)
time_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge', 'track']
avg_time_stats = {t: AverageMeter() for t in time_stats}
if opt.use_loaded_results:
for img_id in data_loader.dataset.images:
results[img_id] = load_results['{}'.format(img_id)]
num_iters = 0
ii = 0
our_time = 0
for ind, (img_id, pre_processed_images) in enumerate(data_loader):
if ind >= num_iters:
break
if opt.tracking and ('is_first_frame' in pre_processed_images):
if '{}'.format(int(img_id.numpy().astype(np.int32)[0])) in load_results:
pre_processed_images['meta']['pre_dets'] = \
load_results['{}'.format(int(img_id.numpy().astype(np.int32)[0]))]
else:
print()
print('No pre_dets for', int(img_id.numpy().astype(np.int32)[0]),
'. Use empty initialization.')
pre_processed_images['meta']['pre_dets'] = []
detector.reset_tracking()
print('Start tracking video', int(pre_processed_images['video_id']))
if opt.public_det:
if '{}'.format(int(img_id.numpy().astype(np.int32)[0])) in load_results:
pre_processed_images['meta']['cur_dets'] = \
load_results['{}'.format(int(img_id.numpy().astype(np.int32)[0]))]
else:
print('No cur_dets for', int(img_id.numpy().astype(np.int32)[0]))
pre_processed_images['meta']['cur_dets'] = []
ret = detector.run(pre_processed_images, img_id=int(img_id.numpy().astype(np.int32)[0]))
results[int(img_id.numpy().astype(np.int32)[0])] = ret['results']
ii += 1
our_time += ret['our_time']
Bar.suffix = '[{0}/{1}]|Tot: {total:} |ETA: {eta:} '.format(
ind, num_iters, total=bar.elapsed_td, eta=bar.eta_td)
for t in avg_time_stats:
avg_time_stats[t].update(ret[t])
Bar.suffix = Bar.suffix + '|{} {tm.val:.3f}s ({tm.avg:.3f}s) '.format(
t, tm = avg_time_stats[t])
if opt.print_iter > 0:
if ind % opt.print_iter == 0:
print('{}/{}| {}'.format(opt.task, opt.exp_id, Bar.suffix))
else:
bar.next()
print('\n', 'average runtime: {}s / image'.format(round(our_time*1.0/ii, 3)))
bar.finish()
if opt.save_results:
print('saving results to', opt.save_dir + '/results_{}{}.json'.format(
opt.test_dataset, opt.dataset_version))
json.dump(_to_list(copy.deepcopy(results)),
open(opt.save_dir + '/results_{}{}.json'.format(
opt.test_dataset, opt.dataset_version), 'w'))
dataset.run_eval(results, opt.save_dir)
def test(opt):
os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str
Dataset = dataset_factory[opt.test_dataset]
opt = opts().update_dataset_info_and_set_heads(opt, Dataset)
print(opt)
Logger(opt)
split = 'val' if not opt.trainval else 'test'
dataset = Dataset(opt, split)
detector = Detector(opt)
if opt.load_results != '': # load results in json
load_results = json.load(open(opt.load_results, 'r'))
results = {}
num_iters = len(dataset) if opt.num_iters < 0 else opt.num_iters
bar = Bar('{}'.format(opt.exp_id), max=num_iters)
time_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge']
avg_time_stats = {t: AverageMeter() for t in time_stats}
for ind in range(num_iters):
img_id = dataset.images[ind]
img_info = dataset.coco.loadImgs(ids=[img_id])[0]
img_path = os.path.join(dataset.img_dir, img_info['file_name'])
input_meta = {}
if 'calib' in img_info:
input_meta['calib'] = img_info['calib']
if (opt.tracking and ('frame_id' in img_info) and img_info['frame_id'] == 1):
detector.reset_tracking()
input_meta['pre_dets'] = load_results[img_id]
ret = detector.run(img_path, input_meta)
results[img_id] = ret['results']
Bar.suffix = '[{0}/{1}]|Tot: {total:} |ETA: {eta:} '.format(
ind, num_iters, total=bar.elapsed_td, eta=bar.eta_td)
for t in avg_time_stats:
avg_time_stats[t].update(ret[t])
Bar.suffix = Bar.suffix + '|{} {:.3f} '.format(t, avg_time_stats[t].avg)
bar.next()
bar.finish()
if opt.save_results:
print('saving results to', opt.save_dir + '/save_results_{}{}.json'.format(
opt.test_dataset, opt.dataset_version))
json.dump(_to_list(copy.deepcopy(results)),
open(opt.save_dir + '/save_results_{}{}.json'.format(
opt.test_dataset, opt.dataset_version), 'w'))
dataset.run_eval(results, opt.save_dir)
- Intel架构的使用。Intel Distribution of Modin* 和 Intel Extension for Scikit-learn* 可以用于加速数据处理和机器学习模型训练的过程,从而提高算法的效率和性能。在 # Track to Detect and Segment: An Online Multi-Object Tracker 中,可以通过以下方式使用这些工具:
数据处理:利用 Intel Distribution of Modin* 中的 Pandas API 替代原生 Pandas API,可以加速数据处理的过程。例如,在读取大量数据时,可以使用 Modin.read_csv() 方法代替 Pandas.read_csv() 方法,从而提高数据读取的速度。
机器学习模型训练:利用 Intel Extension for Scikit-learn* 中的优化算法和工具,可以加速机器学习模型的训练过程。例如,在进行模型参数调优时,可以使用 Intel Extension for Scikit-learn* 中的 GridSearchCV 或 RandomizedSearchCV 方法,从而加速参数搜索的过程。
- 总结
在本次比赛中,我使用了图像分割模型,对于不同的场景也有很高的精确度。在Intel架构的使用中,极大的帮助了我构建以及分析模型,是个不可多得的的好帮手。