diff --git a/python/ftl/ftlstream.py b/python/ftl/ftlstream.py index ccf22520ada31c40839eefc0d1fd4b71cf866701..45b0f8c310aec64549c5637809fe4c45cdfb1ee4 100644 --- a/python/ftl/ftlstream.py +++ b/python/ftl/ftlstream.py @@ -2,8 +2,9 @@ import msgpack import numpy as np +import sys import struct - +from warnings import warn from enum import IntEnum from collections import namedtuple @@ -75,16 +76,18 @@ class FTLStreamReader: self._decoders = {} self._seen_iframe = set() - self._frames = {} + self._frameset = {} + self._frameset_new = {} + self._frame = None + self._calibration = {} self._pose = {} - self._ts = -1 + self._ts = -sys.maxsize - 1 try: magic = self._file.read(5) if magic[:4] != bytes(ord(c) for c in "FTLF"): raise Exception("wrong magic") - print(magic[4]) self._unpacker = msgpack.Unpacker(self._file, raw=True, use_list=False) @@ -137,6 +140,7 @@ class FTLStreamReader: if k not in self._seen_iframe: if not is_iframe(p.data): # can't decode before first I-frame has been received + warn("received P-frame before I-frame") return self._seen_iframe.add(k) @@ -147,11 +151,13 @@ class FTLStreamReader: while decoder.get_number_of_input_bytes_pending() > 0: decoder.decode() - img = None - while img is None: - img = decoder.get_next_picture() + img = decoder.get_next_picture() + if img is None: + # if this happens, does get_next_picture() in loop help? + warn("frame expected, no image from decoded") - self._frames[k] = _ycrcb2rgb(img) + self._frame = _ycrcb2rgb(img) + self._frameset_new[k] = self._frame def _flush_decoders(self): for decoder in self._decoders.values(): @@ -171,15 +177,25 @@ class FTLStreamReader: Reads data for until the next timestamp. Returns False if there is no more data to read, otherwise returns True. ''' + self._frame = None try: self._sp, self._p = self._read_next() self._packets_read += 1 except msgpack.OutOfData: + self._frameset = self._frameset_new + self._frameset_new = {} return False - self._ts = max(self._sp.timestamp, self._ts) + if self._sp.timestamp < self._ts: + # old data, do not update + return True + + if self._sp.timestamp > self._ts: + self._ts = self._sp.timestamp + self._frameset = self._frameset_new + self._frameset_new = {} if self._p.block_total != 1 or self._p.block_number != 0: raise Exception("Unsupported block format (todo)") @@ -233,17 +249,24 @@ class FTLStreamReader: except KeyError: raise ValueError("source id %i not found" % source) - def get_frames(self): - ''' All frames ''' - return self._frames + def get_frame(self): + ''' Return decoded frame from previous packet. Returns None if previous + packet did not contain a (valid) frame. ''' + return self._frame + + def get_frameset(self): + return self._frameset - def get_frame(self, source, channel): + def get_frameset_frame(self, source, channel): k = (source, channel) - if k in self._frames: - return self._frames[k] + if k in self._frameset: + return self._frameset[k] else: # raise an exception instead? return None + + def get_frameset_sources(self): + return list(set(src for src, _ in self._frameset.keys())) def get_Q(self, source): ''' Disparity to depth matrix in OpenCV format ''' @@ -260,4 +283,5 @@ class FTLStreamReader: def get_sources(self): ''' Get list of sources ''' - return list(self._calibration.keys()) \ No newline at end of file + return list(self._calibration.keys()) + diff --git a/python/ftl/ftltypes.py b/python/ftl/ftltypes.py index b72f5606c15fcbcb63f30d90f54d0d59dd25fa2a..3481d248eac4eeb426c615f558bfdb9899ab088e 100644 --- a/python/ftl/ftltypes.py +++ b/python/ftl/ftltypes.py @@ -68,3 +68,11 @@ definition_t = { 7 : (0, 0), 8 : (2056, 1852) } + +def get_definition(shape): + for k, v in definition_t.items(): + if shape[:2] == v: + return k + + return 7 # (None) + diff --git a/python/ftl/libde265.py b/python/ftl/libde265.py index afa663640191b2b2ec64e4b5ab04c85ad5ea575a..8b11df50eb11120c8d49e7768116a0fb456d26a7 100644 --- a/python/ftl/libde265.py +++ b/python/ftl/libde265.py @@ -184,6 +184,7 @@ class Decoder: img_ptr = libde265.de265_get_image_plane(de265_image, c, self._out_stride) + # for frombuffer() no copy assumed ch = np.frombuffer(img_ptr[:size[0] * size[1]], dtype=np.uint8) ch.shape = size diff --git a/python/ftl/misc.py b/python/ftl/misc.py index 791dccf141d8129a03b1221f524fef03d0d96b42..5494382ca1376c8bf96a9d30d7d863d8bfc9eff9 100644 --- a/python/ftl/misc.py +++ b/python/ftl/misc.py @@ -1,7 +1,12 @@ -def disparity_to_depth(disparity, camera): - ''' Calculate depth map from disparity map ''' - return (camera.fx * camera.baseline) / (disparity - camera.doff) +def disparity_to_depth(disparity, camera, max_depth=10.0, invalid_value=0.0): + ''' Calculate depth map from disparity map. Depth values smaller than 0.0 + and larger than max_depth are set to invalid_value. + ''' + depth = (camera.fx * camera.baseline) / (disparity - camera.doff) + depth[depth < 0] = invalid_value + depth[depth > max_depth] = invalid_value + return depth from enum import IntEnum