有没有一个终端命令可以列出连接到我的计算机的所有网络摄像头(包括本机摄像头)?也许使用包ffmpeg
?
答案1
v4l2-ctl --list-devices
sudo apt install v4l-utils
v4l2-ctl --list-devices
使用单个摄像机的样本输出:
Integrated Camera (usb-0000:00:1a.0-1.6):
/dev/video0
在 Ubuntu 16.04、联想 ThinkPad P51 上测试。
video1
元数据设备
然而,在 Ubuntu 19.10 Lenovo Thinkpad P51 上,它列出了两个这样的设备,video0
和video1
,但我只有一个摄像头,只能看到来自 的图像video0
。ffplay
这个问题已在以下位置提出:
- 有四个 /dev/video 条目但只有一个摄像头
- https://unix.stackexchange.com/questions/512759/multiple-dev-video-for-one-physical-device
所发生的情况是,它/dev/video1
仅包含某种视频元数据,而不包含图像,如下所示:
sudo v4l2-ctl --device=/dev/video0 --all
sudo v4l2-ctl --device=/dev/video1 --all
分别显示:
Device Caps : 0x04200001
Video Capture
Device Caps : 0x04a00000
Metadata Capture
如何实时查看摄像机图像
- https://unix.stackexchange.com/questions/3304/how-do-i-watch-my-webcams-feed-in-linux
- 有哪些可用的网络摄像头应用程序以及如何检查您的网络摄像头是否正常工作?
我最喜欢的:
sudo apt install ffmpeg
ffplay /dev/video0
另一个不错的功能是只显示相机而不显示其他内容:
sudo apt-get install guvcview
guvcview
从命令行拍摄单张照片
ffmpeg -f v4l2 -video_size 1280x720 -i /dev/video0 -frames 1 out.jpg
从命令行录制视频
根据以下“如何获取分辨率等相机参数”选择的参数:
ffmpeg -f v4l2 -framerate 30 -video_size 1280x720 -input_format mjpeg \
-i /dev/video0 -c copy out.mkv
然后:
ffprobe out.mkv
包含预期内容:
流#0:0:视频:mjpeg(基线)、yuvj422p(pc、bt470bg/unknown/unknown)、1280x720、30 fps、30 tbr、1k tbn、1k tbc(默认)
如果参数选择错误,分辨率可能会很低。相机已经输出特定的编码格式,最简单的录制方式就是复制该格式,如上所示:
- https://stackoverflow.com/questions/47292785/recording-from-webcam-using-ffmpeg-at-high-framerate
- https://superuser.com/questions/1021899/what-ffmpeg-settings-to-get-the-best-possible-video-resolution-framerate-that-my
TODO 如果我替换-c copy out.mkv
为out.ogv
尝试直接记录为开放格式(与 MJPEG 不同),我会得到低分辨率的视频。
带预览的交互式图像/视频捕捉
对于极简主义者来说,这将打开一个带有 的“预览窗口” ffplay
,关闭该窗口后,其中out.mkv
包含录制的视频:
ffmpeg -f v4l2 -framerate 30 -video_size 1280x720 -input_format mjpeg \
-i /dev/video0 -c copy -f matroska - |
tee out.mkv |
ffplay -
对于非极简主义者来说,Cheese 是一个简单而优秀的 GUI 程序:
sudo apt install cheese
从 Ubuntu 23.10 开始,音频和视频大约有 0.5 秒不同步,这显然很烦人。另一个克服偏移的程序是名字奇怪的程序guvcview
:
sudo apt-get install guvcview
guvcview
这个似乎还有更多的配置选项,但使用起来仍然相当简单。
使用 FFmpeg 从命令行录制视频和麦克风音频
https://stackoverflow.com/questions/19828236/how-to-record-audio-with-ffmpeg-on-linux我获得了视频和音频,但它们不同步。
从 C/C++ 读取相机数据
一个具体的 C++ 示例,使用 OpenGL 在 GPU 上处理来自摄像头的图像并实时显示:https://stackoverflow.com/questions/13693946/image-processing-with-glsl-shaders/40641014#40641014
如何获取相机分辨率等参数
- 如何才能找到所支持的网络摄像头分辨率?
- https://superuser.com/questions/639738/how-can-i-list-the-available-video-modes-for-a-usb-webcam-in-linux
v4l2-ctl --list-formats-ext
产生一些有用的信息:
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 320x180
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 424x240
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 640x360
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 848x480
Interval: Discrete 0.050s (20.000 fps)
Size: Discrete 960x540
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 320x180
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 424x240
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 640x360
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 848x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 960x540
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
此输出还表明,除了 MJPG 压缩输出外,网络摄像头还原生支持无损 YUYV,尽管在 FHD 上无法达到 30 fps。TODO 有没有办法查看视频当前输出的格式?
如何获取相应的ffmpeg编码
v4l2-ctl --list-formats-ext
给出事物的 Linux 内核名称,例如 。YUYV 4:2:2
但要使用ffmpeg
,有时您需要知道 ffmpeg 名称。您可以这样做:
ffmpeg -f v4l2 -list_formats all -i /dev/video0
示例输出:
[video4linux2,v4l2 @ 0x555ba7267240] Raw : yuyv422 : YUYV 4:2:2 : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
[video4linux2,v4l2 @ 0x555ba7267240] Compressed: mjpeg : Motion-JPEG : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
例如,这告诉我们 ffmpeg 的名称YUYV 4:2:2
是yuyv422
。
此刻只想找点乐子
python -m pip install -U yolov5==7.0.9
yolov5 detect --source 0
在 Ubuntu 22.10、联想 ThinkPad P51 上进行了测试。为了适应 2 MB 的最大 Stack Exchange 图像大小,此处上传了极低的 GIF 分辨率,原始图像位于:https://www.youtube.com/watch?v=1MD3Wn7e6OE表明它可以处理我的实际相机分辨率。
video2
红外线装置
当我在装有 Ubuntu 23.10 的较新的 Lenovo ThinkPad P14s 上重新运行此答案的部分内容时,我注意到现在我有一个video2
并且video3
这引起了我的兴趣。video3
是 的元数据,video2
就像video1
是 的元数据video0
。 但这神秘的是什么video2
? 与我的主摄像头相比:
diff -u <( sudo v4l2-ctl --device=/dev/video0 --all ) \
<( sudo v4l2-ctl --device=/dev/video2 --all )
我看到它是一种低分辨率灰度相机:
- Width/Height : 1280/720
- Pixel Format : 'MJPG' (Motion-JPEG)
+ Width/Height : 640/360
+ Pixel Format : 'GREY' (8-bit Greyscale)
谷歌搜索显示它是红外线,我完全不知道我有红外线!显然,它的用例是面部识别来解锁设备,这样别人就更难仅凭你的面部视频来解锁设备,特别是“Windows Hello”使用的就是这个。
ffmpeg -f v4l2 -list_formats all -i /dev/video2
给了:
[video4linux2,v4l2 @ 0x5e00d8e51ac0] Raw : gray : 8-bit Greyscale : 640x360
因此我录制了一段视频:
ffmpeg -y -f v4l2 -framerate 30 -video_size 640x360 -input_format gray \
-i /dev/video2 -c copy out.mkv
TODO 帧速率实际上是 30 吗?
当此设备上使用该摄像头时,红色 LED 会亮起,而普通摄像头使用时则会亮起白色 LED。
答案2
列出内核获取的所有视频设备
ls -ltrh /dev/video*
要列出所有连接到 USB 的设备,请使用:lsusb
;要列出所有连接到 PCI 的设备,请使用:lspci
答案3
对于 Windows,您可以使用 pygrabber 库:https://github.com/bunkahle/pygrabber
要检查已连接网络摄像头的用户友好名称:
from __future__ import print_function
from pygrabber.dshow_graph import FilterGraph
graph = FilterGraph()
print(graph.get_input_devices())