Video recorder in frame emitter (for gige video)
This commit is contained in:
parent
8b9723bdf4
commit
f427b6bb3b
4 changed files with 31 additions and 21 deletions
|
@ -371,9 +371,9 @@ def decorate_frame(frame: Frame, tracker_frame: Frame, prediction_frame: Frame,
|
||||||
for option, value in prediction_frame.log['predictor'].items():
|
for option, value in prediction_frame.log['predictor'].items():
|
||||||
options.append(f"{option}: {value}")
|
options.append(f"{option}: {value}")
|
||||||
|
|
||||||
|
if len(options):
|
||||||
cv2.putText(img, options.pop(-1), (20,img.shape[0]-30), cv2.FONT_HERSHEY_PLAIN, 1, base_color, 1)
|
cv2.putText(img, options.pop(-1), (20,img.shape[0]-30), cv2.FONT_HERSHEY_PLAIN, 1, base_color, 1)
|
||||||
cv2.putText(img, " | ".join(options), (20,img.shape[0]-10), cv2.FONT_HERSHEY_PLAIN, 1, base_color, 1)
|
cv2.putText(img, " | ".join(options), (20,img.shape[0]-10), cv2.FONT_HERSHEY_PLAIN, 1, base_color, 1)
|
||||||
|
|
||||||
return img
|
return img
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import multiprocessing
|
|
||||||
import pickle
|
import pickle
|
||||||
from argparse import ArgumentParser, Namespace
|
from argparse import ArgumentParser, Namespace
|
||||||
from multiprocessing import Event
|
from multiprocessing import Event
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import zmq
|
|
||||||
|
|
||||||
from trap import node
|
from trap import node
|
||||||
from trap.base import *
|
from trap.base import *
|
||||||
from trap.base import LambdaParser
|
from trap.base import LambdaParser
|
||||||
from trap.timer import Timer
|
from trap.preview_renderer import FrameWriter
|
||||||
from trap.video_sources import get_video_source
|
from trap.video_sources import get_video_source
|
||||||
|
|
||||||
logger = logging.getLogger('trap.frame_emitter')
|
logger = logging.getLogger('trap.frame_emitter')
|
||||||
|
@ -39,20 +36,31 @@ class FrameEmitter(node.Node):
|
||||||
offset = int(self.config.video_offset or 0)
|
offset = int(self.config.video_offset or 0)
|
||||||
source = get_video_source(self.video_srcs, self.config.camera, offset, self.config.video_end, self.config.video_loop)
|
source = get_video_source(self.video_srcs, self.config.camera, offset, self.config.video_end, self.config.video_loop)
|
||||||
video_gen = enumerate(source, start = offset)
|
video_gen = enumerate(source, start = offset)
|
||||||
while self.run_loop():
|
|
||||||
|
|
||||||
try:
|
# writer = FrameWriter(self.config.record, None, None) if self.config.record else nullcontext
|
||||||
i, img = next(video_gen)
|
print(self.config.record)
|
||||||
except StopIteration as e:
|
writer = FrameWriter(str(self.config.record), None, None) if self.config.record else None
|
||||||
logger.info("Video source ended")
|
try:
|
||||||
break
|
while self.run_loop():
|
||||||
|
|
||||||
frame = Frame(i, img=img, H=self.config.camera.H, camera=self.config.camera)
|
try:
|
||||||
|
i, img = next(video_gen)
|
||||||
|
except StopIteration as e:
|
||||||
|
logger.info("Video source ended")
|
||||||
|
break
|
||||||
|
|
||||||
# TODO: this is very dirty, need to find another way.
|
frame = Frame(i, img=img, H=self.config.camera.H, camera=self.config.camera)
|
||||||
# perhaps multiprocessing Array?
|
|
||||||
self.frame_noimg_sock.send(pickle.dumps(frame.without_img()))
|
# TODO: this is very dirty, need to find another way.
|
||||||
self.frame_sock.send(pickle.dumps(frame))
|
# perhaps multiprocessing Array?
|
||||||
|
self.frame_noimg_sock.send(pickle.dumps(frame.without_img()))
|
||||||
|
self.frame_sock.send(pickle.dumps(frame))
|
||||||
|
|
||||||
|
if writer:
|
||||||
|
writer.write(frame.img)
|
||||||
|
finally:
|
||||||
|
if writer:
|
||||||
|
writer.release()
|
||||||
|
|
||||||
|
|
||||||
logger.info("Stopping")
|
logger.info("Stopping")
|
||||||
|
@ -84,6 +92,10 @@ class FrameEmitter(node.Node):
|
||||||
help="End (or loop) playback at given frame.",
|
help="End (or loop) playback at given frame.",
|
||||||
default=None,
|
default=None,
|
||||||
type=int)
|
type=int)
|
||||||
|
argparser.add_argument("--record",
|
||||||
|
help="Record source video to given filename",
|
||||||
|
default=None,
|
||||||
|
type=Path)
|
||||||
|
|
||||||
argparser.add_argument("--video-loop",
|
argparser.add_argument("--video-loop",
|
||||||
help="By default it emitter will run only once. This allows it to loop the video file to keep testing.",
|
help="By default it emitter will run only once. This allows it to loop the video file to keep testing.",
|
||||||
|
|
|
@ -300,7 +300,7 @@ class FrameWriter:
|
||||||
"""
|
"""
|
||||||
def __init__(self, filename: str, fps: float, frame_size: Optional[tuple] = None) -> None:
|
def __init__(self, filename: str, fps: float, frame_size: Optional[tuple] = None) -> None:
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.fps = fps
|
self._fps = fps
|
||||||
self.frame_size = frame_size
|
self.frame_size = frame_size
|
||||||
|
|
||||||
self.tmp_dir = tempfile.TemporaryDirectory(prefix="trap-output-")
|
self.tmp_dir = tempfile.TemporaryDirectory(prefix="trap-output-")
|
||||||
|
|
|
@ -107,8 +107,6 @@ class GigE(VideoSource):
|
||||||
br = self.config.post_crop_br or (img.shape[1], img.shape[0])
|
br = self.config.post_crop_br or (img.shape[1], img.shape[0])
|
||||||
|
|
||||||
return img[tl[1]:br[1],tl[0]:br[0],:]
|
return img[tl[1]:br[1],tl[0]:br[0],:]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SingleCvVideoSource(VideoSource):
|
class SingleCvVideoSource(VideoSource):
|
||||||
def recv(self):
|
def recv(self):
|
||||||
|
|
Loading…
Reference in a new issue