如何在 LXC 容器中使用 OpenCV (Python) 访问网络摄像头
How to access webcam using OpenCV (Python) in LXC container
我在主机上 运行ning Ubuntu 18.04 和 LXC 容器内的 Ubuntu 20.04。我的目标是 运行 ROS2(需要 Ubuntu 20.04)在一个 LXC 容器中,然后用它连接到两个 dynamixel 伺服电机和一个 USB Logitech 网络摄像头。我还在容器内安装了 miniconda,这样我就可以安装 OpenCV 和 dlib。我也在容器内使用conda虚拟环境。
所有提到的软件都可以正常工作。现在我需要用 OpenCV 访问网络摄像头,我使用这个命令进行测试
python -c "import cv2;print(cv2.VideoCapture(0).isOpened())"
主机上 returns True
但 returns
[ WARN:0] global ../modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
False
从容器内部。
到目前为止我试过:
lxc config device add rosfoxy video0 unix-char path=/dev/video0
与 video0
, video1
和 video2
仍然得到相同的错误。
lxc config device add rosfoxy logitech usb vendorid=046d productid=082b
结果
Device logitech added to rosfoxy
,但仍然是同样的错误。
- 然后我尝试了
lxc profile device add ros logitech usb vendorid=046d productid=082b
结果
Device logitech added to ros
。测试时出现同样的错误。
- 在主机上测试了
glxgears
和 glxinfo
,都工作正常。但是,当从 LXC 容器内部测试它们时,它工作正常但首先出现此错误:
libGL error: MESA-LOADER: failed to retrieve device information
libGL error: Version 4 or later of flush extension not found
libGL error: failed to load driver: i915
libGL error: failed to open /dev/dri/card0: No such file or directory
libGL error: failed to load driver: i965
3073 frames in 5.0 seconds = 614.256 FPS
5238 frames in 5.0 seconds = 1047.546 FPS
3766 frames in 5.0 seconds = 753.186 FPS
4214 frames in 5.0 seconds = 842.731 FPS
4926 frames in 5.0 seconds = 985.092 FPS
6007 frames in 5.0 seconds = 1201.399 FPS
5694 frames in 5.0 seconds = 1138.660 FPS
- 在主机上测试
guvcview
,工作正常。但是在容器上,它不起作用,它给出:
V4L2_CORE: ERROR opening V4L2 interface for /dev/video2
V4L2_CORE: ERROR opening V4L2 interface for /dev/video3
V4L2_CORE: ERROR opening V4L2 interface for /dev/video0
V4L2_CORE: ERROR opening V4L2 interface for /dev/video1
GUVCVIEW: version 2.0.6
GUVCVIEW: couldn't open /home/ubuntu//.config/guvcview2/video0 for read: No such file or directory
V4L2_CORE: ERROR opening V4L interface: Permission denied
GUVCVIEW (1): Guvcview error
no video device found
(guvcview:1526): dbind-WARNING **: 19:29:55.201: Couldn't connect to accessibility bus: Failed to connect to socket /tmp/dbus-EhmzLUeJ8h: Connection refused
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:17: not a number
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:31: Using Pango syntax for the font: style property is deprecated; please use CSS syntax
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:17: not a number
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:32: Using Pango syntax for the font: style property is deprecated; please use CSS syntax
你会建议怎么做吗?
更新 1:
试过 lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
但似乎不起作用。
我从容器里面试过了
(base) ubuntu@rosfoxy:~$ v4l2-ctl --all
Failed to open /dev/video0: Permission denied
但是当我添加 sudo
我得到:
(base) ubuntu@rosfoxy:~$ sudo v4l2-ctl --all
Driver Info:
Driver name : uvcvideo
Card type : Webcam C170: Webcam C170
Bus info : usb-0000:00:14.0-1
Driver version : 5.4.86
Capabilities : 0x84a00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
...
在我看来,网络摄像头被检测到!
但我还是得到了
(py38) ubuntu@rosfoxy:~$ python -c "import cv2;print(cv2.VideoCapture(0).isOpened())"
[ WARN:0] global ../modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
False
更新 2:
我应该先发出 lxc config device remove rosfoxy video0
然后 lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
感谢 Simos https://discuss.linuxcontainers.org/t/cant-open-camera-by-index-on-lxc-container/10452/8
当您 运行 命令 lxc config device add rosfoxy video0 unix-char path=/dev/video0
时,会在容器中创建一个具有默认所有者和组的设备。这些是 root/root
。在主机上,此设备的组是 video
但在容器中没有将非根用户添加到此组的设置。
因此,将命令修改为以下内容。 ubuntu:*
容器映像中的非根帐户具有组 ID 1000。
lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
USB设备问题应该有类似的解决方法。有关文档,请参阅 https://linuxcontainers.org/lxd/docs/master/instances#type-usb。您可能需要明确设置 uid
或 gid
.
如果要修改添加的LXD设备,需要先将其删除,然后使用新参数重新添加。你可以像下面那样做。
lxc config device remove rosfoxy video0
lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
请注意,gid=1000
指定容器中非根用户的组 ID。如果您使用不同类型的容器映像(Ubuntu 除外),您可能需要更改此值。如果您在容器中 运行 id
命令,您可以在容器中找到您的非根帐户的组 ID。
这两个命令就是我的问题的答案:
第一个lxc config device remove rosfoxy video0
然后 lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
感谢 Simos https://discuss.linuxcontainers.org/t/cant-open-camera-by-index-on-lxc-container/10452/8
我在主机上 运行ning Ubuntu 18.04 和 LXC 容器内的 Ubuntu 20.04。我的目标是 运行 ROS2(需要 Ubuntu 20.04)在一个 LXC 容器中,然后用它连接到两个 dynamixel 伺服电机和一个 USB Logitech 网络摄像头。我还在容器内安装了 miniconda,这样我就可以安装 OpenCV 和 dlib。我也在容器内使用conda虚拟环境。
所有提到的软件都可以正常工作。现在我需要用 OpenCV 访问网络摄像头,我使用这个命令进行测试
python -c "import cv2;print(cv2.VideoCapture(0).isOpened())"
主机上 returns True
但 returns
[ WARN:0] global ../modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
False
从容器内部。
到目前为止我试过:
lxc config device add rosfoxy video0 unix-char path=/dev/video0
与video0
,video1
和video2
仍然得到相同的错误。lxc config device add rosfoxy logitech usb vendorid=046d productid=082b
结果Device logitech added to rosfoxy
,但仍然是同样的错误。- 然后我尝试了
lxc profile device add ros logitech usb vendorid=046d productid=082b
结果Device logitech added to ros
。测试时出现同样的错误。 - 在主机上测试了
glxgears
和glxinfo
,都工作正常。但是,当从 LXC 容器内部测试它们时,它工作正常但首先出现此错误:
libGL error: MESA-LOADER: failed to retrieve device information
libGL error: Version 4 or later of flush extension not found
libGL error: failed to load driver: i915
libGL error: failed to open /dev/dri/card0: No such file or directory
libGL error: failed to load driver: i965
3073 frames in 5.0 seconds = 614.256 FPS
5238 frames in 5.0 seconds = 1047.546 FPS
3766 frames in 5.0 seconds = 753.186 FPS
4214 frames in 5.0 seconds = 842.731 FPS
4926 frames in 5.0 seconds = 985.092 FPS
6007 frames in 5.0 seconds = 1201.399 FPS
5694 frames in 5.0 seconds = 1138.660 FPS
- 在主机上测试
guvcview
,工作正常。但是在容器上,它不起作用,它给出:
V4L2_CORE: ERROR opening V4L2 interface for /dev/video2
V4L2_CORE: ERROR opening V4L2 interface for /dev/video3
V4L2_CORE: ERROR opening V4L2 interface for /dev/video0
V4L2_CORE: ERROR opening V4L2 interface for /dev/video1
GUVCVIEW: version 2.0.6
GUVCVIEW: couldn't open /home/ubuntu//.config/guvcview2/video0 for read: No such file or directory
V4L2_CORE: ERROR opening V4L interface: Permission denied
GUVCVIEW (1): Guvcview error
no video device found
(guvcview:1526): dbind-WARNING **: 19:29:55.201: Couldn't connect to accessibility bus: Failed to connect to socket /tmp/dbus-EhmzLUeJ8h: Connection refused
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:17: not a number
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:31: Using Pango syntax for the font: style property is deprecated; please use CSS syntax
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:17: not a number
(guvcview:1526): Gtk-WARNING **: 19:29:55.307: Theme parsing error: <data>:1:32: Using Pango syntax for the font: style property is deprecated; please use CSS syntax
你会建议怎么做吗?
更新 1:
试过 lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
但似乎不起作用。
我从容器里面试过了
(base) ubuntu@rosfoxy:~$ v4l2-ctl --all
Failed to open /dev/video0: Permission denied
但是当我添加 sudo
我得到:
(base) ubuntu@rosfoxy:~$ sudo v4l2-ctl --all
Driver Info:
Driver name : uvcvideo
Card type : Webcam C170: Webcam C170
Bus info : usb-0000:00:14.0-1
Driver version : 5.4.86
Capabilities : 0x84a00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
...
在我看来,网络摄像头被检测到!
但我还是得到了
(py38) ubuntu@rosfoxy:~$ python -c "import cv2;print(cv2.VideoCapture(0).isOpened())"
[ WARN:0] global ../modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
False
更新 2:
我应该先发出 lxc config device remove rosfoxy video0
然后 lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
感谢 Simos https://discuss.linuxcontainers.org/t/cant-open-camera-by-index-on-lxc-container/10452/8
当您 运行 命令 lxc config device add rosfoxy video0 unix-char path=/dev/video0
时,会在容器中创建一个具有默认所有者和组的设备。这些是 root/root
。在主机上,此设备的组是 video
但在容器中没有将非根用户添加到此组的设置。
因此,将命令修改为以下内容。 ubuntu:*
容器映像中的非根帐户具有组 ID 1000。
lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
USB设备问题应该有类似的解决方法。有关文档,请参阅 https://linuxcontainers.org/lxd/docs/master/instances#type-usb。您可能需要明确设置 uid
或 gid
.
如果要修改添加的LXD设备,需要先将其删除,然后使用新参数重新添加。你可以像下面那样做。
lxc config device remove rosfoxy video0
lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
请注意,gid=1000
指定容器中非根用户的组 ID。如果您使用不同类型的容器映像(Ubuntu 除外),您可能需要更改此值。如果您在容器中 运行 id
命令,您可以在容器中找到您的非根帐户的组 ID。
这两个命令就是我的问题的答案:
第一个lxc config device remove rosfoxy video0
然后 lxc config device add rosfoxy video0 unix-char path=/dev/video0 gid=1000
感谢 Simos https://discuss.linuxcontainers.org/t/cant-open-camera-by-index-on-lxc-container/10452/8