nesting: Added ability to display tensors of any rank as multiple windows. Added to readme. lowered opencv_python requirement due to char* assertion bug.
This commit is contained in:
10
README.md
10
README.md
@ -41,6 +41,16 @@ Python 2.7/3.5+ and PyPy.
|
|||||||
|
|
||||||
w.VideoHandlerThread(callbacks=[redden_frame_print_spam] + w.display_callbacks).display()
|
w.VideoHandlerThread(callbacks=[redden_frame_print_spam] + w.display_callbacks).display()
|
||||||
|
|
||||||
|
#### Display a tensor
|
||||||
|
|
||||||
|
def tensor_from_image(frame, cam_id):
|
||||||
|
ten = tensor_from_pytorch_or_tensorflow(frame)
|
||||||
|
return ten
|
||||||
|
|
||||||
|
t = wp.VideoHandlerThread(video_source=cam, callbacks=[tensor_from_image] + wp.display_callbacks)
|
||||||
|
|
||||||
|
t.display()
|
||||||
|
|
||||||
#### Display multiple windows from one source
|
#### Display multiple windows from one source
|
||||||
import cvpubsubs.webcam_pub as w
|
import cvpubsubs.webcam_pub as w
|
||||||
from cvpubsubs.window_sub import SubscriberWindows
|
from cvpubsubs.window_sub import SubscriberWindows
|
||||||
|
@ -28,7 +28,7 @@ class SubscriberWindows(object):
|
|||||||
if isinstance(name, np.ndarray):
|
if isinstance(name, np.ndarray):
|
||||||
self.source_names.append(str(hash(str(name))))
|
self.source_names.append(str(hash(str(name))))
|
||||||
self.input_vid_global_names = [str(hash(str(name))) + "frame" for name in video_sources]
|
self.input_vid_global_names = [str(hash(str(name))) + "frame" for name in video_sources]
|
||||||
elif len(str(name))<=1000:
|
elif len(str(name)) <= 1000:
|
||||||
self.source_names.append(str(name))
|
self.source_names.append(str(name))
|
||||||
self.input_vid_global_names = [str(name) + "frame" for name in video_sources]
|
self.input_vid_global_names = [str(name) + "frame" for name in video_sources]
|
||||||
else:
|
else:
|
||||||
@ -37,7 +37,6 @@ class SubscriberWindows(object):
|
|||||||
self.callbacks = callbacks
|
self.callbacks = callbacks
|
||||||
self.input_cams = video_sources
|
self.input_cams = video_sources
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_global_frame_dict(name, *args):
|
def set_global_frame_dict(name, *args):
|
||||||
if len(str(name)) <= 1000:
|
if len(str(name)) <= 1000:
|
||||||
@ -47,7 +46,6 @@ class SubscriberWindows(object):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("Input window name too long.")
|
raise ValueError("Input window name too long.")
|
||||||
|
|
||||||
|
|
||||||
def __stop_all_cams(self):
|
def __stop_all_cams(self):
|
||||||
for c in self.source_names:
|
for c in self.source_names:
|
||||||
CamCtrl.stop_cam(c)
|
CamCtrl.stop_cam(c)
|
||||||
@ -69,20 +67,27 @@ class SubscriberWindows(object):
|
|||||||
RuntimeWarning("Unknown key code: [{}]. Please report to cv_pubsubs issue page.".format(key_input))
|
RuntimeWarning("Unknown key code: [{}]. Please report to cv_pubsubs issue page.".format(key_input))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _display_frames(self, frames, win_num):
|
||||||
|
for f in range(len(frames)):
|
||||||
|
if frames[f].dtype.num == 17 or len(frames[f].shape) > 3: # detect nested
|
||||||
|
self._display_frames(frames[f], win_num)
|
||||||
|
else:
|
||||||
|
cv2.imshow(self.window_names[win_num % len(self.window_names)] + " (press ESC to quit)", frames[f])
|
||||||
|
win_num += 1
|
||||||
|
|
||||||
def update_window_frames(self):
|
def update_window_frames(self):
|
||||||
win_num = 0
|
win_num = 0
|
||||||
for i in range(len(self.input_vid_global_names)):
|
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[
|
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.input_vid_global_names[i]],
|
||||||
if len(self.callbacks)>0 and self.callbacks[i % len(self.callbacks)] is not None:
|
NoData):
|
||||||
|
if len(self.callbacks) > 0 and self.callbacks[i % len(self.callbacks)] is not None:
|
||||||
frames = self.callbacks[i % len(self.callbacks)](self.frame_dict[self.input_vid_global_names[i]])
|
frames = self.callbacks[i % len(self.callbacks)](self.frame_dict[self.input_vid_global_names[i]])
|
||||||
else:
|
else:
|
||||||
frames = self.frame_dict[self.input_vid_global_names[i]]
|
frames = self.frame_dict[self.input_vid_global_names[i]]
|
||||||
if isinstance(frames, np.ndarray) and len(frames.shape)<=3:
|
if isinstance(frames, np.ndarray) and len(frames.shape) <= 3:
|
||||||
frames = [frames]
|
frames = [frames]
|
||||||
for f in range(len(frames)):
|
self._display_frames(frames, win_num)
|
||||||
cv2.imshow(self.window_names[win_num % len(self.window_names)] + " (press ESC to quit)", frames[f])
|
|
||||||
win_num += 1
|
|
||||||
|
|
||||||
# todo: figure out how to get the red x button to work. Try: https://stackoverflow.com/a/37881722/782170
|
# todo: figure out how to get the red x button to work. Try: https://stackoverflow.com/a/37881722/782170
|
||||||
def loop(self):
|
def loop(self):
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
opencv_python==4.0.0.21
|
opencv_python==3.4.5.20
|
||||||
localpubsub==0.0.3
|
localpubsub==0.0.3
|
||||||
numpy==1.16.1
|
numpy==1.16.1
|
2
setup.py
2
setup.py
@ -14,7 +14,7 @@ with open('README.md', 'r', encoding='utf-8') as f:
|
|||||||
readme = f.read()
|
readme = f.read()
|
||||||
|
|
||||||
REQUIRES = [
|
REQUIRES = [
|
||||||
'opencv_python == 4.0.0.21',
|
'opencv_python == 3.4.5.20',
|
||||||
'localpubsub == 0.0.3',
|
'localpubsub == 0.0.3',
|
||||||
'numpy == 1.16.1'
|
'numpy == 1.16.1'
|
||||||
]
|
]
|
||||||
|
@ -89,3 +89,10 @@ class TestSubWin(ut.TestCase):
|
|||||||
|
|
||||||
t1.join()
|
t1.join()
|
||||||
t1.join()
|
t1.join()
|
||||||
|
|
||||||
|
def test_nested_frames(self):
|
||||||
|
def nest_frame(frame, cam_id):
|
||||||
|
frame = np.asarray([[[[[[frame]]]]]])
|
||||||
|
return frame
|
||||||
|
|
||||||
|
w.VideoHandlerThread(callbacks=[nest_frame] + w.display_callbacks).display()
|
Reference in New Issue
Block a user