Render directly to video

This commit is contained in:
Ruben van de Ven 2023-10-17 12:04:53 +02:00
parent 821d06c9cf
commit ec31810d80
4 changed files with 43 additions and 4 deletions

View File

@ -37,6 +37,7 @@ class FrameEmitter:
video = cv2.VideoCapture(str(self.config.video_src)) video = cv2.VideoCapture(str(self.config.video_src))
fps = video.get(cv2.CAP_PROP_FPS) fps = video.get(cv2.CAP_PROP_FPS)
frame_duration = 1./fps frame_duration = 1./fps
logger.info(f"Emit frames at {fps} fps")
prev_time = time.time() prev_time = time.time()
while self.is_running.is_set(): while self.is_running.is_set():
@ -65,4 +66,5 @@ class FrameEmitter:
def run_frame_emitter(config: Namespace, is_running: Event): def run_frame_emitter(config: Namespace, is_running: Event):
router = FrameEmitter(config, is_running) router = FrameEmitter(config, is_running)
router.emit_video() router.emit_video()
is_running.clear()

View File

@ -1,7 +1,11 @@
import atexit
import logging import logging
from logging.handlers import SocketHandler from logging.handlers import SocketHandler
from multiprocessing import Event, Process, Queue from multiprocessing import Event, Process, Queue
import multiprocessing
import signal
import sys import sys
import time
from trap.config import parser from trap.config import parser
from trap.frame_emitter import run_frame_emitter from trap.frame_emitter import run_frame_emitter
from trap.prediction_server import run_prediction_server from trap.prediction_server import run_prediction_server
@ -12,17 +16,28 @@ from trap.tracker import run_tracker
logger = logging.getLogger("trap.plumbing") logger = logging.getLogger("trap.plumbing")
class ExceptionHandlingProcess(Process): class ExceptionHandlingProcess(Process):
def run(self): def run(self):
assert 'is_running' in self._kwargs assert 'is_running' in self._kwargs
# exit handler to make sure that on many kinds of crashes and kills the
# suprocess warns parent/siblings
# TODO: Does not work with OOM kill. Would need a watchdog process for that
def exit_handler(*args):
self._kwargs['is_running'].clear()
atexit.register(exit_handler)
signal.signal(signal.SIGTERM, exit_handler)
signal.signal(signal.SIGINT, exit_handler)
try: try:
super(Process, self).run() super(Process, self).run()
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)
self._kwargs['is_running'].clear() self._kwargs['is_running'].clear()
def start(): def start():
args = parser.parse_args() args = parser.parse_args()
loglevel = logging.NOTSET if args.verbose > 1 else logging.DEBUG if args.verbose > 0 else logging.INFO loglevel = logging.NOTSET if args.verbose > 1 else logging.DEBUG if args.verbose > 0 else logging.INFO
@ -40,6 +55,8 @@ def start():
isRunning.set() isRunning.set()
if args.remote_log_addr: if args.remote_log_addr:
logging.captureWarnings(True) logging.captureWarnings(True)
root_logger.setLevel(logging.NOTSET) # to send all records to cutelog root_logger.setLevel(logging.NOTSET) # to send all records to cutelog
@ -64,6 +81,9 @@ def start():
for proc in procs: for proc in procs:
proc.start() proc.start()
# wait for processes to clean up
for proc in procs: for proc in procs:
proc.join() proc.join()
logger.info('Stop')

View File

@ -207,8 +207,13 @@ class PredictionServer:
trajectron.set_environment(online_env, init_timestep) trajectron.set_environment(online_env, init_timestep)
timestep = init_timestep + 1 timestep = init_timestep + 1
prev_run_time = 0
while self.is_running.is_set(): while self.is_running.is_set():
timestep += 1 timestep += 1
this_run_time = time.time()
logger.debug('test')
time.sleep(max(0, prev_run_time - this_run_time + .5))
prev_run_time = this_run_time
# for timestep in range(init_timestep + 1, eval_scene.timesteps): # for timestep in range(init_timestep + 1, eval_scene.timesteps):
# input_dict = eval_scene.get_clipped_input_dict(timestep, hyperparams['state']) # input_dict = eval_scene.get_clipped_input_dict(timestep, hyperparams['state'])

View File

@ -1,5 +1,6 @@
from argparse import Namespace from argparse import Namespace
import datetime
import logging import logging
from multiprocessing import Event from multiprocessing import Event
import cv2 import cv2
@ -36,6 +37,15 @@ class Renderer:
if not self.config.output_dir.exists(): if not self.config.output_dir.exists():
raise FileNotFoundError("Path does not exist") raise FileNotFoundError("Path does not exist")
date_str = datetime.datetime.now().isoformat(timespec="minutes")
filename = self.config.output_dir / f"render_predictions-{date_str}.mp4"
logger.info(f"Write to {filename}")
fourcc = cv2.VideoWriter_fourcc(*'vp09')
# TODO: get FPS from frame_emitter
self.out = cv2.VideoWriter(str(filename), fourcc, 23.97, (1280,720))
def run(self): def run(self):
predictions = {} predictions = {}
i=0 i=0
@ -81,8 +91,10 @@ class Renderer:
img_path = (self.config.output_dir / f"{i:05d}.png").resolve() img_path = (self.config.output_dir / f"{i:05d}.png").resolve()
cv2.imwrite(str(img_path), img) # cv2.imwrite(str(img_path), img)
self.out.write(img)
logger.info('Stopping') logger.info('Stopping')
self.out.release()