你问的 Get() 方法在这段 Options 结构体中实际上是通过返回 v_(一个 std::unique_ptr<OptsInternal>)的引用 来实现的。
先逐行拆解这个结构:
如下最基本,有许多根据不同功能的派生类比如still和detect
1️⃣ 成员结构
struct Options
{
Options();
virtual ~Options() {}
virtual bool Parse(int argc, char *argv[]);
virtual void Print() const { v_->Print(); }
const OptsInternal &Get() const { return *v_.get(); }
OptsInternal &Set() const { return *v_.get(); }
void SetApp(RPiCamApp *app) { app_ = app; }
Platform GetPlatform() const { return platform_; };
-
v_:通常是std::unique_ptr<OptsInternal>类型的成员变量(在类定义里可能是std::unique_ptr<OptsInternal> v_;)。OptsInternal是一个保存实际解析后配置参数的内部类。- 负责保存例如:分辨率、帧率、后处理配置、模型路径等。
2️⃣ Get() 的实现
const OptsInternal &Get() const { return *v_.get(); }
-
v_.get():- 调用了
unique_ptr的get()方法,返回一个 原始指针OptsInternal*。
- 调用了
-
*v_.get():- 对这个指针解引用,返回
OptsInternal&。
- 对这个指针解引用,返回
-
最后用
const修饰:- 保证调用者不能通过这个引用修改配置(只读)。
因此,Get() 是一个只读访问器,允许外部代码访问 OptsInternal 内部存储的参数。
3️⃣ Set() 的实现
OptsInternal &Set() const { return *v_.get(); }
- 与
Get()相比,Set()去掉了const限制。 - 外部调用
Set()后,能修改OptsInternal内部的配置(可写访问)。
4️⃣ 功能总结
| 方法 | 返回值类型 | 功能 | 典型用途 |
|---|---|---|---|
Get() |
const OptsInternal& |
只读访问内部配置 | 打印、传递参数 |
Set() |
OptsInternal& |
读写访问内部配置 | 修改解析后的配置参数 |
5️⃣ 关联的实现背景
在 rpicam-apps 中:
Options负责解析命令行参数 (Parse)。OptsInternal存储实际的参数。Get()被rpicam-hello,rpicam-still等应用用来读取解析后的参数。Set()被某些需要在运行时修改配置的模块使用(如动态调整分辨率或模型路径)。
✅ 总结:
Get() 通过 std::unique_ptr<OptsInternal>::get() 实现,它只是一个访问器,返回内部参数的只读引用,不会创建新对象,也不会复制数据。
好的,我查阅了 rpicam-apps 官方源代码与文档,结合 Options(内部为 OptsInternal)在 options.cpp 中的定义和 rpicam-hello、rpicam-vid 等应用中的用法,总结了常用参数、配置方式及调用场景。
🛠️ 内部结构及参数映射
在 options.cpp 中,OptsInternal 定义了 CLI 参数与内部成员变量的一一对应,并由 Parse() 方法从命令行或配置文件中填充这些字段。Get() / Set() 则分别提供只读与读写访问接口 ([GitHub][1])。
🔑 常见重要参数说明
| 参数名 | 类型 | 功能说明 |
|---|---|---|
timeout / -t |
整数(毫秒) | 应用运行或预览持续时间,0 表示无限运行 |
width, height |
整数 | 输出图像或视频分辨率 |
framerate |
整数(fps) | 视频录制帧率 |
codec |
字符串 | 编码格式,支持 h264, mjpeg, libav 等 |
lores-width, lores-height |
整数 | 低分辨率子流尺寸(用于检测或分析) |
denoise |
字符串 | ISP 降噪模式,如 cdn_off 表示关闭降噪 |
shutter |
微秒 | 固定曝光时间 |
gain |
浮点数 | 模拟/数字增益设置 |
ev |
浮点数 | 曝光补偿值 |
hflip, vflip, rotation |
布尔 / 整数 | 图像翻转与旋转角度 |
tuning-file |
字符串(路径) | 指定校准文件(如传感器颜色配置) |
此外还有 preview, fullscreen, nopreview, info-text, roi, hdr, contrast, brightness 等参数支持 UI 显示和图像优化控制 ([Waveshare][2], [Cytron Technologies][3])。
🧩 官方 apps 中的使用示例
rpicam-hello
用于测试预览与模式配置:
rpicam-hello --list-cameras
rpicam-hello -t 5000 --width 1640 --height 1232 --mode 1640:1232:12:P \
--hflip --info-text "fps %fps"
--list-cameras:列出传感器及支持模式--mode width:height:bit:packing:选择特定 sensor 模式--hflip/--info-text用于图像水平方向翻转与预览上的文字显示
rpicam-vid
用于视频录制与流式输出:
rpicam-vid -t 10000 --width 1280 --height 720 \
--framerate 120 --codec h264 --level 4.2 \
--denoise cdn_off --nopreview -o output.h264
--framerate设置帧率--level,--denoise,--nopreview用于高性能录制- 支持
--codec libav输出.avi等格式,并可启用--libav-audio等选项 ([Waveshare][2])
rpicam-still / rpicam-jpeg
用于拍摄图片:
rpicam-still -t 2000 --width 4056 --height 3040 -o pic.jpg
rpicam-jpeg --shutter 20000 --gain 1.5 --ev 0.5 -o brighter.jpg
- 控制曝光时间、增益和曝光补偿以生成特定效果图像 ([Waveshare][4], [Waveshare][2])
🚀 在你的代码中如何调用
1. 通过命令行或配置文件加载参数
Options options;
options.Parse(argc, argv);
const auto &opts = options.Get();
2. 用 opts 设置 libcamera 控制参数
camera.configure(opts.width, opts.height, opts.mode);
camera.setControls(opts.shutter, opts.gain, opts.ev);
// 如果需要实时修改:
auto &opts_mut = options.Set();
opts_mut.framerate = 60;
opts_mut.denoise = "cdn_off";
3. 结合应用逻辑使用
例如在 rpicam-hello 的事件循环中:
auto *options = app.GetOptions();
app.OpenCamera();
...
// 根据 opts 构建 Preview 或编码器等
在 rpicam-vid 中:
EncodeBuffer(request, opts.codec, opts.level);
ShowPreview(request, opts.preview ? true : false);
参数直接来自 OptsInternal,保证一致性与可复用性 ([reddit.com][5], [GitHub][6])。
✅ 总结
OptsInternal包含了命令行及配置文件中定义的所有参数。Parse()填充这些字段,Get()/Set()管理访问权限。- 你可以通过命令行演示或者配置文件灵活控制这些参数。
- 在程序中直接使用
Get()获取参数,或调用Set()动态修改。 - 应用层(如
rpicam-vid,rpicam-still)读取这些配置后,调用 libcamera 接口完成拍摄、编码、预览功能。
如果你能提供你项目里选定的 OptsInternal 定义或你专注的应用模块(如 detect 或 track),我可以进一步帮你对应源码具体字段、调用位置和逻辑流程。
浙公网安备 33010602011771号