Merge pull request #43 from SimLeek/same_cam
One camera can now be accessed by two seperate pieces of code. Update…
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__ = "1.0.0"
|
||||
__version__ = "1.1.0"
|
||||
|
||||
from .window.subscriber_windows import display, breakpoint_display, read_updates
|
||||
from .frame.frame_publishing import publish_updates_zero_mq, publish_updates_ros
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
"""Publish frames so any function within this program can find them."""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import asyncio
|
||||
import cv2
|
||||
import warnings
|
||||
import sys
|
||||
|
||||
import cv2
|
||||
|
||||
using_pyv4l2cam = False
|
||||
try:
|
||||
@@ -123,6 +124,7 @@ def pub_cam_loop_opencv(
|
||||
request_size: Tuple[int, int] = (-1, -1),
|
||||
high_speed: bool = True,
|
||||
fps_limit: float = float("inf"),
|
||||
extra: Optional[List[Tuple[int, int]]] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Publish whichever camera you select to CVCams.<cam_id>.Vid.
|
||||
@@ -186,6 +188,9 @@ def pub_cam_loop_opencv(
|
||||
return True
|
||||
|
||||
|
||||
uid_dict: Dict[str, threading.Thread] = {}
|
||||
|
||||
|
||||
def pub_cam_thread(
|
||||
cam_id: Union[int, str],
|
||||
request_ize: Tuple[int, int] = (-1, -1),
|
||||
@@ -194,22 +199,27 @@ def pub_cam_thread(
|
||||
) -> threading.Thread:
|
||||
"""Run pub_cam_loop in a new thread. Starts on creation."""
|
||||
|
||||
if (
|
||||
sys.platform == "linux"
|
||||
and using_pyv4l2cam
|
||||
and (
|
||||
isinstance(cam_id, int)
|
||||
or (isinstance(cam_id, str) and "/dev/video" in cam_id)
|
||||
)
|
||||
):
|
||||
pub_cam_loop = pub_cam_loop_pyv4l2
|
||||
name = uid_for_source(cam_id)
|
||||
if name in uid_dict.keys():
|
||||
t = uid_dict[name]
|
||||
else:
|
||||
pub_cam_loop = pub_cam_loop_opencv
|
||||
if (
|
||||
sys.platform == "linux"
|
||||
and using_pyv4l2cam
|
||||
and (
|
||||
isinstance(cam_id, int)
|
||||
or (isinstance(cam_id, str) and "/dev/video" in cam_id)
|
||||
)
|
||||
):
|
||||
pub_cam_loop = pub_cam_loop_pyv4l2
|
||||
else:
|
||||
pub_cam_loop = pub_cam_loop_opencv
|
||||
|
||||
t = threading.Thread(
|
||||
target=pub_cam_loop, args=(cam_id, request_ize, high_speed, fps_limit)
|
||||
)
|
||||
t.start()
|
||||
t = threading.Thread(
|
||||
target=pub_cam_loop, args=(cam_id, request_ize, high_speed, fps_limit)
|
||||
)
|
||||
uid_dict[name] = t
|
||||
t.start()
|
||||
return t
|
||||
|
||||
|
||||
|
||||
@@ -91,14 +91,18 @@ class FrameUpdater(threading.Thread):
|
||||
sub_cam = subscriber_dictionary.cam_frame_sub(str(self.cam_id))
|
||||
sub_owner = subscriber_dictionary.handler_cmd_sub(str(self.cam_id))
|
||||
msg_owner = sub_owner.return_on_no_data = ""
|
||||
while msg_owner != "quit":
|
||||
frame = sub_cam.get(blocking=True, timeout=1.0) # type: np.ndarray
|
||||
self.__apply_callbacks_to_frame(frame)
|
||||
msg_owner = sub_owner.get()
|
||||
sub_owner.release()
|
||||
sub_cam.release()
|
||||
subscriber_dictionary.stop_cam(self.cam_id)
|
||||
t.join()
|
||||
try:
|
||||
while msg_owner != "quit":
|
||||
frame = sub_cam.get(blocking=True, timeout=1.0) # type: np.ndarray
|
||||
self.__apply_callbacks_to_frame(frame)
|
||||
msg_owner = sub_owner.get()
|
||||
except Exception as e:
|
||||
raise e
|
||||
finally:
|
||||
sub_owner.release()
|
||||
sub_cam.release()
|
||||
subscriber_dictionary.stop_cam(self.cam_id)
|
||||
t.join()
|
||||
|
||||
def display(self, callbacks: List[Callable[[np.ndarray], Any]] = None):
|
||||
"""
|
||||
|
||||
@@ -211,7 +211,6 @@ class SubscriberWindows(object):
|
||||
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()
|
||||
if not self.silent:
|
||||
self.display_frames(self.frames)
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
from displayarray import read_updates
|
||||
|
||||
with read_updates(0) as a, read_updates(0) as b:
|
||||
for i in range(1000):
|
||||
a.update()
|
||||
b.update()
|
||||
try:
|
||||
print(a.frames == b.frames)
|
||||
except ValueError:
|
||||
print(f"frame comparison: {(a.frames['0'][0] == b.frames['0'][0]).all()}")
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = 'displayarray'
|
||||
version = '1.0.0'
|
||||
version = '1.1.0'
|
||||
description = 'Tool for displaying numpy arrays.'
|
||||
authors = ['SimLeek <simulator.leek@gmail.com>']
|
||||
license = 'MIT'
|
||||
|
||||
@@ -75,7 +75,7 @@ def test_callback_exception():
|
||||
frame[:, :, 2] = 1 / 0
|
||||
|
||||
with pytest.raises(ZeroDivisionError) as e:
|
||||
v = fup.FrameUpdater(np.zeros((1, 1, 3)), callbacks=redden_frame_print_spam)
|
||||
v = fup.FrameUpdater(np.zeros((1, 2, 3)), callbacks=redden_frame_print_spam)
|
||||
v.loop()
|
||||
assert e.errisinstance(ZeroDivisionError)
|
||||
|
||||
@@ -92,8 +92,6 @@ def test_display():
|
||||
|
||||
mock_sub_win.assert_called_once_with(video_sources=["0"], callbacks=[])
|
||||
mock_sub_win_instance.loop.assert_called_once()
|
||||
f.start.assert_called_once()
|
||||
f.join.assert_called_once()
|
||||
|
||||
|
||||
def test_display_exception():
|
||||
@@ -109,6 +107,7 @@ def test_display_exception():
|
||||
v = fup.FrameUpdater(np.zeros((1, 1, 3)), callbacks=redden_frame_print_spam)
|
||||
v.display()
|
||||
assert e.errisinstance(ZeroDivisionError)
|
||||
# todo: clear the frame dict so that these don't hang forever
|
||||
|
||||
|
||||
from displayarray.window.window_commands import win_cmd_pub
|
||||
|
||||
Reference in New Issue
Block a user