在存储库的根级别创建一个构建目录,然后导航到该目录: mkdir _build
cd _build
接下来,运行 meson 配置构建环境: meson
现在,您可以使用 ninja 构建 libexpoxy: ninja
最后,运行以下命令以安装新构建的 libepoxy 二进制文件: sudo ninja install
编写自己的 rpicam 应用程序rpicam-apps 并不提供任何人都可能需要的所有与相机相关的功能。相反,这些应用程序小巧而灵活。需要不同行为的用户可以自己实现。 所有 rpicam 应用程序都使用一个事件循环,当一组新帧从相机系统到达时接收消息。这组帧称为 CompletedRequest。CompletedRequest 包含: * 从该单个相机帧派生的所有图像:通常是低分辨率图像和全尺寸输出 * 来自相机和后处理系统的元数据 rpicam-hellorpicam-hello 是最小的应用程序,也是开始了解 rpicam-apps 设计的最佳场所。它从消息中提取 CompletedRequestPtr(指向 CompletedRequest 的共享指针),并将其转发到预览窗口: CompletedRequestPtr &completed_request = std::get(msg.payload);
app.ShowPreview(completed_request, app.ViewfinderStream());
每个 CompletedRequest 都必须回收回相机系统,以便可以重复使用缓冲区。否则,相机将耗尽用于新相机帧的缓冲区。当使用 C++ 的共享指针和自定义删除程序机制未保留对 CompletedRequest 的引用时,会自动执行此回收过程。 因此,rpicam-hello 必须完成以下操作才能回收缓冲区空间: rpicam-vidrpicam-vid 类似于 rpicam-hello,但将编码添加到事件循环中。在事件循环开始之前,rpicam-vid 使用回调配置编码器。回调处理包含编码图像数据的缓冲区。在下面的代码中,我们将缓冲区发送到 Output 对象。输出可以将其写入文件或流式传输,具体取决于指定的选项。 app.SetEncodeOutputReadyCallback(std::bind(&Output::OutputReady, output.get(), _1, _2, _3, _4));
由于此代码向编码器传递对 CompletedRequest 的引用,因此 rpicam-vid 无法回收缓冲区数据,直到事件循环、预览窗口和编码器都丢弃其引用。 rpicam-rawrpicam-raw 类似于 rpicam-vid。它还在事件循环期间进行编码。但是,rpicam-raw 使用称为 NullEncoder 的虚拟编码器。这将使用输入图像作为输出缓冲区,而不是使用编解码器对其进行编码。NullEncoder 仅在输出回调完成后放弃其对缓冲区的引用。这可以保证在回调处理映像之前不会回收缓冲区。 rpicam-raw 不会将任何内容转发到预览窗口。 NullEncoder 在 rpicam-raw 中可能矫枉过正。相反,我们可能可以将图像直接发送到 Output 对象。但是,rpicam-apps 需要限制事件循环中的工作。NullEncoder 演示了如何处理其他线程中的大多数进程(甚至保留引用)。 rpicam-jpegRPiCam-jpeg 以通常的方式在预览模式下启动相机。计时器完成后,它会停止预览并切换到仍捕获: app.StopCamera();
app.Teardown();
app.ConfigureStill();
app.StartCamera();
事件循环抓取从静止模式返回的第一帧,并将其保存为 JPEG。 将 libcamera 与 Qt 一起使用Qt是一个流行的应用程序框架和GUI工具包。rpicam-apps 包含一个使用 Qt 作为相机预览窗口的选项。 不幸的是,Qt将某些符号(如slot和emit)定义为全局命名空间中的宏。这会导致在包含 libcamera 文件时出错。这个问题是所有同时使用Qt和libcamera的平台的共同点。请尝试以下解决方法来避免这些错误:
尽可能在任何Qt头文件之前列出libcamera包含文件或包含libcamera文件的文件(例如rpicam-apps文件)。 如果您确实需要将 Qt 应用程序文件与 libcamera include 混合使用,请将 signals: 替换为 Q_SIGNALS:,将 slots: 替换为 Q_SLOTS:,将 emit 替换为 Q_EMIT,将 foreach 替换为 Q_FOREACH。 在任何 libcamera 包含文件的顶部添加以下内容:
```
#undef signals
#undef slots
#undef emit
#undef foreach
```
将 Python 中的 libcamera 与 Picamera2 一起使用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
注意:如果您之前使用 pip 安装了 Picamera2,请使用以下命令卸载它:pip3 uninstall picamera2。 使用 USB 网络摄像头大多数 Raspberry Pi 设备都有用于摄像头模块的专用端口。摄像头模块是受 Raspberry Pi 用户欢迎的高质量、高度可配置的摄像头。 但是,出于多种用途,USB 网络摄像头拥有从 Raspberry Pi 录制图片和视频所需的一切。本节介绍如何在 Raspberry Pi 上使用 USB 网络摄像头。 安装依赖项首先,安装 fswebcam 软件包: sudo apt install fswebcam
接下来,将您的用户名添加到视频组,否则您可能会看到“权限被拒绝”错误: sudo usermod -a -G video
要检查用户是否已正确添加到组中,请使用 groups 命令。 拍照运行以下命令以使用网络摄像头拍摄照片并将图像保存到名为 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 使用低分辨率并添加显示时间戳的横幅。 要为捕获的图像指定不同的分辨率,请使用 -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'.
指定分辨率以捕获更高质量的图像。
移除横幅要从捕获的图像中删除横幅,请使用 --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'.
指定 --no-banner 以保存不带时间戳横幅的图像。
自动捕获图像与 rpicam-apps 不同,fswebcam 没有任何内置功能来替换输出图像名称中的时间戳和数字。这在捕获多个图像时非常有用,因为每次录制图像时手动编辑文件名可能会很乏味。相反,请使用 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'.
捕捉延时摄影使用 cron 安排在给定时间间隔拍摄照片。使用正确的间隔(例如每分钟一次),您可以捕获延时摄影。 首先,打开 cron 表进行编辑: crontab -e
在编辑器中打开文件后,将以下行添加到计划中,每分钟拍摄一张照片,并<username>替换为您的用户名: * * * * * /home//webcam.sh 2>&1
保存并退出,您应该会看到以下消息: crontab: installing new crontab
V4L2 驱动程序V4L2 驱动程序提供用于访问相机和编解码器功能的标准 Linux 接口。通常,Linux 会在启动期间自动加载驱动程序。但在某些情况下,您可能需要显式加载相机驱动程序。 使用 libcamera 时的设备节点/dev/videoX | 默认操作 |
---|
video0 | 第一个 CSI-2 接收器的 Unicam 驱动程序 | video1 | 第二个 CSI-2 接收器的 Unicam 驱动程序 | video10 | 视频解码 | video11 | 视频编码 | video12 | 简单的ISP,除了拜耳到RGB / YUV的转换外,还可以在RGB / YUV格式之间执行转换和调整大小 | video13 | 输入到完全可编程的 ISP | video14 | 来自完全可编程 ISP 的高分辨率输出 | video15 | 来自完全可编程 ISP 的低结果输出 | video16 | 来自完全可编程 ISP 的图像统计 | video19 | HEVC 解码 |
使用 V4L2 驱动程序有关如何使用 V4L2 驱动程序的详细信息,请参阅 V4L2 文档。 |