Skip to content
Snippets Groups Projects
Commit 4fb514dc authored by Sebastian Hahta's avatar Sebastian Hahta
Browse files

Merge branch 'feature/python' into 'master'

Python: HEVC depth decoding

See merge request nicolas.pope/ftl!208
parents d55d10a0 dfe12e3d
No related branches found
No related tags found
1 merge request!208Python: HEVC depth decoding
Pipeline #17819 passed
......@@ -222,7 +222,7 @@ class FTLStreamReader:
k = (sp.streamID, sp.channel)
if k not in self._decoders_hevc:
self._decoders_hevc[k] = libde265.Decoder(ftl.definition_t[p.definition])
self._decoders_hevc[k] = libde265.Decoder()
decoder = self._decoders_hevc[k]
......@@ -243,10 +243,25 @@ class FTLStreamReader:
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")
warn("frame expected, no image received from decoder")
if ftl.is_float_channel(self._sp.channel):
raise NotImplementedError("non-color channel decoding not available")
# TODO: only supports 8 bits per pixel format and 16 bits
# ()"old format")
#
# NVPipe: (2 * width), high bits in left, low in right
high = img[:,(img.shape[1]//2):,0].astype(np.uint32) << 8
low = img[:,:(img.shape[1]//2),0].astype(np.uint32)
img = (high|low).astype(np.float)/1000.0
try:
img[img < self._calibration[sp.streamID].min_depth] = 0.0
img[img > self._calibration[sp.streamID].max_depth] = 0.0
except KeyError:
warn("no calibration for received frame")
self._frame = img
else:
if self._version < 3:
......
......@@ -164,8 +164,7 @@ class WaitingForInput(libde265Error):
pass
class Decoder:
def __init__(self, size, threads=_threads):
self._size = size
def __init__(self, threads=_threads):
self._more = ctypes.c_int()
self._out_stride = ctypes.c_int()
self._ctx = libde265.de265_new_decoder()
......@@ -180,26 +179,34 @@ class Decoder:
libde265.de265_free_decoder(self._ctx)
def _copy_image(self, de265_image):
res = np.zeros((self._size[0], self._size[1], 3), dtype=np.uint8)
size = (libde265.de265_get_image_height(de265_image, 0),
libde265.de265_get_image_width(de265_image, 0))
res = np.zeros((*size, 3), dtype=np.uint8)
# libde265: always 420 (???)
# chroma_format = libde265.de265_get_chroma_format(de265_image)
for c in range(0, 3):
size = (libde265.de265_get_image_height(de265_image, c),
size_channel = (libde265.de265_get_image_height(de265_image, c),
libde265.de265_get_image_width(de265_image, c))
if size_channel[0] > size[0] or size_channel[1] > size[1]:
# Is this possible?
print(size, size_channel)
raise Exception("Channel larger than first channel")
bpp = libde265.de265_get_bits_per_pixel(de265_image, c)
if bpp != 8:
raise NotImplementedError("unsupported bits per pixel %i" % bpp)
raise NotImplementedError("%i-bit format not implemented (TODO)" % bpp)
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
# libde: how is 10 bits per pixel returned
ch = np.frombuffer(img_ptr[:size_channel[0] * size_channel[1]], dtype=np.uint8)
ch.shape = size_channel
res[:,:,c] = _resize(ch, self._size)
res[:,:,c] = _resize(ch, size)
return res
......
......@@ -8,6 +8,13 @@ def disparity_to_depth(disparity, camera, max_depth=10.0, invalid_value=0.0):
depth[depth > max_depth] = invalid_value
return depth
def depth_to_disparity(depth, camera, invalid_value=0.0):
invalid = depth == 0.0
depth[invalid] = 1.0
disparity = ((camera.fx * camera.baseline) / depth) + camera.doff
disparity[invalid] = invalid_value
return disparity
from enum import IntEnum
# components/codecs/include/ftl/codecs/hevc.hpp
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment