3. 相机参数配置基础
在 pylon 工程中,相机参数配置的本质是围绕 GenICam 节点树进行读写。相机内部并不是一组孤立的“设置项”,而是一棵由功能组、类别节点和叶子节点构成的树。曝光时间、增益、伽马、像素格式分别对应不同的节点路径,理解这些路径和节点类型,才能写出稳定、可复用的配置代码。
GenICam 节点树与访问入口
pylon 通过 Pylon::CInstantCamera 暴露节点访问接口。典型入口是 GetNodeMap(),它返回相机根节点映射;对于流通道相关参数,则使用 GetStreamGrabberNodeMap()。节点分为整数节点、浮点节点、枚举节点、布尔节点和命令节点。曝光时间通常是浮点节点,增益可能是浮点或整数节点,伽马是浮点节点,像素格式是枚举节点。
访问节点时,推荐使用 GenApi::CIntegerPtr、CFloatPtr、CEnumerationPtr 等智能指针,并通过 IsReadable()、IsWritable() 判断可访问性。直接使用 GetNode("ExposureTime") 并强制转换虽然可行,但缺少类型检查,容易在相机型号切换时崩溃。
曝光时间与增益的读写
曝光时间节点通常名为 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。
参数配置检查表
| 参数 | 节点名 | 节点类型 | 典型范围/取值 | 注意事项 |
|---|---|---|---|---|
| 曝光时间 | ExposureTime | CFloatPtr | 20~1000000 µs | 先读 Min/Max,避免越界 |
| 增益 | Gain | CFloatPtr / CIntegerPtr | 0~24 dB | 优先曝光,增益放大噪声 |
| 伽马 | Gamma | CFloatPtr | 0.1~4.0 | 需先使能 GammaEnable |
| 像素格式 | PixelFormat | CEnumerationPtr | Mono8 / BayerRG8 / RGB8Packed | 切换后重读 PayloadSize |
camera.GetNodeMap().GetNode("TLParamsLocked") 检查是否处于锁定状态。若相机正在采集,部分参数不可写,应先 StopGrabbing(),配置完成后再 StartGrabbing()。ExposureTimeAbs 或 GainRaw 等旧名称。工程代码中应封装节点查找函数,先尝试标准名,再回退到兼容名,并记录实际使用的节点路径。完成上述配置后,可通过 GetValue() 回读确认写入生效。例如曝光时间写入 5000 µs 后,回读值应在 5000 附近;像素格式写入 Mono8 后,回读枚举字符串应为 "Mono8"。若回读值与写入值不一致,通常说明节点被自动模式覆盖或写入未成功,应检查 ExposureAuto、GainAuto 是否处于 Continuous 状态。