任务场景:检测现场视频中出现行人的时间段。这只是一个大致的方向,本文实现以了下两个具体细节:
- 由于每一帧相比上一帧中行人的动作变换幅度不大,对视频相隔一定帧数进行检测以减少整段视频的检测时长和提高后续人工检测的效率。
- 在1的基础上,滤除未检测到行人的视频段,进一步提高后续人工检测的效率。
注:由于动态图行人检测模型在检测视频过程中会出现CUDA显存泄露问题,因此本文在静态图模型下调试成功。 https://github.com/PaddlePaddle/PaddleDetection/issues/2999
整体思路:
- 使用 export_model 导出静态图行人检测模型。https://paddlemodels.bj.bcebos.com/object_detection/yolov3_darknet.tar
- 在 infer.py 添加相隔帧数的输入参数,在 predict_video 添加 if 相隔帧数 != ' ' 代码块,写入相关逻辑,这样不会影响到原来帧帧检测的功能。在此基础上再添加0行人的视频段滤除逻辑。
具体实现:
- 添加相隔帧参数
parser.add_argument( "--step_frame", type=int, default='', help="Step of frame when detect video file")
- 添加相隔帧数检测和逻辑,0行人视频段滤除只需要从boxes.shape来实现即可
def predict_video(detector, camera_id):
if camera_id != -1:
capture = cv2.VideoCapture(camera_id)
video_name = 'output.mp4'
else:
capture = cv2.VideoCapture(FLAGS.video_file)
video_name = os.path.split(FLAGS.video_file)[-1]
fps = 30
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
if not os.path.exists(FLAGS.output_dir):
os.makedirs(FLAGS.output_dir)
out_path = os.path.join(FLAGS.output_dir, video_name)
writer = cv2.VideoWriter(out_path, fourcc, fps, (width, height))
index = 1
if FLAGS.step_frame != '':
count = 1
while True:
ret, frame = capture.read()
if not ret:
break
print('detect frame:%d' % index)
if count % FLAGS.step_frame == 0: # 相隔 step_frame 帧检测
index += 1
results = detector.predict(frame, FLAGS.threshold)
if results['boxes'].shape[0] != 0: # 0行人视频段滤除
im = visualize_box_mask(
frame,
results,
detector.config.labels,
mask_resolution=detector.config.mask_resolution,
threshold=FLAGS.threshold)
im = np.array(im)
writer.write(im)
if camera_id != -1:
cv2.imshow('Mask Detection', im)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
count += 1
writer.release()
else:
while True:
ret, frame = capture.read()
if not ret:
break
print('detect frame:%d' % index)
index += 1
results = detector.predict(frame, FLAGS.threshold)
im = visualize_box_mask(
frame,
results,
detector.config.labels,
mask_resolution=detector.config.mask_resolution,
threshold=FLAGS.threshold)
im = np.array(im)
writer.write(im)
if camera_id != -1:
cv2.imshow('Mask Detection', im)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
writer.release()
生成结果对比:
帧帧检测视频:
隔帧检测视频:
隔帧检测+0行人滤除: