3. 相机参数配置基础

在 pylon 工程中,相机参数配置的本质是围绕 GenICam 节点树进行读写。相机内部并不是一组孤立的“设置项”,而是一棵由功能组、类别节点和叶子节点构成的树。曝光时间、增益、伽马、像素格式分别对应不同的节点路径,理解这些路径和节点类型,才能写出稳定、可复用的配置代码。

GenICam 节点树与访问入口

pylon 通过 Pylon::CInstantCamera 暴露节点访问接口。典型入口是 GetNodeMap(),它返回相机根节点映射;对于流通道相关参数,则使用 GetStreamGrabberNodeMap()。节点分为整数节点、浮点节点、枚举节点、布尔节点和命令节点。曝光时间通常是浮点节点,增益可能是浮点或整数节点,伽马是浮点节点,像素格式是枚举节点。

访问节点时,推荐使用 GenApi::CIntegerPtr、CFloatPtr、CEnumerationPtr 等智能指针,并通过 IsReadable()、IsWritable() 判断可访问性。直接使用 GetNode("ExposureTime") 并强制转换虽然可行,但缺少类型检查,容易在相机型号切换时崩溃。

GenICam 节点树与 pylon 访问路径 Camera NodeMap AcquisitionControl AnalogControl ImageFormatControl ExposureTime CFloatPtr · µs Gain CFloatPtr / CIntegerPtr · dB Gamma CFloatPtr · 0.1~4.0 ExposureAuto CEnumerationPtr GainAuto CEnumerationPtr PixelFormat CEnumerationPtr pylon C++ 访问接口 GetNodeMap().GetNode("ExposureTime") → CFloatPtr SetValue() / GetValue() / GetMin() / GetMax()

曝光时间与增益的读写

曝光时间节点通常名为 ExposureTime,单位微秒。写入前应先读取 GetMin() 和 GetMax(),避免超出相机允许范围。例如某 Basler ace 相机曝光时间范围为 20 µs 到 1000000 µs,若写入 5 µs 会抛出 OutOfRangeException。正确做法是:

GenApi::CFloatPtr ptrExposure = camera.GetNodeMap().GetNode("ExposureTime");
if (ptrExposure.IsValid() && ptrExposure.IsWritable()) {
    double minVal = ptrExposure->GetMin();
    double maxVal = ptrExposure->GetMax();
    double target = 5000.0; // 5000 µs
    if (target >= minVal && target <= maxVal) {
        ptrExposure->SetValue(target);
    }
}

增益节点名为 Gain,单位 dB。部分相机增益以整数寄存器值表示,此时应使用 CIntegerPtr。增益与曝光时间共同决定图像亮度,但增益会放大噪声,因此优先增加曝光时间,在运动场景中再考虑提高增益。

伽马校正

伽马节点名为 Gamma,典型范围 0.1 到 4.0,默认值通常为 1.0。伽马值小于 1 会提亮暗部,大于 1 会压暗暗部。伽马校正作用于相机内部,在像素格式转换之前完成。若使用 GammaEnable 节点,需先将其设为 true,再设置 Gamma 值。

像素格式

像素格式节点名为 PixelFormat,是枚举节点。常见值包括 Mono8、Mono12、BayerRG8、BayerRG12、RGB8Packed、YUV422Packed 等。设置时不能直接写字符串,而应通过枚举项访问:

GenApi::CEnumerationPtr ptrPixelFormat = camera.GetNodeMap().GetNode("PixelFormat");
GenApi::CEnumEntryPtr entry = ptrPixelFormat->GetEntryByName("Mono8");
if (entry.IsValid() && entry->IsAvailable()) {
    ptrPixelFormat->SetIntValue(entry->GetValue());
}

像素格式决定了每像素字节数、是否需要 Bayer 转换以及后续图像处理链路。例如 Mono8 每像素 1 字节,BayerRG8 需要去马赛克,RGB8Packed 每像素 3 字节。切换像素格式后,应重新读取 PayloadSize 和 Width、Height,因为部分相机在改变像素格式时会自动调整 ROI。

参数配置检查表

参数节点名节点类型典型范围/取值注意事项
曝光时间ExposureTimeCFloatPtr20~1000000 µs先读 Min/Max,避免越界
增益GainCFloatPtr / CIntegerPtr0~24 dB优先曝光,增益放大噪声
伽马GammaCFloatPtr0.1~4.0需先使能 GammaEnable
像素格式PixelFormatCEnumerationPtrMono8 / BayerRG8 / RGB8Packed切换后重读 PayloadSize
建议在配置前调用 camera.GetNodeMap().GetNode("TLParamsLocked") 检查是否处于锁定状态。若相机正在采集,部分参数不可写,应先 StopGrabbing(),配置完成后再 StartGrabbing()。
不要依赖节点名称在所有相机型号中完全一致。不同厂商、不同固件版本可能使用 ExposureTimeAbs 或 GainRaw 等旧名称。工程代码中应封装节点查找函数,先尝试标准名,再回退到兼容名,并记录实际使用的节点路径。

完成上述配置后,可通过 GetValue() 回读确认写入生效。例如曝光时间写入 5000 µs 后,回读值应在 5000 附近;像素格式写入 Mono8 后,回读枚举字符串应为 "Mono8"。若回读值与写入值不一致,通常说明节点被自动模式覆盖或写入未成功,应检查 ExposureAuto、GainAuto 是否处于 Continuous 状态。