相机

本文档介绍如何使用我们的软件工具支持的相机模块,所有树莓派相机可以录制高分辨率照片和HD 1080p视频(或更好)以及软件工具。

Raspberry Pi生产多种官方相机模块,包括:

  • 原装500万像素相机模块1(停产)

  • 800万像素 相机模块2,带或不带红外滤光片

  • 一千两百万像素 相机模块3,配有标准和广角镜头,带或不带红外滤光片

  • 一千两百万像素 高品质相机,带有CS和M12卡口变体,可用于外部镜头

  • 用于快速运动摄影的160万像素 全局快门相机

  • 1200万像素的https://www.raspberrypi.com/products/ai-camera/[AI相机]使用索尼IMX500成像传感器,为任何相机应用提供低延迟、高性能的AI功能

有关相机硬件的更多信息,请参阅 相机硬件文档

首先,安装您的相机模块。然后,按照本节中的指南将您的相机模块投入使用。

rpicam-apps

Note

树莓派操作系统 Bookworm 将相机捕捉应用程序从 libcamera-\* 重命名为 rpicam-* 。符号链接允许用户暂时使用旧名称。尽快采用新的应用程序名称。 Bookworm 之前的树莓派操作系统版本仍然使用 libcamera-* 名称。

Raspberry Pi提供了一组示例 rpicam-apps 。这些CLI应用程序建立在 libcamera 之上,可从相机捕获图像和视频。这些应用程序包括:

  • rpicam-hello :一个 hello world -相当于相机,它启动相机预览流并将其显示在屏幕上。

  • rpicam-jpeg :运行预览窗口,然后捕获高分辨率静止图像。

  • rpicam-still :模拟原始 raspistil 应用程序的许多功能。

  • rpicam-vid :捕获视频。

  • rpicam-raw :直接从传感器捕获原始(未处理的Bayer)帧。

  • rpicam-detect :默认情况下未构建,但如果用户在其Raspberry Pi上安装了TensorFlow Lite,则可以构建它。检测到特定物体时捕获 JPEG 图像。

最新版本的Raspberry Pi OS包括五个基本的 rpicam-apps ,因此即使在全新的Raspberry Pi OS安装上,您也可以使用相机录制图像和视频。

用户可以根据自己的要求创建具有自定义功能的基于 rpicam 的应用程序。 rpicam-apps 源代码 在BSD-2-Clause许可下免费提供。

libcamera

libcamera 是一个开源软件库,旨在直接支持Arm处理器上Linux操作系统的相机系统。在 Broadcom GPU 上运行的专有代码被减至最少。有关 libcamera 的更多信息,请参阅 libcamera 网站

libcamera 提供了一个C++API来配置相机,然后允许应用程序请求图像帧。这些图像缓冲区驻留在系统内存中,可以直接传递给静止图像编码器(如JPEG)或视频编码器(如h.264)。 libcamera 本身不编码或显示图像:该功能使用 rpicam-apps

您可以在 官方libcam存储库中找到源代码。Raspberry Pi OS发行版使用 fork 来控制更新。

libcamera 内核之下,我们提供了一个自定义流水线处理程序。libcamera "使用该层驱动 Raspberry Pi 上的传感器和图像信号处理器(ISP)。libcamera "包含一系列图像处理算法(IPA),包括自动曝光/增益控制(AEC/AGC)、自动白平衡(AWB)和自动镜头阴影校正(ALSC)。

Raspberry Pi的 libcamera 实现支持以下相机:

  • 官方相机:

    • OV5647 (V1)

    • IMX219 (V2)

    • IMX708 (V3)

    • IMX477 (HQ)

    • IMX296 (GS)

    • IMX500 (AI)

    • IMX708 (V3)

  • 第三方传感器:

    • IMX290

    • IMX327

    • IMX378

    • IMX519

    • OV9281

扩展对新传感器的支持,https://git.linuxtv.org/libcamera.git/[贡献给 libcamera ]。

rpicam-hello

rpicam-hello 简要显示包含来自连接相机的视频馈送的预览窗口。要使用 rpicam-hello 显示预览窗口五秒钟,请在终端中运行以下命令:

$ rpicam-hello

您可以使用 timeout 选项传递可选的持续时间(以毫秒为单位)。值 0 无限期运行预览:

$ rpicam-hello --timeout 0

使用终端中的 Ctrl+C 或预览窗口上的关闭按钮停止 rpicam-hello

显示图像预览

大多数 rpicam-apps 会在窗口中显示预览图像。如果没有活动的桌面环境,则使用Linux直接渲染管理器(DRM)将预览直接绘制到显示器上。否则, rpicam-apps 会尝试使用桌面环境。两条路径都使用零拷贝GPU缓冲区共享:因此,_不_支持X转发。

如果您运行X窗口服务器并希望使用X转发,请添加 qt-preview标志以在 Qt 窗口中呈现预览窗口。Qt预览窗口比替代窗口使用更多资源。

Note
使用Gtk2的旧系统在与OpenCV链接时可能会产生 Glib-GObject 错误并且无法显示Qt预览窗口。在这种情况下,以root身份编辑文件 /etc/xdg/qt5ct/qt5ct.conf 并将包含 style=gtk2 的行替换为 style=gtk3

要完全禁止预览窗口,请传递 nopreview 标志:

$ rpicam-hello -n

info-text 选项使用 % 指令在窗口标题栏上显示图像信息。例如,以下命令显示当前的红色和蓝色增益值:

$ rpicam-hello --info-text "red gain %rg, blue gain %bg"

有关指令的完整列表,请参阅 info-text 参考

rpicam-jpeg

rpicam-jpeg 可帮助您在Raspberry Pi设备上捕获图像。

要捕获全分辨率JPEG图像并将其保存到名为 test.jpg 的文件中,请运行以下命令:

$ rpicam-jpeg --output test.jpg

您应该会看到五秒钟的预览窗口。然后, rpicam-jpeg 捕获全分辨率JPEG图像并保存它。

使用 timeout 选项更改预览窗口的显示时间。 widthheight 选项更改保存图像的分辨率。例如,以下命令将预览窗口显示2秒,然后捕获并保存分辨率为640×480像素的图像:

$ rpicam-jpeg --output test.jpg --timeout 2000 --width 640 --height 480

rpicam-still

rpicam-stillrpicam-jpeg 一样,可以帮助你在 Raspberry Pi 设备上捕捉图像。 与 rpicam-jpeg 不同, rpicam-still 支持传统 raspistill 应用程序中提供的许多选项。

要捕获全分辨率JPEG图像并将其保存到名为 test.jpg 的文件中,请运行以下命令:

$ rpicam-still --output test.jpg

编码器

rpicam-still 可以以多种格式保存图像,包括 pngbmp 以及RGB和YUV二进制像素转储。要读取这些二进制转储,任何读取文件的应用程序都必须了解像素排列。

使用 encoding 选项指定输出格式。传递给 output 的文件名对输出文件类型没有影响。

要捕获全分辨率PNG图像并将其保存到名为 test.png 的文件中,请运行以下命令:

$ rpicam-still --encoding png --output test.png

有关指定图像格式的更多信息,请参阅 encoding 选项参考

捕获原始图像

原始图像是由图像传感器直接生成的图像,然后再由图像信号处理器(ISP)或中央处理器进行处理。彩色图像传感器通常使用 Bayer 格式。使用 raw 选项可捕捉原始图像。

要捕获图像,请将其保存到名为 test.jpg 的文件中,并将图像的原始版本保存到名为 test.dng 的文件中,请运行以下命令:

$ rpicam-still --raw --output test.jpg

rpicam-still 以DNG(Adobe Digital Negative)格式保存原始图像。要确定原始图像的文件名, rpicam-still 使用与输出文件相同的名称,扩展名更改为 .dng 。要处理DNG图像,请使用 DcrawRawTherapee 等应用程序。

DNG元数据包括电平、白平衡信息以及ISP用于生成JPEG的色彩矩阵。使用 ExifTool 查看 DNG 元数据。以下输出显示了存储在 Raspberry Pi 使用 HQ 摄像机拍摄的原始图像中的典型元数据:

File Name                       : test.dng
Directory                       : .
File Size                       : 24 MB
File Modification Date/Time     : 2021:08:17 16:36:18+01:00
File Access Date/Time           : 2021:08:17 16:36:18+01:00
File Inode Change Date/Time     : 2021:08:17 16:36:18+01:00
File Permissions                : rw-r--r--
File Type                       : DNG
File Type Extension             : dng
MIME Type                       : image/x-adobe-dng
Exif Byte Order                 : Little-endian (Intel, II)
Make                            : Raspberry Pi
Camera Model Name               : /base/soc/i2c0mux/i2c@1/imx477@1a
Orientation                     : Horizontal (normal)
Software                        : rpicam-still
Subfile Type                    : Full-resolution Image
Image Width                     : 4056
Image Height                    : 3040
Bits Per Sample                 : 16
Compression                     : Uncompressed
Photometric Interpretation      : Color Filter Array
Samples Per Pixel               : 1
Planar Configuration            : Chunky
CFA Repeat Pattern Dim          : 2 2
CFA Pattern 2                   : 2 1 1 0
Black Level Repeat Dim          : 2 2
Black Level                     : 256 256 256 256
White Level                     : 4095
DNG Version                     : 1.1.0.0
DNG Backward Version            : 1.0.0.0
Unique Camera Model             : /base/soc/i2c0mux/i2c@1/imx477@1a
Color Matrix 1                  : 0.8545269369 -0.2382823821 -0.09044229197 -0.1890484985 1.063961506 0.1062747385 -0.01334283455 0.1440163847 0.2593136724
As Shot Neutral                 : 0.4754476844 1 0.413686484
Calibration Illuminant 1        : D65
Strip Offsets                   : 0
Strip Byte Counts               : 0
Exposure Time                   : 1/20
ISO                             : 400
CFA Pattern                     : [Blue,Green][Green,Red]
Image Size                      : 4056x3040
Megapixels                      : 12.3
Shutter Speed                   : 1/20

要找到模拟增益,请将ISO数除以100。 自动白平衡(AWB)算法确定一个单一的校准光源,该光源始终标为 "D65"。

捕捉长时间曝光

要拍摄长时间曝光的图像,请禁用自动曝光/增益控制 (AEC/AGC) 和自动白平衡 (AWB)。否则,这些算法将迫使用户在收敛时等待若干帧。

要禁用这些算法,请为增益和 AWB 提供明确的值。由于长时间曝光已经耗费了大量时间,使用 immediate 选项完全跳过预览阶段通常是合理的。

要执行100秒曝光捕获,请运行以下命令:

$ rpicam-still -o long_exposure.jpg --shutter 100000000 --gain 1 --awbgains 1,1 --immediate

要查找 Raspberry Pi 官方摄像头的最大曝光时间,请参阅 摄像头硬件规格

创建延时视频

要创建延时视频,请定期捕获静止图像,例如一分钟一次,然后使用应用程序将图片拼接成视频。

使用 rpicam-still 延时模式

要使用内置的延时模式 rpicam-still ,请使用 timelapse 选项。此选项接受一个值,该值表示您希望Raspberry Pi在两次捕获之间等待的时间,以毫秒为单位。

首先,创建一个目录,您可以在其中存储延时照片:

$ mkdir timelapse

运行以下命令创建 30 秒钟的延时,每两秒记录一张照片,将输出保存到 image0001.jpgimage0013.jpg 中:

$ rpicam-still --timeout 30000 --timelapse 2000 -o timelapse/image%04d.jpg
通过 cron

您还可以使用 cron 自动延时。首先,创建名为 timelapse.sh 的脚本,其中包含以下命令。将Raspberry Pi上的 <username> 占位符替换为您的用户帐户名称:

#!/bin/bash
DATE=$(date +"%Y-%m-%d_%H%M")
rpicam-still -o /home/<username>/timelapse/$DATE.jpg

然后,使脚本可执行:

$ chmod +x timelapse.sh

创建 timelapse 目录,您将在其中保存延时照片:

$ mkdir timelapse

打开您的crontab进行编辑:

$ crontab -e

在编辑器中打开文件后,添加以下行以安排每分钟捕获一次图像,将 <username> 占位符替换为您的主要用户帐户的用户名:

* * * * * /home/<username>/timelapse.sh 2>&1

保存并退出,您应该会看到以下消息:

crontab: installing new crontab
Tip
要停止为延时拍摄图像,请再次运行 crontab -e 并从crontab中删除上面的行。
将图像拼接在一起

一旦你有了一系列延时照片,你可能想把它们组合成一个视频。使用 ffmpeg 在树莓派上执行此操作。

首先,安装 ffmpeg

$ sudo apt install ffmpeg

从包含 timelapse 目录的目录运行以下命令,将JPEG文件转换为mp4视频:

$ ffmpeg -r 10 -f image2 -pattern_type glob -i 'timelapse/*.jpg' -s 1280x720 -vcodec libx264 timelapse.mp4

上面的命令使用以下参数:

  • -r 10 :将输出视频的帧率(Hz值)设置为每秒10帧

  • -f image2 :设置 ffmpeg 以从模式指定的图像文件列表中读取

  • -pattern_type glob :使用通配符模式来解释文件名输入

  • -i 'timelapse/*.jpg' :指定输入文件以匹配 timelapse 目录中的JPG文件

  • -s 1280x720 :缩放到720p

  • -vcodec libx264 使用软件x264编码器。

  • timelapse.mp4 输出视频文件的名称。

有关 ffmpeg 选项的更多信息,请在终端中运行 ffmpeg --help

rpicam-vid

rpicam-vid 可帮助您在 Raspberry Pi 设备上捕获视频。 rpicam-vid 显示预览窗口并将编码的比特流写入指定的输出。这会生成未打包的视频比特流,该比特流未包装在任何类型的容器(例如 mp4 文件)格式中。

Note
如果可用, rpicam-vid 使用硬件 H.264 编码。

例如,以下命令将十秒的视频写入名为’test.h264’的文件:

$ rpicam-vid -t 10s -o test.h264

您可以使用 VLC 和其他视频播放器播放生成的文件:

$ vlc test.h264

在 Raspberry Pi 5 上,您可以通过为输出文件指定’mp4’文件扩展名直接输出为 MP4 容器格式:

$ rpicam-vid -t 10s -o test.mp4

编码器

'rpicam-vid' 支持运动 JPEG 以及未压缩和未格式化的 YUV420:

$ rpicam-vid -t 10000 --codec mjpeg -o test.mjpeg
$ rpicam-vid -t 10000 --codec yuv420 -o test.data

codec 选项决定输出格式,而不是输出文件的扩展名。

segment 选项将输出文件分解为片段大小的块(以毫秒为单位)。通过指定非常短(1 毫秒)的片段,这可以方便地将运动 JPEG 流分解为单个 JPEG 文件。例如,以下命令将 1 毫秒的片段与输出文件名中的计数器组合起来,为每个片段生成一个新文件名:

$ rpicam-vid -t 10000 --codec mjpeg --segment 1 -o test%05d.jpeg

捕获高帧率视频

要最大限度地减少高帧率 (> 60fps) 视频的丢帧,请尝试以下配置调整:

  • 使用 --level 4.2H.264 目标级别 设置为 4.2。

  • 通过将 denoise 选项设置为 cdn_off 来禁用软件色彩降噪处理。

  • 使用 nopreview 禁用显示窗口以释放一些额外的 CPU 周期。

  • /boot/firmware/config.txt 中设置 force_turbo=1 以确保在视频捕获期间 CPU 时钟不会节流。有关更多信息,请参阅 force_turbo 文档

  • 使用 --width 1280 --height 720 或更低的值调整 ISP 输出分辨率以实现您的帧速率目标。

  • 在 Raspberry Pi 4 上,您可以通过在 /boot/firmware/config.txt 中添加 gpu_freq=550 或更高来超频 GPU 以提高性能。有关更多详细信息,请参阅 超频文档

以下命令演示了如何实现 1280×720 120fps 视频:

$ rpicam-vid --level 4.2 --framerate 120 --width 1280 --height 720 --save-pts timestamp.pts -o video.264 -t 10000 --denoise cdn_off -n

libavrpicam-vid 集成

rpicam-vid 可以使用 ffmpeg / libav 编解码器后端来编码音频和视频流。您可以将这些流保存到文件中,也可以通过网络传输它们。 libav 使用硬件 H.264 视频编码(如果存在)。

要启用 libav 后端,请将 libav 传递给 codec 选项:

$ rpicam-vid --codec libav --libav-format avi --libav-audio --output example.avi

rpicam-raw

rpicam-raw 直接从传感器将视频记录为原始Bayer帧。它不显示预览窗口。要将两秒钟的原始剪辑录制到名为 test.raw 的文件中,请运行以下命令:

$ rpicam-raw -t 2000 -o test.raw

rpicam-raw 输出完全没有格式信息的原始帧,直接一个接一个。应用程序将像素格式和图像尺寸打印到终端窗口,以帮助用户解释像素数据。

默认情况下, rpicam-raw 会将原始图像输出到一个可能非常大的文件中。使用 segment 选项将每个原始图像帧导入单独的文件,并使用 %05d directive 使每个图像帧的文件名独一无二:

$ rpicam-raw -t 2000 --segment 1 -o test%05d.raw

如果使用快速存储设备, rpicam-raw 能以 10fps 的速度将 18MB 的 1200 万像素 HQ 相机帧写入磁盘。rpicam-raw "无法将输出帧格式化为 DNG 文件;如需该功能,请使用 rpicam-still 。使用 framerate 选项时,速度应低于 10,以避免丢帧:

$ rpicam-raw -t 5000 --width 4056 --height 3040 -o test.raw --framerate 8

有关原始格式的更多信息,请参阅 mode 文档

rpicam-detect

Note
Raspberry Pi OS 不包含 rpicam-detect。不过,如果您安装了 已安装 TensorFlow Lite,则可以构建 rpicam-detect。有关详细信息,请参阅 rpicam-apps 构建说明。运行 meson 时不要忘记传递 Denable_tflite=enabled

rpicam-detect 显示一个预览窗口,并使用Google MobileNet v1 SSD(单发探测器)神经网络监控内容,该网络经过训练,可以使用可可数据集识别大约80类物体。 rpicam-detect 识别人、汽车、猫和许多其他物体。

每当 rpicam-detect 检测到目标对象时,它都会捕获全分辨率JPEG。然后它返回到监控预览模式。

有关模型使用的一般信息,请参阅 TensorFlow Lite对象检测器 部分。例如,您可能会在外出时偷偷监视您的猫:

$ rpicam-detect -t 0 -o cat%04d.jpg --lores-width 400 --lores-height 300 --post-process-file object_detect_tf.json --object cat

配置

大多数用例自动工作,无需更改相机配置。但是,一些常见用例确实需要配置调整,包括:

  • 第三方摄像机(制造商的说明应解释必要的配置更改,如果有)

  • Raspberry Pi 官方摄像头使用非标准驱动程序或overlay

Raspberry Pi OS识别 /boot/firmware/config.txt 中的以下overlay。

相机模块 /boot/firmware/config.txt 中的配置

V1相机(OV5647)

dtoverlay=ov5647

V2相机(IMX219)

dtoverlay=imx219

HQ相机(IMX477)

dtoverlay=imx477

GS相机(IMX296)

dtoverlay=imx296

相机模块3(IMX708)

dtoverlay=imx708

IMX290和IMX327

dtoverlay=imx290,clock-frequency=74250000dtoverlay=imx290,clock-frequency=37125000 (两个模块共享imx290内核驱动程序;有关正确的频率,请参阅模块供应商的说明)

IMX378

dtoverlay=imx378

OV9281

dtoverlay=ov9281

要使用这些overlay之一,您必须禁用自动相机检测。要禁用自动检测,请在 /boot/firmware/config.txt 中设置 camera_auto_detect=0 。如果 config.txt 已包含分配 camera_auto_detect 值的行,请将值更改为 0 。使用 sudo reboot 重新启动Raspberry Pi以加载更改。

通过调谐文件来调整相机行为

Raspberry Pi的 libcam 实现包括每个相机的调谐文件。该文件控制算法和硬件以产生最佳画质。 libcamera 只能确定正在使用的传感器,而不能确定模块。因此,某些模块需要调谐文件覆盖。使用 tuning-file 选项来指定overlay。您还可以复制和更改现有的调谐文件以自定义相机行为。

例如,无红外过滤器(NoIR)版本的传感器使用与标准版本不同的自动白平衡(AWB)设置。在Raspberry Pi 5或更高版本上,您可以使用以下命令指定IMX219传感器的NoIR调谐文件:

$ rpicam-hello --tuning-file /usr/share/libcamera/ipa/rpi/pisp/imx219_noir.json
Note
Raspberry Pi 5之前的Raspberry Pi型号使用不同的调谐文件。在这些设备上,请改用存储在 /usr/share/libcam/ipa/rpi/vc4/ 中的文件。

libcamera 维护许多相机的调谐文件,包括第三方型号。例如,您可以在 se327m12.json 中找到Soho Enterprises SE327M12的调谐文件。

使用多个摄像头

rpicam-apps 基本支持多个摄像头。您可以通过以下方式将多个摄像头连接到Raspberry Pi:

  • 对于 Raspberry Pi 计算模块,您可以将两个摄像头直接连接到 Raspberry Pi 计算模块的 I/O 板上。详情请参阅 计算模块文档。使用这种方法,您可以 同时使用两个摄像头

  • 对于Raspberry Pi 5,您可以使用双MIPI连接器将两个摄像头直接连接到电路板。

  • 对于其他带有摄像头端口的树莓派设备,您可以将两个或多个摄像头与视频多路复用板连接,例如 此第三方产品。由于两个摄像头都连接到单个Unicam端口,_同时只能有一个摄像头在_使用。

要列出平台上所有可用的相机,请使用 list-cameras 选项。要选择要使用的相机,请将相机索引传递给 相机 选项。

Note
libcamera 尚不提供立体相机支持。当同时运行两个相机时,它们必须在不同的进程中运行。这意味着它们之间无法同步传感器取景或3A操作。作为一种解决方法,您可以通过HQ(IMX477)相机的外部同步信号同步相机,并在必要时将3A切换到手动模式。

安装 libcamrpicam-apps

Raspberry Pi提供了两个 rpicam-apps 包:

  • rpicam-apps 包含支持使用桌面环境进行预览的完整应用程序。此软件包预装在Raspberry Pi OS中。

  • rpicam-apps-lite 省略了桌面环境支持,仅提供DRM预览版。此软件包预装在Raspberry Pi OS Lite中。

依赖关系

rpicam-apps 依赖于名为 library-name<n> 的包,其中 <n> 是ABI版本。您的包管理器应该会自动安装这些。

开发包

您可以重建 rpicam-apps ,而无需从头开始构建 libcameralibepoxy 。有关详细信息,请参阅 构建rpicam-apps而无需重建libcam

使用 rpicam-app 通过网络流式传输视频

本节介绍来自 rpicam-vid 的本机流。您还可以使用 libav 后端进行网络流。

UDP

要使用Raspberry Pi作为服务器通过UDP流式传输视频,请使用以下命令,将 <ip-addr> 占位符替换为客户端或多播地址的IP地址,并将 <port> 占位符替换为您要用于流式传输的端口:

$ rpicam-vid -t 0 --inline -o udp://<ip-addr>:<port>

要使用Raspberry Pi作为客户端查看通过UDP流式传输的视频,请使用以下命令,将 <port> 占位符替换为您要从中流式传输的端口:

$ vlc udp://@:<port> :demux=h264

或者,在客户端上使用以下命令使用 ffplay 进行流式传输:

$ ffplay udp://<ip-addr-of-server>:<port> -fflags nobuffer -flags low_delay -framedrop

TCP

您还可以通过TCP流式传输视频。要将Raspberry Pi用作服务器:

$ rpicam-vid -t 0 --inline --listen -o tcp://0.0.0.0:<port>

要使用Raspberry Pi作为客户端查看通过TCP流式传输的视频,请使用以下命令:

$ vlc tcp/h264://<ip-addr-of-server>:<port>

或者,在客户端上使用以下命令以每秒30帧的速度使用 ffplay 进行流式传输:

$ ffplay tcp://<ip-addr-of-server>:<port> -vf "setpts=N/30" -fflags nobuffer -flags low_delay -framedrop

RTSP

要使用VLC使用Raspberry Pi作为服务器通过RTSP流式传输视频,请使用以下命令:

$ rpicam-vid -t 0 --inline -o - | cvlc stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/stream1}' :demux=h264

要在 Raspberry Pi 5 上获得最佳性能,请使用以下命令,该命令添加了 libav 以强制使用 H264 格式:

$ rpicam-vid -t 0 --inline --libav-format h264 -o - | cvlc stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/stream1}' :demux=h264

要使用Raspberry Pi作为客户端查看通过RTSP流式传输的视频,请使用以下命令:

$ ffplay rtsp://<ip-addr-of-server>:8554/stream1 -vf "setpts=N/30" -fflags nobuffer -flags low_delay -framedrop

或者,在客户端上使用以下命令使用VLC进行流式传输:

$ vlc rtsp://<ip-addr-of-server>:8554/stream1

要取消服务器上的预览窗口,请使用 nopreview

使用 inline 标志强制流头信息进入每个帧内,这有助于客户端在错过开头时理解流。

libav

您可以将 libav 后端用作音频/视频的网络流源。 要使用Raspberry Pi作为服务器通过TCP流式传输视频,请使用以下命令,将 <ip-addr> 占位符替换为客户端或多播地址的IP地址,并将 <port> 占位符替换为您要用于流式传输的端口:

$ rpicam-vid -t 0 --codec libav --libav-format mpegts --libav-audio -o "tcp://<ip-addr>:<port>?listen=1"

您可以使用类似的命令通过UDP流式传输:

$ rpicam-vid -t 0 --codec libav --libav-format mpegts --libav-audio  -o "udp://<ip-addr>:<port>"

GStreamer

https://gstreamer.freedesktop.org/[GStreamer] 是一个用于读取、处理和播放多媒体文件的Linux框架。本节展示如何使用 `rpicam-vid` 通过网络流式传输视频。

此设置使用 rpicam-vid 将编码的h.264比特流输出到标准输出。然后,我们使用GStreamer fdsrc 元素接收比特流,并使用额外的GStreamer元素通过网络发送它。在服务器上,运行以下命令来启动流,将 <ip-addr> 占位符替换为客户端的IP地址或多播地址,并将 <port> 占位符替换为您要用于流式传输的端口:

$ rpicam-vid -t 0 -n --inline -o - | gst-launch-1.0 fdsrc fd=0 ! udpsink host=<ip-addr> port=<port>

在客户端上,运行以下命令来接收流,将 <ip-addr> 占位符替换为客户端的IP地址或多播地址,并将 <port> 占位符替换为您要用于流的端口:

$ gst-launch-1.0 udpsrc address=<ip-addr> port=<port> ! h264parse ! v4l2h264dec ! autovideosink
Tip
要测试此配置,请在同一设备上的不同终端中运行服务器和客户端命令,使用 localhost 作为地址。

RTP

$ rpicam-vid -t 0 -n --inline -o - | gst-launch-1.0 fdsrc fd=0 ! h264parse ! rtph264pay ! udpsink host=<ip-addr> port=<port>

要通过RTP接收,请在客户端上运行以下命令,将 <ip-addr> 占位符替换为客户端的IP地址或多播地址,并将 <port> 占位符替换为您要用于流式传输的端口:

$ gst-launch-1.0 udpsrc address=<ip-addr> port=<port> caps=application/x-rtp ! rtph264depay ! h264parse ! v4l2h264dec ! autovideosink

如果客户端不是Raspberry Pi,它可能有不同的GStreamer元素可用。在运行Linux的x86设备上,您可以改为运行以下命令:

$ gst-launch-1.0 udpsrc address=<ip-addr> port=<port> caps=application/x-rtp ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink

libcamerasrc GStreamer 元素

libcam 提供了一个 libcamasrc GStreamer元素,可以直接使用它来代替 rpicam-vid 。要使用此元素,请在服务器上运行以下命令,将 <ip-addr> 占位符替换为客户端或多播地址的IP地址,并将 <port> 占位符替换为您要用于流式传输的端口:

$ gst-launch-1.0 libcamerasrc ! capsfilter caps=video/x-raw,width=1280,height=720,format=NV12 ! v4l2convert ! v4l2h264enc extra-controls="controls,repeat_sequence_header=1" ! 'video/x-h264,level=(string)4.1' ! h264parse ! rtph264pay ! udpsink host=<ip-addr> port=<port>

在客户端上,我们使用与以前相同的播放管道。

rpicam-apps 选项参考

常用选项

除非另有说明,否则以下选项适用于所有具有相似或相同语义学的 rpicam-apps

要将以下选项之一传递给应用程序,请在选项名称前加上 -- .如果选项需要值,请在选项名称后立即传递该值,并用单个空格分隔。如果值包含空格,请将值用引号括起来。

一些选项有速记别名,例如 -h 而不是 --help 。使用这些速记别名而不是完整的选项名称可以节省空间和时间,但会降低易读性。

help

别名: -h

打印完整的选项集,以及每个选项的简要概要。不接受值。

version

打印 libcamrpicam-apps 的版本字符串。不接受值。

示例输出:

rpicam-apps build: ca559f46a97a 27-09-2021 (14:10:24)
libcamera build: v0.0.0+3058-c29143f7

list-cameras

列出连接到Raspberry Pi的检测到的相机及其可用的传感器模式。不接受值。

传感器模式标识符具有以下形式: S<Bayer order><Bit-depth>_<Optional packing> : <Resolution list>

裁剪在本机传感器像素中(即使在像素合并模式下)指定为 (<x>, <y>)/<Width>×<Height> . (x, y) 指定传感器阵列中大小为 width x height 的裁剪窗口的位置。

例如,以下输出显示有关索引0的 IMX219 传感器和索引1的 IMX477 传感器的信息:

Available cameras
-----------------
0 : imx219 [3280x2464] (/base/soc/i2c0mux/i2c@1/imx219@10)
    Modes: 'SRGGB10_CSI2P' : 640x480 [206.65 fps - (1000, 752)/1280x960 crop]
                             1640x1232 [41.85 fps - (0, 0)/3280x2464 crop]
                             1920x1080 [47.57 fps - (680, 692)/1920x1080 crop]
                             3280x2464 [21.19 fps - (0, 0)/3280x2464 crop]
           'SRGGB8' : 640x480 [206.65 fps - (1000, 752)/1280x960 crop]
                      1640x1232 [41.85 fps - (0, 0)/3280x2464 crop]
                      1920x1080 [47.57 fps - (680, 692)/1920x1080 crop]
                      3280x2464 [21.19 fps - (0, 0)/3280x2464 crop]
1 : imx477 [4056x3040] (/base/soc/i2c0mux/i2c@1/imx477@1a)
    Modes: 'SRGGB10_CSI2P' : 1332x990 [120.05 fps - (696, 528)/2664x1980 crop]
           'SRGGB12_CSI2P' : 2028x1080 [50.03 fps - (0, 440)/4056x2160 crop]
                             2028x1520 [40.01 fps - (0, 0)/4056x3040 crop]
                             4056x3040 [10.00 fps - (0, 0)/4056x3040 crop]

对于上面示例中的IMX219传感器:

  • 所有模式都有 RGGB Bayer排序

  • 所有模式均可在所列分辨率下提供 8 位或 10 位 CSI2 封装读数

camera

选择要使用的相机。从 可用相机列表

config

别名: -c

指定一个包含CLI选项和值的文件。考虑一个名为 example_configuration.txt 的文件,该文件包含以下文本,将选项和值指定为键值对,每行一个选项,仅长(非别名)选项名称:

timeout=99000
verbose=
Tip
省略您通常在命令行上传递的前导 -- 。对于缺少值的标志,例如上面示例中的 verbose ,您必须在后面添加 =

然后,您可以运行以下命令来指定99000毫秒的超时和详细输出:

$ rpicam-hello --config example_configuration.txt

timeout

别名: -t

默认值:5000毫秒(5秒)

指定应用程序在关闭前运行多长时间。这适用于视频录制和预览窗口。捕获静止图像时,应用程序会在捕获输出图像之前显示 timeout 毫秒的预览窗口。

要无限期运行应用程序,请指定值 0

preview

别名: -p

设置桌面或DRM预览窗口的位置(x,y坐标)和大小(w,h尺寸)。不影响相机请求的图像的分辨率或长宽比。缩放图像大小和柱子或信箱图像长宽比以适应预览窗口。

以逗号分隔的形式传递预览窗口尺寸: x, y,w,h

示例: rpicam-hello --preview 100,100,500,500

信箱预览图像

fullscreen

别名: -f

强制预览窗口使用整个屏幕,没有边框或标题栏。缩放图像大小并调整图像宽高比,使其适合整个屏幕。不接受数值。

qt-preview

使用Qt预览窗口,它比替代窗口消耗更多资源,但支持X窗口转发。与 fullscreen 标志不兼容。不接受值。

nopreview

别名: -n

使应用程序_不_显示预览窗口。不接受值。

info-text

默认值: "#%frame (%fps fps) exp %exp ag %ag dg %dg"

在桌面环境中运行时,将提供的字符串设置为预览窗口的标题。支持以下图像元数据替换:

指令 替代

%帧

帧的序列号。

%fps

瞬时帧率。

%exp

用于捕获图像的快门速度,以微秒为单位。

%ag

模拟增益应用于传感器中的图像。

%dg

ISP应用于图像的数字增益。

%rg

增益应用于每个像素的红色分量。

%bg

增益应用于每个像素的蓝色分量。

%焦点

图像的焦点指标,其中较大的值意味着更清晰的图像。

%lp

以屈光度为单位的当前镜头位置(1/距离,以米为单位)。

%afstate

自动对焦算法状态( idlescanningfocusedfailed )。

显示焦点测量的图像

widthheight

每个都接受一个数字,定义捕获图像的尺寸(以像素为单位)。

对于 rpicam-stillrpicam-jpegrpicam-vid ,指定输出分辨率。

对于 rpicam-raw ,指定原始图像的分辨率。对于采用 2×2 分档读出模式的相机,指定等于或小于分档模式的分辨率可捕获 2×2 分档的原始图像。

对于 rpicam-hello ,没有效果。

例子:

  • rpicam-vid -o test.h264 --width 1920 --height 1080 捕获1080p视频。

  • rpicam-still -r -o test.jpg --width 2028 --height 1520 捕获2028×1520分辨率的JPEG。如果与HQ相机一起使用,则使用2×2 像素合并模式,因此原始文件( test.dng )包含2028×1520原始Bayer图像。

viewfinder-widthviewfinder-height

每个都接受一个数字,定义预览窗口中显示的图像的尺寸(以像素为单位)。不影响预览窗口尺寸,因为图像会调整大小以适应。不影响捕获的静止图像或视频。

mode

允许您以下列以冒号分隔的格式指定摄像机模式: <宽度>:<高度>:<比特深度>:<包装>。如果所提供的值不完全匹配,系统会为传感器选择最接近的可用选项。您可以使用打包 (P) 或未打包 (U) 的打包格式。影响存储视频和照片的格式,但不影响传递到预览窗口的帧格式。

位深和封装是可选的。 位深度默认为12。 打包默认为 P (打包)。

有关传感器可用的位深度、分辨率和封装选项的信息,请参阅 list-cameras

例子:

  • 4056:3040:12:P - 4056×3040 分辨率,每像素 12 位,打包。

  • 1632:1224:10 - 1632×1224 分辨率,每个像素 10 位。

  • 2592:1944:10:U - 2592×1944 分辨率,每像素 10 位,未打包。

  • 3264:2448 - 3264×2448 分辨率。

打包格式详细信息

打包格式使用较少的像素数据存储空间。

在 Raspberry Pi 4 和更早的设备上,打包格式使用 MIPI CSI-2 标准打包像素。这意味着

  • 10 位摄像头模式将 4 个像素打包成 5 个字节。前 4 个字节包含每个像素的 8 个最有效位(MSB),最后一个字节包含 4 对最小有效位(LSB)。

  • 12 位摄像机模式将 2 个像素打包成 3 个字节。前 2 个字节包含每个像素的 8 个最有效位 (MSB),最后一个字节包含两个像素的 4 个最小有效位 (LSB)。

在 Raspberry Pi 5 及更高版本的设备上_,打包格式通过视觉无损压缩方案将像素值压缩为每个像素 8 位(1 个字节)。

解压格式详细信息

解压缩格式提供的像素值更易于手动操作,但像素数据的存储空间却更大。

在所有设备上,未打包格式每个像素使用 2 个字节。

在 Raspberry Pi 4 和更早的设备上,应用程序会在 most significant end 应用零填充。在未打包格式中,10 位相机模式的像素值不能超过 1023。

在 Raspberry Pi 5 及更早的设备上,应用程序会在 least significant end 应用零填充,因此图像会使用传感器提供的像素深度的全部 16 位动态范围。

viewfinder-mode

mode 选项相同,但它适用于传递到预览窗口的数据。有关详细信息,请参阅 mode 文档

lores-widthlores-height

从相机传送第二个分辨率较低的图像流,缩小到指定的尺寸。

每个都接受一个数字,定义低分辨率流的维度(以像素为单位)。

可用于预览和视频模式。不适用于静态捕获。如果您指定的长宽比与正常分辨率流不同,则会生成非方形像素。

对于 rpicam-vid ,禁用额外的颜色去噪处理。

图像后处理 结合使用时对图像分析很有用。

hflip

水平翻转图像。不接受值。

vflip

垂直翻转图像。不接受值。

rotation

旋转从传感器提取的图像。仅接受值0或180。

roi

裁剪从传感器的完整字段中提取的图像。接受四个十进制值,ranged0到1,格式如下: <x>,<y>,<w>, h> 。这些值中的每一个都代表可用宽度和高度的百分比,作为0到1之间的小数。

这些值定义了以下比例:

  • <x> :提取图像前要跳过的X坐标

  • <y> :提取图像前要跳过的Y坐标

  • <w> :要提取的图像宽度

  • <h> :要提取的图像高度

默认为 0,0,1,1 (从第一个X坐标和第一个Y坐标开始,使用100%的图像宽度,使用100%的图像高度)。

例子:

  • rpicam-hello—​roi 0.25,0.25,0.5,0.5 选择从图像中心裁剪的总像素数的一半(跳过X坐标的前25%,跳过Y坐标的前25%,使用总图像宽度的50%,使用总图像高度的50%)。

  • rpicam-hello—​roi 0,0,0.25,0.25 选择从图像左上角裁剪的总像素数的四分之一(跳过X坐标的前0%,跳过Y坐标的前0%,使用25%的图像宽度,使用25%的图像高度)。

hdr

默认值: off

以HDR模式运行相机。如果不带值传递,则假定 auto 。接受以下值之一:

  • off - 禁用 HDR。

  • auto - 在支持的设备上启用 HDR。使用传感器的内置 HDR 模式(如果可用)。如果传感器没有内置 HDR 模式,则使用可用的板载 HDR 模式。

  • single-exp - 使用板载 HDR 模式(如果可用),即使传感器有内置 HDR 模式。如果板载 HDR 模式不可用,则禁用 HDR

Raspberry Pi 5及更高版本的设备具有板载HDR模式。

要检查传感器中的内置 HDR 模式,除了 list-cameras 之外,还需传递此选项。

相机控制选项

以下选项控制影响相机画质的图像处理和算法。

sharpness 锐化

设置图像清晰度。接受以下光谱的数值:

  • 0.0 不适用锐化

  • 大于 0.0 但小于 1.0 的值适用于小于默认锐化量

  • 1.0 应用默认的锐化量

  • 大于 1.0 的值应用额外的锐化

contrast 对比度

指定图像对比度。接受以下光谱的数值:

  • 0.0 应用最小对比度

  • 大于 0.0 但小于 1.0 的值应用于小于默认对比度量

  • 1.0 应用默认对比度量

  • 大于 1.0 的值应用额外的对比度

brightness 亮度

指定图像亮度,作为输出图像中所有像素的偏移量添加。接受以下光谱的数值:

  • -1.0 适用于最小亮度(黑色)

  • 0.0 适用标准亮度

  • 1.0 适用于最大亮度(白色)

对于许多用例,更喜欢 ev

saturation 饱和度

  • 0.0 适用于最小饱和度(灰度)

  • 大于 0.0 但小于 1.0 的值适用于小于默认饱和量

  • 1.0 应用默认的饱和度量

  • 大于 1.0 的值应用额外的饱和度

ev

指定图像的 曝光值(EV) 补偿。接受一个数值,该数值控制沿着以下光谱传递给自动曝光/增益控制(AEC/AGC)处理算法的目标值:

  • -10.0 应用最小目标值

  • 0.0 应用标准目标值

  • 10.0 适用最大目标值

shutter 快门

使用快门以_microseconds_指定曝光时间。使用此选项时,增益仍然会有所不同。如果相机以帧速率运行得太快,以至于不允许指定的曝光时间(例如,帧速率为1fps,曝光时间为10000微秒),传感器将使用帧速率允许的最大曝光时间。

有关官方相机的最小和最大快门时间列表,请参阅 相机硬件文档。高于最大值的值会导致未定义的行为。

gain 增益

别名: --analoggain

设置模拟和数字增益的组合。当传感器驱动器可以提供请求的增益时,仅使用模拟增益。当模拟增益达到最大值时,ISP应用数字增益。接受一个数值。

有关官方相机的模拟增益限制列表,请参阅 相机硬件文档

有时,即使没有超过模拟增益限制,数字增益也可能超过1.0。这可能发生在以下情况下:

  • 任一颜色增益低于1.0,这将导致数字增益稳定在1.0/min(red_gain,blue_gain)。这使应用于任何颜色通道的总数字增益保持在1.0以上,以避免变色伪影。

  • 自动曝光/增益控制(AEC/AGC)更改期间的轻微差异。

metering 测光

默认值: centre

设置自动曝光/增益控制(AEC/AGC)算法的计量模式。接受以下值:

  • 中心 -中心加权计量

  • spot -点计量

  • 平均 -平均或整个帧计量

  • 自定义 -相机调谐文件中定义的自定义测光模式

有关定义自定义计量模式和调整现有计量模式中的区域权重的更多信息,请参阅 Raspberry Pi相机和lib相机的调整指南

exposure 曝光

设置曝光配置文件。更改曝光配置文件不应影响图像曝光。相反,不同模式会调整增益设置以实现相同的净结果。接受以下值:

  • 运动 :短曝光,大收益

  • normal :正常曝光,正常增益

  • long :长期敞口,收益较小

您可以使用调谐文件编辑曝光配置文件。有关详细信息,请参阅 树莓派相机和lib相机的调整指南

awb 白平衡

设置自动白平衡(AWB)模式。接受以下值:

模式名称 颜色温度范围

auto

2500K 到 8000K

incandescent

2500K 到 3000K

tungsten

3000K 到 3500K

fluorescent

4000K 到 4700K

indoor

3000K 到 5000K

daylight

5500K 到 6500K

cloudy

7000K 到 8500K

custom

在调谐文件中定义的自定义范围。

这些值只是近似值:值可能会根据相机调整而有所不同。

没有模式完全禁用AWB。相反,您可以使用 awbgains 修复颜色增益。

有关AWB模式的更多信息,包括如何定义自定义模式,请参阅 树莓派相机和lib相机的调整指南

awbgains

设置要使用的固定红色和蓝色增益值,而不是自动白平衡(AWB)算法。设置非零值以禁用AWB。接受逗号分隔的数字输入,格式如下: <red_gain>,<blue_gain>

denoise 降噪

默认值: auto

设置去噪模式。接受以下值:

  • auto :启用标准空间去噪。对视频使用超快的色彩去噪,对图像使用高质量的色彩去噪。在预览窗口中不启用额外的色彩去噪。

  • off : 禁用空间和色彩去噪

  • cdn_off :禁用颜色降噪。

  • cdn_fast :使用快速颜色降噪。

  • cdn_hq :使用高质量的色彩去噪。由于吞吐量降低,不适合视频/取景器。

即使是快速的色彩去噪也能降低帧率。高质量的色彩去噪_大幅地_降低帧率。

tuning-file 调谐文件

指定相机调谐文件。调谐文件允许您控制图像处理的许多方面,包括自动曝光/增益控制(AEC/AGC)、自动白平衡(AWB)、颜色阴影校正、颜色处理、去噪等。接受调谐文件路径作为输入。

有关调优文件的详细信息,请参见 调谐文件

autofocus-mode 自动对焦模式

默认值: default

指定自动对焦模式。接受以下值:

  • default :将相机置于连续自动对焦模式,除非 lens-position autofocus-on-capture 将模式改成手动

  • manual :根本不会移动镜头,除非手动配置 lens-position

  • auto :仅在相机启动时或拍摄前移动镜头进行自动对焦扫描,如果还使用了 autofocus-on-capture

  • continuous :随着场景的变化自动调整镜头位置

此选项仅适用于某些相机模块。

autofocus-window

默认值: normal

指定自动对焦范围。接受以下值:

  • normal :从合理接近到无穷大的焦点

  • macro :只关注近距离物体,包括相机支持的最近焦距

  • full :关注整个范围,从最接近的物体到无穷大

此选项仅适用于某些相机模块。

autofocus-speed 自动对焦速度

默认值: normal

指定自动对焦速度。接受以下值:

  • normal :以正常速度改变镜头位置

  • fast :快速改变镜头位置

此选项仅适用于某些相机模块。

autofocus-range 自动对焦范围

指定传感器完整字段内的自动对焦窗口。接受四个十进制值,范围0到1,格式如下: <x>,<y>,<w>,h> 。这些值中的每一个都表示可用宽度和高度的百分比,作为0到1之间的小数。

这些值定义了以下比例:

  • <x> :在应用自动对焦之前要跳过的X坐标

  • <y> :在应用自动对焦之前要跳过的Y坐标

  • <w> :自动对焦区域宽度

  • <h> :自动对焦区域高度

默认值使用两个维度中输出图像的中间三分之一(总图像区域的1/9)。

例子:

  • rpicam-hello --autofocus-window 0.25,0.25,0.5,0.5 选择从图像中心裁剪的总像素数的一半(跳过X坐标的前25%,跳过Y坐标的前25%,使用总图像宽度的50%,使用总图像高度的50%)。

  • rpicam-hello --autofocus-window 0,0,0.25,0.25 选择从图像左上角裁剪的总像素数的四分之一(跳过X坐标的前0%,跳过Y坐标的前0%,使用25%的图像宽度,使用25%的图像高度)。

此选项仅适用于某些相机模块。

lens-position 镜头位置

默认值: default

将镜头移动到固定焦距,通常以屈光度(单位为1/distancemetres)给出。接受以下值光谱:

  • 0.0 :将镜头移动到 无穷大 位置

  • 任何其他 number :将镜头移动到1/ 数字 位置。例如,值 2.0 将聚焦在大约0.5m

  • default :将镜头移动到与镜头超焦位置相对应的默认位置

镜头校准不完美,因此同一型号的不同相机模块可能会有所不同。

verbose

别名: -v

默认值: 1

设置详细级别。接受以下值:

  • 0 :无输出

  • 1 :正常输出

  • 2 :详细输出

输出文件选项

输出

别名: -o

设置用于录制图像或视频的文件的名称。除了明文文件名外,还接受以下特殊值:

  • - : 写入标准输出。

  • udp:// (前缀):UDP流的网络地址。

  • tcp:// (前缀):TCP流的网络地址。

  • 在文件名中包含 %d 指令,以替换为每打开一个文件就递增一次的计数指令。该指令支持标准 C 格式指令修饰符。

例子:

  • rpicam-vid -t 100000 --segment 10000 -o chunk%04d.h264 在10秒段中记录一个100秒的文件,其中每个文件都包含一个递增的四位数计数器,并用前导零填充:例如 chunk0001.h264chunk0002.h264 等。

  • rpicam-vid -t 0 --inline -o udp://192.168.1.13:5000 在端口5000上使用UDP将H.264视频流式传输到网络地址192.168.1.13。

wrap 包装

设置 输出 %d 指令使用的计数器的最大值。计数器在达到此值后重置为零。接受一个数值。

flush 刷新

帧完成写入后立即将输出文件刷新到磁盘,而不是等待系统处理它。不接受值。

post-process-file 处理后文件

指定一个 JSON 文件,用于配置成像管道应用的后处理。这适用于相机图像到达应用程序之前。其工作原理类似于传统的 raspicam "图像特效"。接受文件名路径作为输入。

后处理是一个大课题,需要使用 OpenCV 和 TensorFlowLite 等第三方软件来分析和处理图像。有关详细信息,请参阅 后处理

图像选项

本节中指定的命令行选项仅适用于静止图像输出。

要将以下选项之一传递给应用程序,请在选项名称前加上 -- .如果选项需要值,请在选项名称后立即传递该值,并用单个空格分隔。如果值包含空格,请将值用引号括起来。

一些选项有速记别名,例如 -h 而不是 --help 。使用这些速记别名而不是完整的选项名称可以节省空间和时间,但会牺牲易读性。

quality

别名: -q

默认值: 93

设置JPEG质量。接受介于 1100 之间的值。

exif

在JPEG输出文件中保存额外的EXIF标签。仅适用于JPEG输出。由于 libexif 库中的限制,许多标签当前(错误地)格式化为ASCII并在终端中打印警告。

此选项对于添加与相机设置相关的某些EXIF标签是必需的,您可以在使用 ExifTool 录制后将与相机设置无关的标签添加到输出JPEG。

示例: rpicam-still -o test.jpg --exif IDO0.Artist=Someone

timelapse

以指定的间隔记录图像。接受以毫秒为单位的间隔。将此设置与 timeout 结合使用以捕获一段时间内重复的图像。

您可以使用字符串格式为每个输出文件指定单独的文件名,例如 --output test%d.jpg

示例: rpicam-still -t 100000 -o test%d.jpg --timelapse 10000 每10秒捕获一张图像,持续100秒。

framestart

将在输出文件名中访问的帧计数器的起始值配置为 %d 。接受整数起始值。

datetime

在输出文件名中使用当前日期和时间,形式为 MMDDhhmmss.jpg :

  • MM = 2位月数

  • DD = 2位数的天数

  • hh = 2位24小时小时数

  • mm = 2位分钟数

  • ss = 2位第二个数字

不接受值。

timestamp

使用当前系统 Unix time 作为输出文件名。不接受值。

restart

默认值: 0

配置 JPEG 输出的重启标记间隔。JPEG 重启标记可帮助限制损坏对 JPEG 图像的影响,还能启用多线程 JPEG 编码和解码。接受整数值。

immediate

在应用程序运行时立即捕获图像。

keypress

别名: -k

timeout 过期或按 Enter 键时捕获图像,以先到者为准。按 x 键,然后按 Enter 退出而不捕获。不接受值。

signal

timeout 过期或收到 SIGUSR1 时捕获图像。使用 SIGUSR2 退出而不捕获。不接受值。

thumb

默认值: 320:240:70

使用以下格式配置缩略图的尺寸和质量: <w:h:q> (或 none ,省略缩略图)。

encoding

别名: -e

默认值: jpg

设置用于图像输出的编码器。接受以下值:

  • jpg - JPEG

  • png - PNG

  • bmp - BMP

  • rgb - 未压缩RGB像素的二进制转储

  • yuv420 - 未压缩YUV420像素的二进制转储

此选项始终确定编码,覆盖传递给 output 的扩展名。

使用 datetime timestamp 选项时,此选项确定输出文件扩展名。

raw

别名: -r

除输出图像外,还以 DNG 格式保存原始 Bayer 文件。用 .dng 替换输出文件扩展名。您可以使用 dcrawRawTherapee 等工具处理这些标准 DNG 文件。不接受数值。

原始文件中的图像数据正是来自传感器的数据,没有来自ISP或其他任何东西的处理。文件中保存的EXIF数据包括:

  • 曝光时间

  • 模拟增益(ISO标签是使用的模拟增益的100倍)

  • 白平衡增益(这是 拍摄中性 值的倒数)

  • ISP使用的颜色矩阵

latest

创建指向最近保存的文件的符号链接。接受符号链接名称作为输入。

autofocus-on-capture

如果设置,则在捕捉图像之前运行自动对焦循环。与下列 autofocus_mode 值交互:

  • defaultmanual :只运行捕捉时的自动对焦循环。

  • auto :在预览窗口加载时运行额外的自动对焦循环。

  • continuous : 忽略此选项,而是在整个预览过程中持续对焦。

不需要数值,但可以通过 1 启用,通过 0 关闭。不传递值等同于传递 1

只有某些相机模块(如 Raspberry Pi Camera Module 3)支持该选项。

视频选项

本节中指定的命令行选项仅适用于视频输出。

要将以下选项之一传递给应用程序,请在选项名称前加上 -- .如果选项需要值,请在选项名称后立即传递该值,并用单个空格分隔。如果值包含空格,请将值用引号括起来。

一些选项有速记别名,例如 -h 而不是 --help 。使用这些速记别名而不是完整的选项名称可以节省空间和时间,但会牺牲易读性。

quality

别名: -q

默认值: 50

接受1到100之间的MJPEG质量级别。仅适用于以MJPEG格式编码的视频。

bitrate

别名: -b

以每秒比特数控制H.264编码器使用的目标比特率。仅适用于以H.264格式编码的视频。影响输出视频的大小。

示例: rpicam-vid -b 10000000 --width 1920 --height 1080 -o test.h264

intra

别名: -g

默认值: 60

设置H.264比特流中Iframe(帧内帧)的频率。接受一定数量的帧。仅适用于以H.264格式编码的视频。

profile

设置H.264配置文件。接受以下值:

  • baseline

  • main

  • high

仅适用于以H.264格式编码的视频。

level

设置H.264级别。接受以下值:

  • 4

  • 4.1

  • 4.2

仅适用于以H.264格式编码的视频。

codec

设置用于视频输出的编码器。接受以下值:

  • h264 - 使用H.264编码器(默认)

  • mjpeg - 使用MJPEG编码器

  • yuv420 - 输出未压缩的YUV420帧。

  • libav - 使用libav后端编码音频和视频(有关详细信息,请参阅 libav

save-pts

Warning
Raspberry Pi 5不支持 save-pts 选项。改用 libav 自动生成容器格式的时间戳。

启用帧时间戳输出,允许您使用 mkvmerge 等工具将比特流转换为容器格式。接受时间戳输出文件的文件名。

示例: rpicam-vid -o test.h264 --save-pts timestamps.txt

然后,您可以使用以下命令从比特流和时间戳文件生成MKV容器文件:

$ mkvmerge -o test.mkv --timecodes 0:timestamps.txt test.h264

keypress

别名: -k

允许 CLI 使用 Enter 键启用或禁用视频输出。除非使用 initial 另行指定,否则始终以记录状态启动。键入 x 键并按 Enter 退出。不接受数值。

signal

别名: -s

允许CLI使用 SIGUSR1 启用和禁用视频输出。使用 SIGUSR2 退出。除非使用 初始 另有说明,否则始终以录制状态开始。不接受值。

initial

默认值: record

指定是启用还是禁用视频输出来启动应用程序。接受以下值:

  • record :从启用视频输出开始。

  • pause :从禁用视频输出开始。

将此选项与 keypress signal 配合使用,可在两种状态之间切换。

split

使用 keypresssignal 切换录制时,会将不同录制会话的视频输出写入不同的文件。不接受值。除非与 output 结合使用,为每个文件指定唯一的名称,否则每次写入文件时都会覆盖。

segment

将视频输出剪切为多个文件,文件长度与所传递的时间长度相同。接受以毫秒为单位的持续时间。如果传入的持续时间很小(例如 "1"),则会将每一帧记录到单独的输出文件中,以模拟突发捕捉。

您可以使用字符串格式为每个文件指定单独的文件名,例如 --output test%04d.h264

circular

默认值: 4

将视频记录写入内存中的循环缓冲区。应用程序退出时,将循环缓冲区记录到磁盘。接受以兆字节为单位的可选大小。

inline

在每个 Iframe(帧内)写入序列头。这可以帮助客户端从视频中的任意点解码视频序列,而不只是从开头解码。建议与 segment split circular 和流媒体选项一起使用。

仅适用于以H.264格式编码的视频。不接受值。

listen

在编码视频之前等待传入的客户端连接。用于通过TCP/IP进行网络流传输。不接受值。

frames

准确记录指定的帧数。任何非零值都会覆盖 timeout。接受非零整数。

framerate

准确记录指定的帧率。接受非零整数。

libav 选项

本节中指定的命令行选项仅适用于 libav 视频后端。

要启用 libav 后端,请在 codec 选项中加入 libav 值。

要将以下选项之一传递给应用程序,请在选项名称前加上 -- .如果选项需要值,请在选项名称后立即传递该值,并用单个空格分隔。如果值包含空格,请将值用引号括起来。

一些选项有速记别名,例如 -h 而不是 --help 。使用这些速记别名而不是完整的选项名称可以节省空间和时间,但会牺牲易读性。

libav-format

设置 libav 输出格式。接受以下值:

  • mkv 编码

  • mp4 编码

  • avi 编码

  • h264 流媒体

  • mpegts

如果不提供此选项,则传递给 output 选项的文件扩展名将确定文件格式。

libav-audio

启用录音。启用后,您还必须指定 audio-codec。不接受值。

audio-codec

默认值: aac

选择用于输出的音频编解码器。有关可用编解码器的列表,请运行 ffmpeg-codec

audio-bitrate

以每秒比特数为单位设置音频编码的比特率。接受数字输入。

示例: rpicam-vid --codec libav -o test.mp4 --audio_codec mp2 --audio-bitrate 16384 (使用mp2编解码器以16千比特/秒的速度录制音频)

audio-samplerate 音频采样

默认值: 0

以Hz为单位设置音频采样率。接受数字输入。 0 使用输入采样率。

audio-device

选择用于录音的ALSA输入设备。有关可用设备的列表,请运行以下命令:

$ pactl list | grep -A2 'Source #' | grep 'Name: '

您应该会看到类似于以下内容的输出:

Name: alsa_output.platform-bcm2835_audio.analog-stereo.monitor
Name: alsa_output.platform-fef00700.hdmi.hdmi-stereo.monitor
Name: alsa_output.usb-GN_Netcom_A_S_Jabra_EVOLVE_LINK_000736B1214E0A-00.analog-stereo.monitor
Name: alsa_input.usb-GN_Netcom_A_S_Jabra_EVOLVE_LINK_000736B1214E0A-00.mono-fallback

av-sync

将音频样本时间戳移动一个以微秒为单位的值。接受正数值和负数值。

检测选项

本节中指定的命令行选项仅适用于使用 rpicam-detect 的目标检测。

要将以下选项之一传递给 rpicam-detect ,请在选项名称前加上 -- .如果选项需要值,请在选项名称后立即传递该值,并用单个空格分隔。如果值包含空格,请将值用引号括起来。

一些选项有速记别名,例如 -h 而不是 --help 。使用这些速记别名而不是完整的选项名称可以节省空间和时间,但会牺牲易读性。

object

检测具有给定名称的对象,来自模型的标签文件。接受明文文件名作为输入。

gap

在捕获之间至少等待这么多帧。接受数值。

使用 rpicam-apps 进行后处理

rpicam-apps 共享一个通用的后处理框架。这允许它们通过许多自定义图像处理和图像分析例程传递从相机系统接收的图像。每个这样的例程都称为_stage_。要运行后处理阶段,请提供一个JSON文件,指示应用程序应用哪些阶段和选项。您可以在 rpicam-apps 存储库的 assets 文件夹中找到使用内置后处理阶段的示例JSON文件

例如,negate 阶段会将亮像素变暗,将暗像素变亮。由于negate阶段是基本阶段,不需要任何配置,因此 negate.json 只是为该阶段命名:

{
    "negate": {}
}

要将negate阶段应用于图像,请将 negate.json 传递给 post-process-file 选项:

$ rpicam-hello --post-process-file negate.json

要运行多个后处理阶段,请创建一个 JSON 文件,将多个阶段作为顶层键。例如,以下配置先运行 Sobel 阶段,然后运行 negate 阶段:

{
    "sobel_cv":
    {
        "ksize": 5
    },
    "negate": {}
}

Sobel stage 使用OpenCV,因此有 cv 后缀。它有一个用户可配置的参数 ksize ,指定要使用的过滤器的内核大小。在这种情况下,Sobel过滤器在黑色背景上产生明亮的边缘,negate 阶段将其变成白色背景上的黑暗边缘。

A negated Sobel filter
A negated Sobel filter.

一些阶段,如 negate ,以某种方式改变图像。其他阶段分析图像以生成元数据。后处理阶段可以将此元数据传递给其他阶段甚至应用程序。

为了提高性能,图像分析通常使用降低分辨率。 rpicam-apps 直接从ISP提供专用的低分辨率提要。

Note
随Raspberry Pi OS提供的 rpicam-apps 不包括OpenCV和TensorFlow Lite。因此,某些依赖它们的后处理阶段被禁用。要使用这些阶段,重新编译 rpicam-apps 。在运行32位内核的Raspberry Pi 3或4上,使用 -DENABLE_COMPILE_FLAGS_FOR_TARGET=armv8-neon 标志进行编译以加快某些阶段的速度。

内置阶段

negate 阶段

此阶段将亮像素变为暗像素,将暗像素变为亮像素。

negate 阶段没有用户可配置的参数。

默认的 negate.json 文件:

{
    "negate" : {}
}

运行以下命令以将此阶段文件与 rpicam-hello 一起使用:

$ rpicam-hello --post-process-file negate.json

示例输出:

A negated image
A negated image.

hdr 阶段

此阶段强调使用高动态范围(HDR)和动态范围压缩(DRC)的图像中的细节。DRC使用单个图像,而HDR组合多个图像以获得类似的结果。

参数分为三组:LP过滤器(LP filter)、全局色调映射(global tonemapping)和局部对比度(local contrast)。

此阶段将平滑滤波器(smoothing filter)应用于完全处理的输入图像以生成低通(LP)图像。然后,它根据原始图像和LP图像的差异生成高通(HP)图像。然后,它将全局色调映射应用于LP图像并将其添加回HP图像。此过程有助于保持局部对比度。

您可以使用以下参数配置此阶段:

num_frames

要累积的帧数;对于DRC,使用1;对于HDR,尝试使用8

lp_filter_strength

低通IIR滤波器的系数。

lp_filter_threshold

一个分段线性函数,将像素级别与有意义的细节阈值联系起来

global_tonemap_points

输入图像直方图中的点映射到我们希望移动它们的输出范围内的目标。使用以下子配置:

  • 分位数间平均值( qwidth

  • 目标占全部产出范围的比例( target

  • 最大( max_up )和最小( max_down )增益来移动测量的分位数均值,以防止图像变化太大

global_tonemap_strength

全局应用的强度

local_pos_strength

一个分段线性函数,定义当添加回色调映射LP图像时应用于局部对比度的增益,用于正(明亮)细节

local_neg_strength

一个分段线性函数,定义当添加回色调映射LP图像时应用于局部对比度的增益,用于负(暗)细节

local_tonemap_strength

应用于所有局部对比度的总增益

local_colour_scale

一个允许输出颜色或多或少受到强烈影响的因素

要控制处理强度,可更改 global_tonemap_strengthlocal_tonemap_strength 参数。

在 Raspberry Pi 4 上处理一张 1200 万像素的图像需要两到三秒钟。在累积多帧图像时,该阶段只向应用程序发送处理后的图像。

DRC的默认 drc.json 文件:

{
    "hdr" : {
		"num_frames" : 1,
		"lp_filter_strength" : 0.2,
		"lp_filter_threshold" : [ 0, 10.0 , 2048, 205.0, 4095, 205.0 ],
		"global_tonemap_points" :
			[
			    { "q": 0.1, "width": 0.05, "target": 0.15, "max_up": 1.5, "max_down": 0.7 },
			    { "q": 0.5, "width": 0.05, "target": 0.5, "max_up": 1.5, "max_down": 0.7 },
			    { "q": 0.8, "width": 0.05, "target": 0.8, "max_up": 1.5, "max_down": 0.7 }
			],
		"global_tonemap_strength" : 1.0,
		"local_pos_strength" : [ 0, 6.0, 1024, 2.0, 4095, 2.0 ],
		"local_neg_strength" : [ 0, 4.0, 1024, 1.5, 4095, 1.5 ],
		"local_tonemap_strength" : 1.0,
		"local_colour_scale" : 0.9
    }
}

示例:

没有DRC处理的图像
未经DRC处理的图像

运行以下命令以将此阶段文件与 rpicam-still 一起使用:

$ rpicam-still -o test.jpg --post-process-file drc.json
图像与DRC处理
经过DRC处理的图像

HDR的默认 hdr.json 文件:

{
    "hdr" : {
		"num_frames" : 8,
		"lp_filter_strength" : 0.2,
		"lp_filter_threshold" : [ 0, 10.0 , 2048, 205.0, 4095, 205.0 ],
		"global_tonemap_points" :
			[
			    { "q": 0.1, "width": 0.05, "target": 0.15, "max_up": 5.0, "max_down": 0.5 },
			    { "q": 0.5, "width": 0.05, "target": 0.45, "max_up": 5.0, "max_down": 0.5 },
			    { "q": 0.8, "width": 0.05, "target": 0.7, "max_up": 5.0, "max_down": 0.5 }
			],
		"global_tonemap_strength" : 1.0,
		"local_pos_strength" : [ 0, 6.0, 1024, 2.0, 4095, 2.0 ],
		"local_neg_strength" : [ 0, 4.0, 1024, 1.5, 4095, 1.5 ],
		"local_tonemap_strength" : 1.0,
		"local_colour_scale" : 0.8
    }
}

示例:

未经HDR处理的图像
未经HDR处理的图像

运行以下命令以将此阶段文件与 rpicam-still 一起使用:

$ rpicam-still -o test.jpg --ev -2 --denoise cdn_off --post-process-file hdr.json
图像与DRC处理
经过HDR处理的图像

motion_detect 阶段

motion_detect 阶段分析来自低分辨率图像流的帧。您必须配置低分辨率流以使用该阶段。该阶段通过将帧中的感兴趣区域(ROI)与前一帧的相应部分进行比较来检测运动。如果帧之间有足够的像素变化,则该阶段在 motion_detect 键下指示元数据中的运动。

此阶段不依赖于第三方库。

您可以使用以下参数配置此阶段,将尺寸作为0到1之间的低分辨率图像大小的比例传递:

roi_x

用于比较的感兴趣区域的x偏移量(0和1之间的比例)

roi_y

用于比较的感兴趣区域的y偏移(0和1之间的比例)

roi_width

用于比较的感兴趣区域的宽度(0和1之间的比例)

roi_height

用于比较的感兴趣区域的高度(0和1之间的比例)

difference_m

用于构造不同像素阈值的线性系数

difference_c

常数系数,用于根据 threshold = difference_m * pixel_value + difference_c 构造不同的像素阈值

frame_period

运动检测器只能运行这么多帧

hskip

水平下采样这个量的像素

vksip

这个量垂直下采样的像素

region_threshold

必须分类为不同的像素(区域)的比例才能算作运动

verbose

将消息打印到控制台,包括运动状态更改时

默认 motion_detect.json 配置文件:

{
    "motion_detect" : {
		"roi_x" : 0.1,
		"roi_y" : 0.1,
		"roi_width" : 0.8,
		"roi_height" : 0.8,
		"difference_m" : 0.1,
		"difference_c" : 10,
		"region_threshold" : 0.005,
		"frame_period" : 5,
		"hskip" : 2,
		"vskip" : 2,
		"verbose" : 0
    }
}

调整差异和阈值以使算法或多或少敏感。要提高性能,请使用 hskipvskip 参数。

运行以下命令以将此阶段文件与 rpicam-hello 一起使用:

$ rpicam-hello --lores-width 128 --lores-height 96 --post-process-file motion_detect.json

使用OpenCV进行后处理

Note
这些阶段需要安装OpenCV。您可能需要 重建支持OpenCV的rpicam-apps

sobel_cv 阶段

此阶段将 Sobel过滤器 应用于图像以强调边缘。

您可以使用以下参数配置此阶段:

ksize

Sobel过滤器的内核大小

默认 sobel_cv.json 文件:

{
    "sobel_cv" : {
        "ksize": 5
    }
}

示例:

使用Sobel过滤器强调边缘
使用Sobel过滤器强调边缘。

face_detect_cv 阶段

此阶段使用OpenCV Haar分类器来检测图像中的人脸。它返回关键字 face_detect.results 下的人脸位置元数据,并可选择绘制图像上的位置。

您可以使用以下参数配置此阶段:

cascade_name

可以找到Haar级联的文件名

scaling_factor

确定图像搜索人脸的比例范围

min_neighbors

需要算作脸的最小重叠邻居数

min_size

最小脸大小

max_size

最大面尺寸

refresh_rate

在尝试重新运行面部检测器之前要等待多少帧

draw_features

是否在返回的图像上绘制人脸位置

face_detect_cv 阶段仅在预览和视频捕获期间运行。它忽略静止图像捕获。它在分辨率在320×240和640×480像素之间的低分辨率流上运行。

默认 face_detect_cv.json 文件:

{
    "face_detect_cv" : {
        "cascade_name" : "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml",
        "scaling_factor" : 1.1,
        "min_neighbors" : 2,
        "min_size" : 32,
        "max_size" : 256,
        "refresh_rate" : 1,
        "draw_features" : 1
    }
}

示例:

将检测到的人脸绘制到图像上
将检测到的人脸绘制到图像上。

annotate_cv 阶段

此阶段使用与 info-text 选项相同的 % 替换将文本写入图像的顶角。

首先解释 info-text 指令,然后将任何剩余的标记传递给 strftime

例如,要在视频上实现日期时间戳,请传递 %F %T %z

  • %F 显示ISO-8601日期(2023-03-07)

  • %T 显示当地时间24小时(例如 "09:57:12")

  • %z 显示相对于UTC的时区(例如"-0800")

该阶段不会输出任何元数据,但会写入在 annotate.text 中找到的元数据,以取代 JSON 配置文件中的任何内容。这样,其他后处理阶段就可以将文本写入图像。

您可以使用以下参数配置此阶段:

text

要写入的文本字符串

fg

前景色

bg

背景颜色

scale

与文本大小成比例的数字

thickness

决定文字厚度的数字

alpha

覆盖背景像素时要应用的alpha量

默认 annotate_cv.json 文件:

{
    "annotate_cv" : {
        "text" : "Frame %frame exp %exp ag %ag dg %dg",
        "fg" : 255,
        "bg" : 0,
        "scale" : 1.0,
        "thickness" : 2,
        "alpha" : 0.3
    }
}

示例:

通过注释将相机和日期信息写入图像。
通过注释将相机和日期信息写入图像。

使用TensorFlow Lite进行后处理

先决条件

这些阶段需要导出 C++ API 的 TensorFlow Lite (TFLite) 库。API 的库。TFLite 不发布这种形式的库,但您可以从 lindevs.com 下载并安装导出 API 的版本。

object_classify_tf 阶段

object_classify_tf 使用 Google MobileNet v1 模型对相机图像中的对象进行分类。此阶段需要 labels.txt 文件

您可以使用以下参数配置此阶段:

top_n_results

要显示的结果数

refresh_rate

模型运行之间必须经过的帧数

threshold_high

对象被认为存在的置信度阈值(介于0和1之间)

threshold_low

对象在作为匹配项丢弃之前必须低于的置信度阈值

model_file

TFLite模型文件的文件路径

labels_file

包含对象标签的文件的文件路径

display_labels

是否在图像上显示对象标签;插入 annotate.text 元数据以供 annotate_cv 阶段渲染

verbose

向控制台输出更多信息

示例 object_classify_tf.json 文件:

{
    "object_classify_tf" : {
        "top_n_results" : 2,
        "refresh_rate" : 30,
        "threshold_high" : 0.6,
        "threshold_low" : 0.4,
        "model_file" : "/home/<username>/models/mobilenet_v1_1.0_224_quant.tflite",
        "labels_file" : "/home/<username>/models/labels.txt",
        "display_labels" : 1
    },
    "annotate_cv" : {
        "text" : "",
        "fg" : 255,
        "bg" : 0,
        "scale" : 1.0,
        "thickness" : 2,
        "alpha" : 0.3
    }
}

该阶段在尺寸为 224×224 的低分辨率流图像上运行。 运行以下命令,在 rpicam-hello 中使用该舞台文件:

$ rpicam-hello --post-process-file object_classify_tf.json --lores-width 224 --lores-height 224
台式计算机和显示器的对象分类
台式计算机和显示器的对象分类。

pose_estimation_tf 阶段

pose_estimation_tf 使用Google MobileNet v1模型来检测姿势信息。

您可以使用以下参数配置此阶段:

refresh_rate

模型运行之间必须经过的帧数

model_file

TFLite模型文件的文件路径

verbose

输出额外的信息到控制台

使用单独的 plot_pose_cv 阶段将检测到的姿势绘制到主图像上。

您可以使用以下参数配置plot_pose_cv阶段:

confidence_threshold

确定抽取多少的置信度阈值;可以小于零

示例 pose_estimation_tf.json 文件:

{
    "pose_estimation_tf" : {
        "refresh_rate" : 5,
        "model_file" : "posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite"
    },
    "plot_pose_cv" : {
       "confidence_threshold" : -0.5
    }
}

此阶段在尺寸为257×257的低分辨率流图像上运行。因为YUV420图像必须具有均匀的尺寸,所以对于YUV420图像,取整为258×258。

运行以下命令以将此阶段文件与 rpicam-hello 一起使用:

$ rpicam-hello --post-process-file pose_estimation_tf.json --lores-width 258 --lores-height 258
一个成年人类男性的姿势估计
一个成年男性的姿势估计。

object_detect_tf 阶段

object_detect_tf 使用Google MobileNet v1 SSD(单发探测器)模型来检测和标记对象。

您可以使用以下参数配置此阶段:

refresh_rate

模型运行之间必须经过的帧数

model_file

TFLite模型文件的文件路径

confidence_threshold

接受匹配前的置信度阈值

overlap_threshold

确定要合并为单个匹配项的匹配项之间的重叠量。

verbose

输出额外的信息到控制台

使用单独的 object_detect_draw_cv 阶段将检测到的对象绘制到主图像上。

您可以使用以下参数配置 object_detect_draw_cv 阶段:

line_thickness

边界框线的厚度

font_size

用于标签的字体大小

示例 object_detect_tf.json 文件:

{
    "object_detect_tf" : {
        "number_of_threads" : 2,
        "refresh_rate" : 10,
        "confidence_threshold" : 0.5,
        "overlap_threshold" : 0.5,
        "model_file" : "/home/<username>/models/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29/detect.tflite",
        "labels_file" : "/home/<username>/models/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29/labelmap.txt",
        "verbose" : 1
    },
    "object_detect_draw_cv" : {
       "line_thickness" : 2
    }
}

此阶段在 300×300 的低分辨率流图像上运行。运行以下命令,从 400×300 的低分辨率图像中心向检测器传递 300×300 的裁剪图像,即可将该阶段文件与 rpicam-hello 一起使用:

$ rpicam-hello --post-process-file object_detect_tf.json --lores-width 400 --lores-height 300
检测苹果和猫
检测苹果和猫。

segmentation_tf 阶段

segmentation_tf 使用Google MobileNet v1模型。此阶段需要一个标签文件,位于 assets/segmentation_labels.txt

此阶段在大小为257×257的图像上运行。由于YUV420图像必须具有偶数尺寸,因此低分辨率图像的宽度和高度应至少为258像素。阶段将257×257值的向量添加到图像元数据中,其中每个值表示像素所属的类别。您可以选择在图像的右下角绘制分割的表示。

您可以使用以下参数配置此阶段:

refresh_rate

模型运行之间必须经过的帧数

model_file

TFLite模型文件的文件路径

labels_file

包含标签列表的文件路径

threshold

设置详细时,当任何标签的像素数超过此数时打印

draw

将分割图绘制到图像的右下角

verbose

输出额外的信息到控制台

示例 segmentation_tf.json 文件:

{
    "segmentation_tf" : {
        "number_of_threads" : 2,
        "refresh_rate" : 10,
        "model_file" : "/home/<username>/models/lite-model_deeplabv3_1_metadata_2.tflite",
        "labels_file" : "/home/<username>/models/segmentation_labels.txt",
        "draw" : 1,
        "verbose" : 1
    }
}

此示例获取相机图像并将其缩小到258×258像素大小。此阶段甚至在不裁剪的情况下压缩非方形图像时也有效。此示例启用右下角的分割图。

运行以下命令以将此阶段文件与 rpicam-hello 一起使用:

$ rpicam-hello --post-process-file segmentation_tf.json --lores-width 258 --lores-height 258 --viewfinder-width 1024 --viewfinder-height 1024
运行分割并在右下角的分割图上显示结果
运行分割并在右下角的分割图上显示结果。

编写自己的后处理阶段

使用 rpicam-apps 后处理框架,用户可以创建自己的自定义后处理阶段。您甚至可以包含来自OpenCV和TensorFlow Lite的算法和例程。

基本后处理阶段

要创建自己的后处理阶段,请从 PostProcessingStage 类派生一个新类。 所有后处理阶段必须实现以下成员功能:

char const *Name() const

返回阶段名称。与 JSON 后处理配置文件中列出的阶段匹配。

void Read(boost::property_tree::ptree const &params)

从提供的 JSON 文件中读取舞台的配置参数。

void AdjustConfig(std::string const &use_case, StreamConfiguration *config)

为舞台提供影响摄像机配置的机会。对于不需要配置摄像机的舞台,通常为空。

void Configure()

在摄像机配置完成后调用,以分配资源并检查舞台是否能访问必要的数据流。

void Start()

摄像机启动时调用。对于不需要配置摄像机的舞台,通常为空。

bool Process(CompletedRequest &completed_request)

显示已完成的摄像机请求,以便进行后处理。这是您执行像素处理和图像分析的地方。如果后处理框架不应***将此请求传送给应用程序,则返回 true

void Stop()

摄像机停止时调用。用于关闭异步线程上的任何活动处理。

void Teardown()

摄像机配置销毁时调用。将其用作解构器,在此可以取消分配在 Configure 方法中设置的资源。

在任何阶段实现中,调用 RegisterStage 向系统注册您的阶段。

不要忘记将您的stage添加到后处理文件夹中的 meson.build 中。

在编写自己的阶段时,请记住以下TIP:

  • Process 方法阻塞成像管道。如果时间太长,管道会卡顿。始终将耗时的算法委托给异步线程。

  • 将工作委托给另一个线程时,您必须复制图像缓冲区。对于不需要全分辨率的图像分析等应用程序,请尝试使用低分辨率图像流。

  • 后处理框架_使用并行方式处理每个帧_。这提高了吞吐量。然而,一些 OpenCV 和 TensorFlow Lite 函数在每个帧内引入了另一层并行性。考虑在每一帧内序列化调用,因为后处理已经利用了多个线程。

  • 大多数流,包括低分辨率流,使用YUV420格式。对于某些OpenCV或TFLite功能,您可能需要将其转换为另一种格式。

  • 为获得最佳性能,请务必就地修改图像。

关于一个基本的例子,请参见 negate_stage.cpp。这个阶段通过将亮像素变暗和暗像素变亮来反相图像。这个阶段主要是派生类样板,只用六行代码就实现了反相逻辑。

另一个例子,请参见 sobel_cv_stage.cpp,它仅在几行OpenCV函数中实现了Sobel过滤器。

TensorFlow Lite阶段

对于使用TensorFlow Lite(TFLite)的阶段,从 TfStage 类派生一个新类。 此类将模型执行委托给单独的线程以防止相机卡顿。

TfStage 类实现了后处理阶段通常必须实现的所有 PostProcessingStage 成员函数,除了 Name 。" 所有 TfStage 派生的阶段都必须实现 Name 函数,并且应该实现以下部分或全部虚拟成员函数:

void readExtras()::基类读取命名模型和某些其他参数,如 refresh_rate 。使用此函数this读取派生阶段的额外参数并检查加载的模型是否正确(例如具有正确的输入和输出尺寸)。 void checkConfiguration():: 基类获取 TFLite 运行所需的低分辨率数据流和全分辨率数据流,以备派生阶段之需。使用此函数检查舞台所需的流。如果您的舞台无法访问所需的流之一,您可能会跳过处理或抛出错误。 void interpretOutputs():: 使用此函数读取并解释模型输出。当模型完成时,在与模型相同的线程中运行。 void applyResults():: 使用此函数将模型结果(可能是几帧前的结果)应用到当前帧。通常涉及附加元数据或绘图。在主线程中运行,在帧传送之前。

有关示例实现,请参见 object_classify_tf_stage.cpp pose_estimation_tf_stage.cpp

高级 rpicam-apps

构建 libcamerarpicam-apps

为自己构建 libcamerarpicam-apps 有以下优点:

  • 您可以获得最新的增强功能和特性。

  • rpicam-apps 可以针对运行 32 位操作系统的 Raspberry Pi 3 和 Raspberry Pi 4 设备进行额外优化编译。

  • 您可以包含可选的 OpenCV 和/或 TFLite 后处理阶段,也可以添加您自己的阶段。

  • 您可以自定义或添加您自己的源自 rpicam-apps 的应用程序

删除预装的 rpicam-apps

Raspberry Pi OS 包含预安装的 rpicam-apps 副本。在构建和安装自己的 rpicam-apps 版本之前,必须先移除预安装版本。运行以下命令从 Raspberry Pi 上删除 rpicam-apps 软件包:

[源码,控制台]

$ sudo apt remove --purge rpicam-apps

Building rpicam-apps without building libcamera

To build rpicam-apps without first rebuilding libcamera and libepoxy, install libcamera, libepoxy and their dependencies with apt:

$ sudo apt install -y libcamera-dev libepoxy-dev libjpeg-dev libtiff5-dev libpng-dev
Tip
如果您不需要支持 GLES/EGL 预览窗口,请省略 libepoxy-dev

要使用 Qt 预览窗口,请安装以下附加依赖项:

$ sudo apt install -y qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5

要获得 rpicam-vid 中的 libav 支持,请安装以下附加依赖项:

$ sudo apt install libavcodec-dev libavdevice-dev libavformat-dev libswresample-dev

如果您运行的是 Raspberry Pi OS Lite,请安装 git

$ sudo apt install -y git

接下来,build rpicam-apps

构建 libcamera

Note
如果您需要自定义行为或 apt 源内的包还未支持的最新功能,请仅从头构建 libcamera
Note

如果您运行 Raspberry Pi OS Lite,请先安装以下软件包:

$ sudo apt install -y python3-pip git python3-jinja2

首先,安装以下 libcamera 依赖项:

$ sudo apt install -y libboost-dev
$ sudo apt install -y libgnutls28-dev openssl libtiff5-dev pybind11-dev
$ sudo apt install -y qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5
$ sudo apt install -y meson cmake
$ sudo apt install -y python3-yaml python3-ply
$ sudo apt install -y libglib2.0-dev libgstreamer-plugins-base1.0-dev

现在我们准备构建 libcamera 本身。

从 GitHub 下载 Raspberry Pi 的 libcamera 分支的本地副本:

$ git clone https://github.com/raspberrypi/libcamera.git

导航到存储库的根目录:

$ cd libcamera

接下来,运行 meson 来配置构建环境:

$ meson setup build --buildtype=release -Dpipelines=rpi/vc4,rpi/pisp -Dipas=rpi/vc4,rpi/pisp -Dv4l2=true -Dgstreamer=enabled -Dtest=false -Dlc-compliance=disabled -Dcam=disabled -Dqcam=disabled -Ddocumentation=disabled -Dpycamera=enabled
Note
您可以通过替换 -Dgstreamer=enabled 来禁用 gstreamer 插件在 meson 构建配置期间使用 -Dgstreamer=disabled 。如果禁用 gstreamer ,则无需安装 libglib2.0-devlibgstreamer-plugins-base1.0-dev 依赖项。

现在,您可以使用 ninja 构建 libcamera

$ ninja -C build

最后,运行以下命令安装您刚刚构建的 libcamera 二进制文件:

$ sudo ninja -C build install
Tip
在内存为 1GB 或更少的设备上,构建可能会超出可用内存。将 -j 1 标志附加到 ninja 命令以将构建限制为单个进程。这应该可以防止构建超出 Raspberry Pi Zero 和 Raspberry Pi 3 等设备上的可用内存。

libcamera 尚未具有稳定的二进制接口。始终在构建 libcamera 之后构建 rpicam-apps

构建 rpicam-apps

首先获取 rpicam-apps 所需的依赖项。

$ sudo apt install -y cmake libboost-program-options-dev libdrm-dev libexif-dev
$ sudo apt install -y meson ninja-build

下载 Raspberry Pi 的 rpicam-apps GitHub 存储库的本地副本:

$ git clone https://github.com/raspberrypi/rpicam-apps.git

导航到存储库的根目录:

$ cd rpicam-apps

对于基于桌面的操作系统(如 Raspberry Pi OS),使用以下 meson 命令配置 rpicam-apps 构建:

$ meson setup build -Denable_libav=enabled -Denable_drm=enabled -Denable_egl=enabled -Denable_qt=enabled -Denable_opencv=disabled -Denable_tflite=disabled -Denable_hailo=disabled

对于 Raspberry Pi OS Lite 等无人机交互操作系统,请使用以下 meson 命令配置 rpicam-apps 构建:

$ meson setup build -Denable_libav=disabled -Denable_drm=enabled -Denable_egl=disabled -Denable_qt=disabled -Denable_opencv=disabled -Denable_tflite=disabled -Denable_hailo=disabled
Tip
  • 使用 -Dneon_flags=armv8-neon 为 Raspberry Pi 3 或 Raspberry Pi 4 上的 32 位操作系统启用优化。

  • 如果您已安装 OpenCV 并希望使用基于 OpenCV 的后处理阶段,请使用 -Denable_opencv=enabled

  • 如果您已安装 TensorFlow Lite 并希望在后处理阶段使用它,请使用 -Denable_tflite=enabled

  • 如果安装了 HailoRT 并希望在后处理阶段使用它,请使用 -Denable_hailo=enabled

您现在可以使用以下命令构建 rpicam-apps

$ meson compile -C build
Tip
在内存为 1GB 或更少的设备上,构建可能会超出可用内存。将 -j 1 标志加在 meson 命令后面将构建限制为单个进程。这应该可以防止构建超出 Raspberry Pi Zero 和 Raspberry Pi 3 等设备上的可用内存。

最后,运行以下命令安装您新构建的 rpicam-apps 二进制文件:

$ sudo meson install -C build

安装后打开一个新的终端窗口,以确保您使用新的二进制文件。

最后,按照 配置部分 中的 dtoverlay 和显示驱动程序说明进行操作。

Tip

上述命令会自动更新 ldconfig 缓存。如果在访问新的 rpicam-apps 版本时遇到问题,请运行以下命令更新缓存:

$ sudo ldconfig

运行以下命令检查设备是否使用了新的二进制文件:

$ rpicam-still --version

输出结果应包括本地 rpicam-apps 生成的日期和时间。

rpicam-apps meson标志参考

rpicam-appsmeson 构建配置支持以下标志:

-Dneon_flags=armv8-neon

加快运行 32 位操作系统的 Raspberry Pi 3 或 Raspberry Pi 4 设备上的某些后处理功能。

-Denable_libav=enabled

启用或禁用 libav 编码器集成。

-Denable_drm=enabled

启用或禁用 DRM/KMS 预览渲染,即在没有桌面环境的情况下使用的预览窗口。

-Denable_egl=enabled

启用或禁用非基于 Qt 桌面环境的预览。如果您的系统缺少桌面环境,请禁用。

-Denable_qt=enabled

启用或禁用对基于 Qt 的预览窗口实现的支持。如果您未安装桌面环境或不打算使用基于 Qt 的预览窗口,请禁用。通常不推荐使用基于 Qt 的预览,因为它的计算成本非常高,但它可以与 X 显示转发配合使用。

-Denable_opencv=enabled

强制基于 OpenCV 的后处理阶段链接或不链接。需要 OpenCV 才能启用。默认为 disabled

-Denable_tflite=enabled

启用或禁用 TensorFlow Lite 后处理阶段。默认情况下禁用。需要 Tensorflow Lite 才能启用。根据您构建和/或安装 TFLite 的方式,您可能需要调整 post_processing_stages 目录中的 meson.build 文件。

Denable_hailo=enabled

启用或禁用基于 HailoRT 的后处理阶段。需要 HailoRT 才能启用。默认为 auto

Ddownload_hailo_models=true

为 HailoRT 后处理阶段下载并安装模型。需要安装 wget。默认为 true

上述每个选项(除 neon_flags 外)都支持以下值:

  • enabled :启用该选项,如果依赖项不可用,则构建失败

  • disabled :禁用该选项

  • auto :如果依赖项可用,则启用该选项

构建 libepoxy

通常不需要重建 libepoxy ,因为这个库很少更改。但是,如果您确实想从头开始构建它,请按照以下说明操作。

首先安装必要的依赖项。

$ sudo apt install -y libegl1-mesa-dev

接下来,从 GitHub 下载 libepoxy 存储库的本地副本:

$ git clone https://github.com/anholt/libepoxy.git

导航到存储库的根目录:

$ cd libepoxy

在存储库的根级别创建一个构建目录,然后导航到该目录:

$ mkdir _build
$ cd _build

接下来,运行 meson 来配置构建环境:

$ meson

现在,您可以使用 ninja 构建 libexpoxy

$ ninja

最后,运行以下命令来安装您刚刚构建的 libepoxy 二进制文件:

$ sudo ninja install

编写自己的 rpicam 应用程序

rpicam-apps 并未提供所有与相机相关的功能。相反,这些应用程序体积小且灵活。需要不同行为的用户可以自己实现它。

所有 rpicam-apps 都使用一个事件循环,当一组新帧从相机系统到达时接收消息。这组帧称为 CompletedRequest (完整请求)。 CompletedRequest 包含:

  • 从单个相机帧获得的所有图像:通常是低分辨率图像和全尺寸输出

  • 来自相机和后处理系统的元数据

rpicam-hello

rpicam-hello 是最小的应用程序,也是开始了解 rpicam-apps 设计的最佳场所。它从消息中提取 CompletedRequestPtr ,一个指向 CompletedRequest 的共享指针,并将其转发到预览窗口:

CompletedRequestPtr &completed_request = std::get<CompletedRequestPtr>(msg.payload);
app.ShowPreview(completed_request, app.ViewfinderStream());

每个 CompletedRequest 都必须被回收到相机系统中,以便缓冲区可以重复使用。否则,相机将耗尽用于新相机帧的缓冲区。这个回收过程会在没有对 CompletedRequest 的引用保留时自动发生,这是通过 C++ 的 shared pointercustom deleter 机制实现的。

因此, rpicam-hello 必须完成以下操作才能回收缓冲区空间:

  • 事件循环必须完成一个循环,以便保存对 CompletedRequest 的引用的消息(代码中的 msg )可以替换为下一条消息。这将丢弃对上一条消息的引用。

  • 当事件线程调用 ShowPreview 时,它会向预览线程传递一个对 CompletedRequest 的引用。每次调用 ShowPreview 时,预览线程都会丢弃最后一个 CompletedRequest 实例。

rpicam-vid

rpicam-vid 类似于 rpicam-hello ,在事件循环中添加了编码。在事件循环开始之前, rpicam-vid 使用回调配置编码器。回调处理包含编码图像数据的缓冲区。在下面的代码中,我们将缓冲区发送到 Output 对象。 输出 可以将其写入文件或流式传输,具体取决于指定的选项。

app.SetEncodeOutputReadyCallback(std::bind(&Output::OutputReady, output.get(), _1, _2, _3, _4));

由于这段代码向编码器传递了对 CompletedRequest 的引用,因此 rpicam-vid 无法循环使用缓冲区数据,直到事件循环、预览窗口和编码器都丢弃了它们的引用。

rpicam-raw

rpicam-aw 类似于 rpicam-vid 。它也在事件循环期间进行编码。但是, rpicam-aw 使用称为 NullEncoder 的虚拟编码器。这使用输入图像作为输出缓冲区,而不是使用编解码器对其进行编码。 NullEncoder 仅在输出回调完成后丢弃其对缓冲区的引用。这保证了在回调处理图像之前不会回收缓冲区。

rpicam-aw 不会将任何内容转发到预览窗口。

NullEncoderrpicam-aw 中可能是矫枉过正的。我们可能会将图像直接发送到 Output 对象。但是, rpicam-apps 需要限制事件循环中的工作。 NullEncoder 演示了如何处理其他线程中的大多数进程(甚至保留引用)。

rpicam-jpeg

rpicam-jpeg 以常规方式在预览模式下启动相机。当定时器计时结束后,它将停止预览并切换到静态捕捉模式:

app.StopCamera();
app.Teardown();
app.ConfigureStill();
app.StartCamera();

事件循环抓取从静止模式返回的第一帧并将其保存为JPEG。

在Qt中使用 libcamera

Qt是一个流行的应用程序框架和GUI工具包。 rpicam-apps 包括一个将Qt用于相机预览窗口的选项。

不幸的是,Qt将某些符号(例如 slotemit )定义为全局命名空间中的宏。这会在包含 libcamera 文件时导致错误。这个问题在所有同时使用Qt和 libcamera 的平台上都很常见。尝试以下变通方法来避免这些错误:

  • 尽可能在任何 Qt 头文件之前列出 libcamera 包含文件或包含 libcamera 文件的文件(如 rpicam-apps 文件)。

  • 如果需要将 Qt 应用程序文件与 libcamera 包含文件混合,请将 signals: 替换为 Q_SIGNALS: ,将 slots: 替换为 Q_SLOTS: ,将 emit 替换为 Q_EMIT ,将 foreach 替换为 Q_FOREACH

  • 在任何 libcamera 包含文件的顶部添加以下内容:

    #undef signals
    #undef slots
    #undef emit
    #undef foreach
  • 如果您的项目使用 qmake ,请在项目文件中添加 CONFIG += no_keywords

  • 如果您的项目使用 cmake ,请添加 SET(QT_NO_KEYWORDS ON)

在Picamera2中使用Python中的 libcamera

Picamera2库 是基于 rpicam 的Picamera替代品,Picamera是Raspberry Pi传统相机堆栈的Python接口。Picamera2提供了一个易于使用的Python API。

关于Picamera2的文档 在GitHub上Picamera2手册中

安装

最近的Raspberry Pi OS镜像包括具有所有GUI(Qt和OpenGL)依赖项的Picamera2。最近的Raspberry Pi OS Lite映像包括没有GUI依赖项的Picamera2,尽管仍然可以使用DRM/KMS显示预览图像。

如果您的映像不包含Picamera2,请运行以下命令以安装具有所有GUI依赖项的Picamera2:

$ sudo apt install -y python3-picamera2

如果您不想要GUI依赖项,您可以运行以下命令来安装没有GUI依赖项的Picamera2:

$ sudo apt install -y python3-picamera2 --no-install-recommends
Note
如果您之前使用 pip 安装了Picamera2,请使用: pip3 uninstall picamera2 卸载它。

使用 USB 网络摄像头

大多数 Raspberry Pi 设备都有用于相机模块的专用端口。摄像头模块是深受 Raspberry Pi 用户喜爱的高质量、可高度配置的摄像头。

不过,对于许多用途来说,USB 网络摄像头可以满足您从 Raspberry Pi 录制图片和视频的一切需要。本节将介绍如何在 Raspberry Pi 上使用 USB 网络摄像头。

安装依赖

首先,安装 fswebcam 软件包:

$ sudo apt install fswebcam

然后,将用户名添加到 video 组,否则可能会出现 'permission denied' 的错误:

$ sudo usermod -a -G video <username>

要检查用户是否已正确添加到组中,请使用 groups 命令。

拍照(Take a photo)

运行以下命令使用网络摄像头拍照,并将图像保存到名为 image.jpg 的文件中:

$ fswebcam image.jpg

您应该会看到类似下面的输出:

--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
Adjusting resolution from 384x288 to 352x288.
--- Capturing frame...
Corrupt JPEG data: 2 extraneous bytes before marker 0xd4
Captured frame in 0.00 seconds.
--- Processing captured image...
Writing JPEG image to 'image.jpg'.
默认情况下,`fswebcam` 使用低分辨率,并添加一个显示时间戳的标语
默认情况下,fswebcam 使用低分辨率,并添加一个显示时间戳的横幅。

要为捕获的图像指定不同的分辨率,请使用 -r 标志,将宽度和高度作为两个数字传递,中间用 x 分隔:

$ fswebcam -r 1280x720 image2.jpg

您应该会看到类似下面的输出:

--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
--- Capturing frame...
Corrupt JPEG data: 1 extraneous bytes before marker 0xd5
Captured frame in 0.00 seconds.
--- Processing captured image...
Writing JPEG image to 'image2.jpg'.
指定分辨率以获取更高质量的图像
指定分辨率以获取更高质量的图像。

Remove the banner

要从捕获的图像中删除横幅,请使用 --no-banner 标记:

$ fswebcam --no-banner image3.jpg

您应该会看到类似下面的输出:

--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
--- Capturing frame...
Corrupt JPEG data: 2 extraneous bytes before marker 0xd6
Captured frame in 0.00 seconds.
--- Processing captured image...
Disabling banner.
Writing JPEG image to 'image3.jpg'.
Specify `--no-banner` to save the image without the timestamp banner
Specify --no-banner to save the image without the timestamp banner.

自动采集图像 (Automate image capture)

不同于 rpicam-appsfswebcam 没有在输出图像名称中替换时间戳和数字的内置功能。这在捕获多张图像时很有用,因为每次录制图像时手动编辑文件名可能会很乏味。相反,你可以使用 Bash 脚本自己实现这一功能。

在主文件夹中新建一个名为 webcam.sh 的文件。添加以下示例代码,使用 bash 编程语言将图像保存到文件中,文件名包含年、月、日、时、分和秒:

#!/bin/bash

DATE=$(date +"%Y-%m-%d_%H-%M-%S")

fswebcam -r 1280x720 --no-banner $DATE.jpg

然后,运行以下命令使 bash 脚本可执行:

$ chmod +x webcam.sh

使用以下命令运行脚本,捕捉图像并将其保存到文件中,文件名带有时间戳,类似于 2024-05-10_12-06-33.jpg

$ ./webcam.sh

您应该会看到类似下面的输出:

--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
--- Capturing frame...
Corrupt JPEG data: 2 extraneous bytes before marker 0xd6
Captured frame in 0.00 seconds.
--- Processing captured image...
Disabling banner.
Writing JPEG image to '2024-05-10_12-06-33.jpg'.

捕捉延时 (Capture a time lapse)

使用 cron 按给定的时间间隔安排照片捕捉。如果间隔时间合适,例如一分钟一次,就可以捕捉延时照片。

首先,打开 cron 表进行编辑:

$ crontab -e

在编辑器中打开文件后,在计划表中添加以下一行,每分钟拍摄一张照片,将 <username> 替换为您的用户名:

* * * * * /home/<username>/webcam.sh 2>&1

保存并退出后,你会看到如下信息:

crontab: installing new crontab

V4L2驱动程序

V4L2 驱动程序为访问摄像头和编解码器功能提供了一个标准的 Linux 界面。通常情况下,Linux 会在启动时自动加载驱动程序。但在某些情况下,你可能需要 显式加载摄像头驱动程序

使用 libcamera 时的设备节点

/dev/videoX Default action

video0

Unicam driver for the first CSI-2 receiver

video1

Unicam driver for the second CSI-2 receiver

video10

Video decode

video11

Video encode

video12

Simple ISP, can perform conversion and resizing between RGB/YUV formats in addition to Bayer to RGB/YUV conversion

video13

Input to fully programmable ISP

video14

High resolution output from fully programmable ISP

video15

Low result output from fully programmable ISP

video16

Image statistics from fully programmable ISP

video19

HEVC decode

使用V4L2驱动程序

有关如何使用 V4L2 驱动程序的更多信息,请参阅 V4L2 文档

Unicam

树莓派SoC都有两个摄像头接口,支持CSI-2 D-PHY 1.1或紧凑型摄像头端口2(CCP2)源。该接口的代号为 Unicam。Unicam 的第一个实例支持两个CSI-2数据通道,而第二个实例支持四个。每个通道可以以高达1Gbit/s(DDR,因此最大链路频率为500MHz)的速度运行。

Compute Modules 和 Raspberry Pi 5 可从两个外设引出所有通道。Raspberry Pi 5 之前的其他型号只引出了第二个通道到摄像头连接器。

软件接口

V4L2软件接口是与Unicam外设通信的唯一方式。过去也有固件和MMAL rawcam组件接口,但不再支持这些。

V4L2

Note
Unicam的V4L2接口仅在使用 libcamera 时可用。

Unicam部分有一个完全开源的内核驱动程序;这个名为 bcm2835-unicam 的内核模块与V4L2子设备驱动程序接口以提供原始帧。这个 bcm2835-unicam 驱动程序控制传感器并配置相机串行接口2(CSI-2)接收器。外设将原始帧(在Debayer之后)写入SDRAM,以便V4L2交付给应用程序。捕获图像的相机传感器和将图像数据放入SDRAM的 bcm2835-unicam 驱动程序之间没有图像处理,除了Bayer解压为16位/像素。

|------------------------|
|     bcm2835-unicam     |
|------------------------|
     ^             |
     |      |-------------|
 img |      |  Subdevice  |
     |      |-------------|
     v   -SW/HW-   |
|---------|   |-----------|
| Unicam  |   | I2C or SPI|
|---------|   |-----------|
csi2/ ^             |
ccp2  |             |
    |-----------------|
    |     sensor      |
    |-----------------|

主线Linux包含一系列现有的驱动程序。树莓派内核树有一些额外的驱动程序和设备树覆盖来配置它们:

Device Type Notes

Omnivision OV5647

5MP Camera

Original Raspberry Pi Camera

Sony IMX219

8MP Camera

Revision 2 Raspberry Pi camera

Sony IMX477

12MP Camera

Raspberry Pi HQ camera

Sony IMX708

12MP Camera

Raspberry Pi Camera Module 3

Sony IMX296

1.6MP Camera

Raspberry Pi Global Shutter Camera Module

Toshiba TC358743

HDMI to CSI-2 bridge

Analog Devices ADV728x-M

Analog video to CSI-2 bridge

No interlaced support

Infineon IRS1125

Time-of-flight depth sensor

Supported by a third party

由于子设备驱动程序也是具有标准化API的内核驱动程序,因此第三方可以自由地为他们选择的任何来源编写自己的驱动程序。

写第三方驱动

这是通过Unicam进行接口的推荐方法。

为打算与 bcm2835-unicam 模块一起使用的新设备开发驱动程序时,您需要驱动程序和相应的设备树overlay。理想情况下,驱动程序应该提交到 linux-media 邮件列表进行代码审查并合并到主线中,然后移动到 Raspberry Pi内核树;但是驱动程序可能会被审查并直接合并到Raspberry Pi内核中。

Note
所有内核驱动程序都在GPLv2许可下获得许可,因此源代码必须可用。仅运送二进制模块违反了Linux内核许可下的GPLv2许可。

bcm2835-unicam 模块已被编写为尝试适应当前主线Linux内核中所有类型的CSI-2源驱动程序。这些可以大致分为相机传感器和桥接芯片。桥接芯片允许在其他格式和CSI-2之间进行转换。

相机传感器

相机传感器的传感器驱动程序负责设备的所有配置,通常通过I2C或SPI。与其从头开始编写驱动程序,不如以现有驱动程序为基础并酌情对其进行修改。

IMX219驱动程序 是一个很好的起点。该驱动程序支持8位和10位Bayer读出,因此枚举帧格式和帧大小稍微复杂一些。

传感器通常支持 V4L2 用户控制。并非所有这些控制都需要在驱动程序中实现。IMX219 驱动程序只实现了下面列出的一小部分,其实现由 imx219_set_ctrl 函数处理。

  • V4L2_CID_PIXEL_RATE / V4L2_CID_VBLANK / V4L2_CID_HBLANK :允许应用程序设置帧频。

  • V4L2_CID_EXPOSURE : 以行为单位设置曝光时间;应用程序需要使用 V4L2_CID_PIXEL_RATEV4L2_CID_HBLANK 和帧宽来计算行时间。

  • V4L2_CID_ANALOGUE_GAIN :以传感器为单位的模拟增益

  • V4L2_CID_DIGITAL_GAIN:以传感器为单位的可选数字增益

  • V4L2_CID_HFLIP / V4L2_CID_VFLIP : 水平或垂直翻转图像;此操作可能会改变帧中数据的Bayer顺序,IMX219 就是这种情况。

  • V4L2_CID_TEST_PATTERN / V4L2_CID_TEST_PATTERN_* :可从传感器输出各种测试模式;对调试非常有用。

对于IMX219,其中许多控件直接映射到寄存器写入传感器本身。

进一步的指导可以在 libcamera 传感器驱动程序要求树莓派相机调谐指南 的第3章中找到。

设备树

设备树用于选择传感器驱动程序并配置参数,例如CSI-2通道数、连续时钟通道操作和链路频率(通常只支持一个)。

6.1版本内核中IMX219的 Device Tree overlay 可在GitHub上获得。

桥接芯片

这些设备将传入的视频流(例如HDMI或复合)转换为Raspberry Pi CSI-2接收器可以接受的CSI-2流。

处理桥接芯片更复杂。与相机传感器不同,它们必须响应传入信号并将其报告给应用程序。

处理桥接芯片的机制可以分为两类:模拟或数字。

在下面的章节中使用 ioctls 时, ioctl 名称中的 S 表示它是一个 set 函数,而 G 是一个 get 函数, ENUM 枚举一组允许的值。

模拟视频源

模拟视频源使用标准 ioctls 检测和设置视频标准。https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-g-std.html[VIDIOC_G_STD]、https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-g-std.html[VIDIOC_S_STD], VIDIOC_ENUMSTDVIDIOC_QUERYSTD 可用。

选择错误的标准通常会导致图像损坏。设置标准通常也会设置 V4L2 CAPTURE 队列的分辨率。它不能通过 VIDIOC_S_FMT 设置。一般来说,通过 VIDIOC_QUERYSTD 请求检测到的标准,然后在流媒体播放前用 VIDIOC_S_STD 设置是个好主意。

数字视频源

对于数字视频源,例如HDMI,有一组备用调用允许指定所有数字定时参数:https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-g-dv-timings.html[VIDIOC_G_DV_TIMINGS], VIDIOC_S_DV_TIMINGS, VIDIOC_ENUM_DV_TIMINGSVIDIOC_QUERY_DV_TIMINGS

与模拟网桥一样,时序通常会固定 V4L2 CAPTURE 队列的分辨率,在流媒体传输之前,用 VIDIOC_QUERY_DV_TIMINGS 的结果调用 VIDIOC_S_DV_TIMINGS 应能确保格式正确。

根据桥接芯片和驱动程序,可以通过 VIDIOC_SUBSCRIBE_EVENTV4L2_EVENT_SOURCE_CHANGE 向应用程序报告输入源的变化。

当前支持的设备

Raspberry PiLinux内核目前支持两种桥接芯片:用于模拟视频源的Analog Devices ADV728x-M和用于HDMI源的Toshiba TC358743。

ADI公司 ADV728x(A)-M 模拟视频到CSI2桥接芯片将复合S视频(Y/C)或分量(YPrPb)视频转换为单通道CSI-2接口,并由 ADV7180内核驱动程序 支持。

有关该芯片各种版本的产品详细信息,请访问 Analog Devices 网站:https://www.analog.com/en/products/adv7280a.html[ADV7280A], ADV7281AADV7282A

由于当前 V4L2 核心实现中的某些代码缺失,导致选择源失败,因此树莓派内核版本为 ADV7180 内核驱动程序添加了一个名为 dbg_input 的内核模块参数,每次调用 VIDIOC_S_STD 时都会设置输入源。主流将在某个时候修复根本问题(内核 API 调用 s_routing 与用户空间调用 VIDIOC_S_INPUT 之间的脱节),届时这一修改将被删除。

不支持接收隔行扫描视频,因此 ADV7281(A)-M 版本的芯片用途有限,因为它没有必要的 I2P 去隔行扫描块。在选择设备时,请确保指定 -M 选项。否则,您将得到一个并行输出总线,无法与 Raspberry Pi 连接。

目前尚无使用这些芯片的商用电路板,但此驱动程序已通过ADI公司 EVAL-ADV7282-M评估板 进行了测试。

如果使用的是 "ADV7282-M "芯片变体,可使用 "config.txt "dtoverlay "adv7282m "加载该驱动程序;如果使用的是其他变体,可使用 "adv7280m=1"、"adv7281m=1 "或 "adv7281ma=1 "参数加载 "adv728x-m "驱动程序。

dtoverlay=adv728x-m,adv7280m=1

东芝 TC358743 是一款 HDMI 转 CSI-2 桥接芯片,能够转换最高 1080p60 的视频数据。。

关于这款桥接芯片的信息可以在 东芝网站 上找到。

TC358743将HDMI连接到CSI-2和I2S输出。它由 TC358743内核模块 支持。

该芯片支持输入 RGB888、YUV444 或 YUV422 的 HDMI 信号,最高可达 1080p60。它可以转发 RGB888,或将其转换为 YUV444 或 YUV422,也可以在 YUV444 和 YUV422 之间进行转换。目前只测试了对 RGB888 和 YUV422 的支持。使用两个 CSI-2 通道时,可支持的最大速率为 RGB888 的 1080p30 或 YUV422 的 1080p50。在计算模块上使用四个通道时,可接收 1080p60 的任一格式。

HDMI 通过接收设备发布一个包含所有可支持模式的 EDID 来协商分辨率。内核驱动程序并不了解用户希望接收的分辨率、帧速率或格式,因此用户需要通过 VIDIOC_S_EDID ioctl 提供合适的文件,或者使用 v4l2-ctl --fix-edid-checksums --set-edid=file=filename.txt (添加 --fix-edid-checksums 选项意味着用户不必在源文件中获取正确的校验和值)。生成所需的 EDID 文件(二进制 EDID 文件的文本十六进制转储)并不繁琐,也有一些工具可以生成,但不在本页讨论范围之内。

如上所述,使用 DV_TIMINGS ioctls 配置驱动程序以匹配传入视频。最简单的方法是使用 v4l2-ctl --set-dv-bt-timings query 命令。驱动程序确实支持生成 "SOURCE_CHANGED "事件,如果你想编写一个应用程序来处理不断变化的信号源的话。通过 VIDIOC_S_FMT 设置可更改输出像素格式,但只有像素格式字段会更新,因为分辨率是由 DV 时序配置的。

市面上有几种电路板可以将这种芯片连接到 Raspberry Pi。最常见的是 Auvidea B101 和 B102,但也有其他同类电路板。

该驱动程序使用 config.txt dtoverlay tc358743 加载。

该芯片还支持通过 I2S 捕捉立体声 HDMI 音频。Auvidea 电路板将相关信号分解到一个针座上,然后连接到 Raspberry Pi 的 40 针座上。所需接线如下

Signal B101 header 40-pin header BCM GPIO

LRCK/WFS

7

35

19

BCK/SCK

6

12

18

DATA/SD

5

38

20

GND

8

39

N/A

除了 tc358743-audio 覆盖层之外,还需要 tc358743 覆盖层。这将为 HDMI 音频创建一个 ALSA 录音设备。

音频不会重新采样。音频的存在反映在 V4L2 控制 TC358743_CID_AUDIO_PRESENT (音频存在)中,输入音频的采样率反映在 V4L2 控制 TC358743_CID_AUDIO_SAMPLING_RATE (音频采样频率)中。在没有音频或音频采样率与报告的采样率不同的情况下进行录音会发出警告。

rpicamraspicam 之间的差异

rpicam-apps 模拟了旧版 raspicam 应用程序的大多数功能。但是,用户可能会注意到以下差异:

  • Boost program_options 不允许使用多字符短版本选项,因此必须删除这些选项。长格式选项的命名方式相同,并且保留任何单字符短格式。

  • rpicam-stillrpicam-jpeg 不会在预览窗口中显示捕获的图像。

  • rpicam-apps 删除了以下 raspicam 功能:

    • 不透明度 ( --opacity )

    • 图像效果 ( --imxfx )

    • 色彩效果 ( --colfx )

    • 注释 ( --annotate--annotateex )

    • 动态范围压缩或 DRC ( --drc )

    • 立体声 ( --stereo--decimate--3dswap )

    • 图像稳定 ( --vstab )

    • 演示模式 ( --demo )

      后处理 替换了其中许多功能。

  • rpicam-apps 删除了 rotation 选项对 90° 和 270° 旋转的支持。

  • raspicam 合并了测光和曝光; rpicam-apps 将这些选项分开。

  • 要在 rpicam-apps 中禁用自动白平衡 (AWB),请使用 awbgains 设置一对颜色增益(例如 1.0,1.0 )。

  • rpicam-apps 无法将 NoIR 相机模块的自动白平衡 (AWB) 设置为灰色世界模式。相反,请将 tuning-file 选项传递给 NoIR 特定的调谐文件,如 imx219_noir.json

  • rpicam-apps 不提供对数字增益的明确控制。相反, gain 选项会隐式设置它。

  • rpicam-apps 删除了 --ISO 选项。相反,计算与所需 ISO 值相对应的增益。供应商可以提供增益到 ISO 的映射。

  • rpicam-apps 不支持设置闪烁周期。

  • rpicam-still 不支持连拍。相反,考虑在 MJPEG 模式下使用 rpicam-vid--segment 1 强制将每帧放入单独的文件中。

  • rpicam-apps 对所有图像传感器都使用开源驱动程序,因此启用或禁用传感器上的缺陷像素校正 (DPC) 的机制不同。Raspberry Pi HQ 相机上的 imx477 驱动程序默认启用传感器上的 DPC。要在 HQ 相机上禁用传感器上的 DPC,请运行以下命令:

    $ sudo echo 0 > /sys/module/imx477/parameters/dpc_enable

故障排除

如果你的相机模块不能像你期望的那样工作,请尝试以下修复方法:

  • 在运行 Raspberry Pi OS Bullseye 或更早版本的 Raspberry Pi 3 及更早设备上:

    • 要启用硬件加速相机预览,请启用 Glamor。要启用 Glamor,在终端中输入 sudo raspi-config ,选择 Advanced Options > Glamor > Yes 。然后用 sudo reboot 重启树莓派。

    • 如果看到与显示驱动程序有关的错误,在 /boot/config.txt 中添加 dtoverlay=vc4-fkms-v3ddtoverlay=vc4-kms-v3d

  • 在 Raspberry Pi 3 及更早的版本中,图形硬件只能支持最大 2048×2048 像素的图像,这就限制了预览窗口中可调整大小的摄像头图像。因此,对宽度大于 2048 像素的图像进行视频编码时,会产生损坏或丢失的预览图像。

  • 在 Raspberry Pi 4 上,图形硬件只能支持最大 4096×4096 像素的图像,这就限制了可在预览窗口中调整大小的摄像头图像。因此,对宽度大于 4096 像素的图像进行视频编码时,会产生损坏或丢失的预览图像。

  • 在桌面环境中,预览窗口可能会出现显示撕裂。这是一个已知但是无法修复的问题

  • 检查 FFC(扁平软电缆)是否牢固就位、完全插入,以及触点是否朝向正确方向。

  • 如果在摄像头和 Raspberry Pi 之间使用连接器,请检查连接器上的端口是否牢固就位、完全插入,以及触点是否朝向正确方向。

  • 检查并确保 FFC(扁平软电缆)连接到 CSI(摄像头串行接口),而不是 DSI(显示器串行接口)。连接器可以插入任何一个端口,但只有 CSI 端口可以供电和控制摄像头。请查看印在端口附近电路板上的 "CSI "标签。

  • 更新至最新软件

  • 尝试使用不同的电源。相机模块会增加 Raspberry Pi 约 200-250mA 的电力需求。如果您的电源质量较差,您的 Raspberry Pi 可能无法为相机模块供电。

  • 如果您已经检查了上述所有问题,但您的相机模块仍然无法像您期望的那样工作,请尝试在我们的论坛上发帖寻求更多帮助。

获取帮助

有关 libcamerarpicam-apps 的进一步帮助,请查看 树莓派相机论坛。发帖前:

  • 记下您的操作系统版本( uname -a )。

  • 记下您的 libcamerarpicam-apps 版本( rpicam-hello—​version )。

  • 告您正在使用的相机模块的品牌和型号。

  • 报告您尝试使用的软件。我们不支持第三方相机模组供应商软件。

  • 报告您的Raspberry Pi型号,包括内存大小。

  • 包括应用程序控制台输出的任何相关信息。

如果相机软件中存在特定问题(例如崩溃),请考虑 rpicam-apps GitHub存储库中创建问题,包括上面列出的相同详细信息。

本页内容