frames are now stored and returned as dictionaries with source name as key. Set to version 1.0.0 because this is a major breaking change.
This commit is contained in:
@ -4,7 +4,7 @@ Display any array, webcam, or video file.
|
||||
display is a function that displays these in their own windows.
|
||||
"""
|
||||
|
||||
__version__ = "0.7.5"
|
||||
__version__ = "1.0.0"
|
||||
|
||||
from .window.subscriber_windows import display, breakpoint_display, read_updates
|
||||
from .frame.frame_publishing import publish_updates_zero_mq, publish_updates_ros
|
||||
|
@ -35,7 +35,7 @@ class SubscriberWindows(object):
|
||||
"""Create the array displaying window."""
|
||||
self.source_names: List[Union[str, int]] = []
|
||||
self.close_threads: Optional[List[Thread]] = []
|
||||
self.frames: List[np.ndarray] = []
|
||||
self.frames: Dict[Union[str, int], np.ndarray] = {}
|
||||
self.input_vid_global_names: List[str] = []
|
||||
self.window_names: List[str] = []
|
||||
self.input_cams: List[str] = []
|
||||
@ -117,71 +117,98 @@ class SubscriberWindows(object):
|
||||
mousey = MouseEvent(event, x, y, flags, param)
|
||||
window_commands.mouse_pub.publish(mousey)
|
||||
|
||||
def display_frames(self, frames, win_num=0, ids=None):
|
||||
def display_frames(self, frames, win_num=0, prepend_name=""):
|
||||
"""Display a list of frames on multiple windows."""
|
||||
if isinstance(frames, Exception):
|
||||
raise frames
|
||||
for f in range(len(frames)):
|
||||
# detect nested:
|
||||
if (
|
||||
isinstance(frames[f], (list, tuple))
|
||||
or frames[f].dtype.num == 17
|
||||
or (
|
||||
len(frames[f].shape) != 2
|
||||
and (len(frames[f].shape) != 3 or frames[f].shape[-1] != 3)
|
||||
)
|
||||
):
|
||||
win_num = self.display_frames(frames[f], win_num, ids)
|
||||
else:
|
||||
if len(self.window_names) <= win_num:
|
||||
self.add_window(str(win_num))
|
||||
cv2.imshow(
|
||||
self.window_names[win_num] + " (press ESC to quit)", frames[f]
|
||||
)
|
||||
win_num += 1
|
||||
if isinstance(frames, dict):
|
||||
for f_name, f in frames.items():
|
||||
for i in range(len(f)):
|
||||
# detect nested:
|
||||
if (
|
||||
isinstance(f[i], (list, tuple))
|
||||
or f[i].dtype.num == 17
|
||||
or (
|
||||
len(f[i].shape) != 2
|
||||
and (len(f[i].shape) != 3 or f[i].shape[-1] != 3)
|
||||
)
|
||||
):
|
||||
win_num = self.display_frames(
|
||||
f[i], win_num, prepend_name=f"{f_name} - "
|
||||
)
|
||||
else:
|
||||
if len(self.window_names) <= win_num:
|
||||
self.add_window(f"{prepend_name}{win_num}")
|
||||
cv2.imshow(
|
||||
self.window_names[win_num] + " (press ESC to quit)", f[i]
|
||||
)
|
||||
win_num += 1
|
||||
else:
|
||||
for f in range(len(frames)):
|
||||
# detect nested:
|
||||
if (
|
||||
isinstance(frames[f], (list, tuple))
|
||||
or frames[f].dtype.num == 17
|
||||
or (
|
||||
len(frames[f].shape) != 2
|
||||
and (len(frames[f].shape) != 3 or frames[f].shape[-1] != 3)
|
||||
)
|
||||
):
|
||||
win_num = self.display_frames(frames[f], win_num, prepend_name)
|
||||
else:
|
||||
if len(self.window_names) <= win_num:
|
||||
self.add_window(f"{prepend_name} {win_num}")
|
||||
cv2.imshow(
|
||||
self.window_names[win_num] + " (press ESC to quit)", frames[f]
|
||||
)
|
||||
win_num += 1
|
||||
return win_num
|
||||
|
||||
def __check_too_many_channels(self):
|
||||
for f in range(len(self.frames)):
|
||||
if isinstance(self.frames[f], Exception):
|
||||
raise self.frames[f]
|
||||
if (
|
||||
isinstance(self.frames[f], np.ndarray)
|
||||
and self.frames[f].shape[-1] not in [1, 3]
|
||||
and len(self.frames[f].shape) != 2
|
||||
):
|
||||
print(
|
||||
f"Too many channels in output. (Got {self.frames[f].shape[-1]} instead of 1 or 3.) "
|
||||
f"Frame selection callback added."
|
||||
)
|
||||
print(
|
||||
"Ctrl+scroll to change first channel.\n"
|
||||
"Shift+scroll to change second channel.\n"
|
||||
"Alt+scroll to change third channel."
|
||||
)
|
||||
sel = SelectChannels()
|
||||
sel.enable_mouse_control()
|
||||
sel.mouse_print_channels = True
|
||||
self.callbacks.append(sel)
|
||||
for fr in range(len(self.frames)):
|
||||
self.frames[fr] = self.callbacks[-1](self.frames[fr])
|
||||
break
|
||||
for f_name, f in self.frames.items():
|
||||
for i in range(len(f)):
|
||||
if isinstance(f[i], Exception):
|
||||
raise f[i]
|
||||
if (
|
||||
isinstance(f[i], np.ndarray)
|
||||
and f[i].shape[-1] not in [1, 3]
|
||||
and len(f[i].shape) != 2
|
||||
):
|
||||
print(
|
||||
f"Too many channels in output. (Got {f[i].shape[-1]} instead of 1 or 3.) "
|
||||
f"Frame selection callback added."
|
||||
)
|
||||
print(
|
||||
"Ctrl+scroll to change first channel.\n"
|
||||
"Shift+scroll to change second channel.\n"
|
||||
"Alt+scroll to change third channel."
|
||||
)
|
||||
sel = SelectChannels()
|
||||
sel.enable_mouse_control()
|
||||
sel.mouse_print_channels = True
|
||||
self.callbacks.append(sel)
|
||||
for fr in range(len(f)):
|
||||
f[fr] = self.callbacks[-1](f[fr])
|
||||
break
|
||||
|
||||
def update_frames(self):
|
||||
"""Update the windows with the newest data for all frames."""
|
||||
self.frames = []
|
||||
self.frames = {}
|
||||
|
||||
for i in range(len(self.input_vid_global_names)):
|
||||
if self.input_vid_global_names[i] in self.FRAME_DICT and not isinstance(
|
||||
self.FRAME_DICT[self.input_vid_global_names[i]], NoData
|
||||
):
|
||||
self.frames.append(self.FRAME_DICT[self.input_vid_global_names[i]])
|
||||
if isinstance(self.frames, np.ndarray) and len(self.frames.shape) <= 3:
|
||||
self.frames = [self.frames]
|
||||
if self.input_vid_global_names[i] not in self.frames.keys():
|
||||
self.frames[self.input_vid_global_names[i]] = []
|
||||
self.frames[self.input_vid_global_names[i]].append(
|
||||
self.FRAME_DICT[self.input_vid_global_names[i]]
|
||||
)
|
||||
if len(self.callbacks) > 0:
|
||||
for c in self.callbacks:
|
||||
frame = c(self.frames[-1])
|
||||
frame = c(self.frames[self.input_vid_global_names[i]][-1])
|
||||
if frame is not None:
|
||||
self.frames[-1] = frame
|
||||
self.frames[self.input_vid_global_names[i]][-1] = frame
|
||||
if not self.silent:
|
||||
self.__check_too_many_channels()
|
||||
self.FRAME_DICT[self.input_vid_global_names[i]] = NoData()
|
||||
|
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = 'displayarray'
|
||||
version = '0.7.5'
|
||||
version = '1.0.0'
|
||||
description = 'Tool for displaying numpy arrays.'
|
||||
authors = ['SimLeek <simulator.leek@gmail.com>']
|
||||
license = 'MIT'
|
||||
|
@ -193,7 +193,7 @@ def test_update_frames():
|
||||
|
||||
sw.update_frames()
|
||||
|
||||
assert sw.frames == [frame]
|
||||
assert sw.frames == {"0": [frame]}
|
||||
mock_imshow.assert_called_once_with("displayarray (press ESC to quit)", frame)
|
||||
|
||||
|
||||
@ -219,7 +219,7 @@ def test_update_frames_callback():
|
||||
|
||||
sw.update_frames()
|
||||
|
||||
assert sw.frames == [frame3, frame3]
|
||||
assert sw.frames == {"0": [frame3], "1": [frame3]}
|
||||
assert np.all(cb.mock_calls[0].args[0] == frame)
|
||||
assert np.all(cb2.mock_calls[0].args[0] == frame2)
|
||||
mock_imshow.assert_has_calls(
|
||||
@ -260,7 +260,7 @@ def test_update_frames_too_many_channels():
|
||||
assert isinstance(sw.callbacks[-1], SelectChannels)
|
||||
assert sw.callbacks[-1].mouse_control is not None
|
||||
assert sw.callbacks[-1].mouse_print_channels is True
|
||||
assert sw.frames[0].shape[-1] == 3
|
||||
assert sw.frames["0"][0].shape[-1] == 3
|
||||
|
||||
|
||||
def test_update_frames_nested():
|
||||
@ -275,47 +275,47 @@ def test_update_frames_nested():
|
||||
|
||||
sw.update_frames()
|
||||
|
||||
assert np.all(sw.frames[0] == np.ones((20, 100, 100, 3)))
|
||||
assert np.all(sw.frames["0"][0] == np.ones((20, 100, 100, 3)))
|
||||
assert len(sw.frames) == 1
|
||||
assert mock_imshow.mock_calls[0].args[0] == "displayarray (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[0].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[1].args[0] == "1 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[1].args[0] == "0 - 1 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[1].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[2].args[0] == "2 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[2].args[0] == "0 - 2 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[2].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[3].args[0] == "3 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[3].args[0] == "0 - 3 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[3].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[4].args[0] == "4 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[4].args[0] == "0 - 4 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[4].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[5].args[0] == "5 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[5].args[0] == "0 - 5 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[5].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[6].args[0] == "6 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[6].args[0] == "0 - 6 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[6].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[7].args[0] == "7 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[7].args[0] == "0 - 7 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[7].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[8].args[0] == "8 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[8].args[0] == "0 - 8 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[8].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[9].args[0] == "9 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[9].args[0] == "0 - 9 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[9].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[10].args[0] == "10 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[10].args[0] == "0 - 10 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[10].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[11].args[0] == "11 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[11].args[0] == "0 - 11 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[11].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[12].args[0] == "12 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[12].args[0] == "0 - 12 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[12].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[13].args[0] == "13 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[13].args[0] == "0 - 13 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[13].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[14].args[0] == "14 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[14].args[0] == "0 - 14 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[14].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[15].args[0] == "15 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[15].args[0] == "0 - 15 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[15].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[16].args[0] == "16 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[16].args[0] == "0 - 16 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[16].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[17].args[0] == "17 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[17].args[0] == "0 - 17 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[17].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[18].args[0] == "18 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[18].args[0] == "0 - 18 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[18].args[1] == np.ones((100, 100, 3)))
|
||||
assert mock_imshow.mock_calls[19].args[0] == "19 (press ESC to quit)"
|
||||
assert mock_imshow.mock_calls[19].args[0] == "0 - 19 (press ESC to quit)"
|
||||
assert np.all(mock_imshow.mock_calls[19].args[1] == np.ones((100, 100, 3)))
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user