Skip to content

Commit

Permalink
Grayscale property passthrough (#99)
Browse files Browse the repository at this point in the history
* Initial implementation

* Fix basic python and edge cases

* Fix auto-detection
  • Loading branch information
talmo committed Jul 2, 2024
1 parent 5a30110 commit 95b9c81
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
12 changes: 9 additions & 3 deletions sleap_io/io/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,13 @@ def num_frames(self) -> int:
@property
def img_shape(self) -> Tuple[int, int, int]:
"""Shape of a single frame in the video."""
height, width, channels = self.get_frame(0).shape
height, width, channels = self.read_test_frame().shape
if self.grayscale is None:
self.detect_grayscale()
if self.grayscale is False:
channels = 3
elif self.grayscale is True:
channels = 1
return int(height), int(width), int(channels)

@property
Expand Down Expand Up @@ -578,7 +584,7 @@ def read_test_frame(self) -> np.ndarray:
frame_idx = list(self.frame_map.keys())[0]
else:
frame_idx = 0
return self.read_frame(frame_idx)
return self._read_frame(frame_idx)

@property
def has_embedded_images(self) -> bool:
Expand Down Expand Up @@ -699,7 +705,7 @@ class ImageVideo(VideoBackend):
This backend supports reading videos stored as a list of images.
Attributes:
filename: Path to video files.
filename: Path to image files.
grayscale: Whether to force grayscale. If None, autodetect on first frame load.
"""

Expand Down
13 changes: 10 additions & 3 deletions sleap_io/model/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,16 @@ def grayscale(self) -> bool | None:
if shape is not None:
return shape[-1] == 1
else:
if "grayscale" in self.backend_metadata:
return self.backend_metadata["grayscale"]
return None
return self.backend_metadata.get("grayscale", None)

@grayscale.setter
def grayscale(self, value: bool):
"""Set the grayscale value and adjust the backend."""
if self.backend is not None:
self.backend.grayscale = value
self.backend._cached_shape = None

self.backend_metadata["grayscale"] = value

def __len__(self) -> int:
"""Return the length of the video as the number of frames."""
Expand Down
20 changes: 20 additions & 0 deletions tests/model/test_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,23 @@ def test_video_replace_filename(
video.replace_filename(centered_pair_frame_paths)
assert type(video.backend) == ImageVideo
assert video.exists(check_all=True) is True


def test_grayscale(centered_pair_low_quality_path):
video = Video.from_filename(centered_pair_low_quality_path)
assert video.grayscale == True
assert video.shape[-1] == 1

video.grayscale = False
assert video.shape[-1] == 3

video.close()
video.open()
assert video.grayscale == False
assert video.shape[-1] == 3

video.grayscale = True
video.close()
video.open()
assert video.grayscale == True
assert video.shape[-1] == 1

0 comments on commit 95b9c81

Please sign in to comment.