你问的 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_ptrget() 方法,返回一个 原始指针 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-hellorpicam-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])。


✅ 总结

  1. OptsInternal 包含了命令行及配置文件中定义的所有参数。
  2. Parse() 填充这些字段,Get()/Set() 管理访问权限。
  3. 你可以通过命令行演示或者配置文件灵活控制这些参数。
  4. 在程序中直接使用 Get() 获取参数,或调用 Set() 动态修改。
  5. 应用层(如 rpicam-vid, rpicam-still)读取这些配置后,调用 libcamera 接口完成拍摄、编码、预览功能。

如果你能提供你项目里选定的 OptsInternal 定义或你专注的应用模块(如 detect 或 track),我可以进一步帮你对应源码具体字段、调用位置和逻辑流程。