Skip to content

Commit

Permalink
Merge pull request #1609 from papr/video_overlay_fill_gaps
Browse files Browse the repository at this point in the history
Fill gaps on video overlays
  • Loading branch information
papr authored Sep 11, 2019
2 parents 0dcda92 + 5af11bc commit 4cab71d
Showing 4 changed files with 35 additions and 11 deletions.
4 changes: 3 additions & 1 deletion pupil_src/shared_modules/video_capture/file_backend.py
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ class FileSeekError(Exception):
pass


class Frame(object):
class Frame:
"""docstring of Frame"""

def __init__(self, timestamp, av_frame, index):
@@ -52,6 +52,7 @@ def __init__(self, timestamp, av_frame, index):
self._av_frame = av_frame
self._img = None
self._gray = None
self.is_fake = False

def copy(self):
return Frame(self.timestamp, self._av_frame, self.index)
@@ -94,6 +95,7 @@ def __init__(self, width, height, timestamp, index):
shape = (self.height, self.width, 3)
static_img = np.ones(shape, dtype=np.uint8) * 128
self.img = self.bgr = static_img
self.is_fake = True

def copy(self):
return FakeFrame(self.width, self.height, self.timestamp, self.index)
22 changes: 14 additions & 8 deletions pupil_src/shared_modules/video_overlay/utils/image_manipulation.py
Original file line number Diff line number Diff line change
@@ -6,26 +6,32 @@

class ImageManipulator(metaclass=abc.ABCMeta):
@abc.abstractmethod
def apply_to(self, image, parameter):
def apply_to(self, image, parameter, **kwargs):
raise NotImplementedError


class ScaleTransform(ImageManipulator):
def apply_to(self, image, parameter):
def apply_to(self, image, parameter, **kwargs):
"""parameter: scale factor as float"""
return cv2.resize(image, (0, 0), fx=parameter, fy=parameter)


class HorizontalFlip(ImageManipulator):
def apply_to(self, image, parameter):
def apply_to(self, image, parameter, *, is_fake_frame, **kwargs):
"""parameter: boolean indicating if image should be flipped"""
return np.fliplr(image) if parameter else image
if parameter and not is_fake_frame:
return np.fliplr(image)
else:
return image


class VerticalFlip(ImageManipulator):
def apply_to(self, image, parameter):
def apply_to(self, image, parameter, *, is_fake_frame, **kwargs):
"""parameter: boolean indicating if image should be flipped"""
return np.flipud(image) if parameter else image
if parameter and not is_fake_frame:
return np.flipud(image)
else:
return image


class PupilRenderer(ImageManipulator):
@@ -34,9 +40,9 @@ class PupilRenderer(ImageManipulator):
def __init__(self, pupil_getter):
self.pupil_getter = pupil_getter

def apply_to(self, image, parameter):
def apply_to(self, image, parameter, *, is_fake_frame, **kwargs):
"""parameter: boolean indicating if pupil should be rendered"""
if parameter:
if parameter and not is_fake_frame:
pupil_position = self.pupil_getter()
if pupil_position:
self.render_pupil(image, pupil_position)
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ class FrameFetcher:

def __init__(self, video_path):
self.source = File_Source(
SimpleNamespace(), source_path=video_path, timing=None
SimpleNamespace(), source_path=video_path, timing=None, fill_gaps=True
)
if not self.source.initialised:
raise FileNotFoundError(video_path)
Original file line number Diff line number Diff line change
@@ -39,8 +39,24 @@ def draw_on_frame(self, target_frame):
return
overlay_frame = self.video.closest_frame_to_ts(target_frame.timestamp)
overlay_image = overlay_frame.img
try:
is_fake_frame = overlay_frame.is_fake
# TODO: once we have the unified Frame class, we should just pass the frames
# to the image manipulation pipeline (instead of the images). Then we can
# get rid of the additional parameter stuff in ImageManipulation!
except AttributeError:
# TODO: this is only fore extra safety until we have a unified Frame class
# and can be sure that everything ending up here has the 'is_fake'
# attribute!
logger.warning(
f"Frame passed to overlay renderer does not have 'is_fake' attribute!"
f" Frame: {overlay_frame}"
)
is_fake_frame = False
for param, manipulation in self.pipeline:
overlay_image = manipulation.apply_to(overlay_image, param.value)
overlay_image = manipulation.apply_to(
overlay_image, param.value, is_fake_frame=overlay_frame.is_fake
)

self._adjust_origin_constraint(target_frame.img, overlay_image)
self._render_overlay(target_frame.img, overlay_image)

0 comments on commit 4cab71d

Please sign in to comment.