1. 后处理滤波简介
Filter(滤波器)是 OrbbecSDK v2 提供的后处理模块,用于对传感器输出的原始帧进行处理,常见用途包括:
• 去除深度图中的噪声和空洞
• 对深度图进行空间/时序平滑
• 对图像进行下采样,降低分辨率以减少数据量、提升后续处理性能
• 将深度流与彩色流进行软件方式对齐
• 转换帧的像素格式
• 生成点云数据
注意:Filter 不只针对深度流(Depth),部分 Filter 适用于彩色流(Color)或红外流(IR),使用时请注意各 Filter 的适用流类型。
| 方式 | 说明 | 适用场景 |
| 直接创建 Filter | 明确指定要使用哪个 Filter,自行设置参数 | 需要精细控制,定制化场景 |
| 推荐 Filter 列表 | 通过指定 Sensor 获取,SDK 针对该 Sensor 的流类型返回推荐的 Filter 组合,只能处理对应流类型的帧 | 快速集成,通用场景 |
提示:不确定设备支持哪种?不确定选哪种?建议先从“推荐 Filter 列表”入手,能快速跑通;需要定制时再使用“直接创建”。
| Filter 名称 | 适用流 | 用途简介 | 类型 |
| PointCloudFilter | Depth / Depth+Color | 将深度帧转换为 XYZ 点云,或将深度+彩色帧转换为 RGBD 点云(XYZ+RGB) | 变换类 |
| Align | Depth + Color | 通过软件方式将深度流与彩色流进行空间对齐 | 变换类 |
| FormatConvertFilter | Color / IR | 像素格式转换(如 MJPG→RGB、YUYV→BGR 等) | 变换类 |
| DisparityTransform | Depth | 深度图与视差图之间的互相转换 | 变换类 |
| SequenceIdFilter | Depth / IR | 按帧序列号筛选,配合 HDR 使用 | 流控类 |
| DecimationFilter | Depth / IR / Color | 对图像进行降采样,缩小分辨率 | 采样/阈值类 |
| ThresholdFilter | Depth | 将超出指定距离范围的深度值置零 | 采样/阈值类 |
| NoiseRemovalFilter | Depth | 去除深度图中的噪声(基础版) | 降噪类 |
| FalsePositiveFilter | Depth | 去除深度图中的各种噪声(高级版) | 降噪类 |
| SpatialAdvancedFilter | Depth | 边缘保持型空间平滑,效果好 | 空间平滑类 |
| SpatialFastFilter | Depth | 快速空间平滑,CPU 占用低 | 空间平滑类 |
| SpatialModerateFilter | Depth | 均衡速度与质量的空间平滑 | 空间平滑类 |
| HoleFillingFilter | Depth | 填充深度图中的空洞 | 空间平滑类 |
| TemporalFilter | Depth | 融合相邻帧数据,时序平滑 | 时序平滑类 |
注意:NoiseRemovalFilter在SDK内部自动调用,仅可控制使能或调节相关参数,不可单独创建。其他所有 Filter 均为公开类型,无需激活码,直接创建即可使用。
同步处理(推荐,适合大多数场景)
auto outFrame = filter->process(inFrame);
if(outFrame) {
// 使用处理后的帧
}
异步处理(适合高帧率或流水线场景)
// 设置回调,处理完成后自动触发
filter->setCallBack([](std::shared_ptr<ob::Frame> outFrame) {
if(outFrame) {
// 使用处理后的帧
}
});
// 将帧推入 Filter 的处理队列
filter->pushFrame(inFrame);
注意:`process()` 在某些情况下会返回 `nullptr`,调用后必须判断返回值是否为空再使用。
2. Filter 类型详细说明
2.1 变换类
PointCloudFilter
适用流:Depth(生成 XYZ 点云);Depth + Color(生成 RGBD 点云,要求 Depth 与 Color 已完成对齐(D2C),否则颜色映射会错误)
功能:将深度帧转换为 XYZ 点云(OB_FORMAT_POINT),或将对齐后的深度+彩色帧转换为 RGBD 点云(OB_FORMAT_RGB_POINT,每个点包含 XYZ 坐标和 RGB 颜色)
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| pointFormat | OBFormat | OB_FORMAT_POINT / OB_FORMAT_RGB_POINT |
OB_FORMAT_POINT |
点云格式 |
| decimate | int | 1 ~ 8 | 1 | 点云抽稀系数,>1 时对输出点云降采样 |
示例一:XYZ 点云
auto pointCloudFilter = std::make_shared<ob::PointCloudFilter>();
pointCloudFilter->setCreatePointFormat(OB_FORMAT_POINT);
pointCloudFilter->setCoordinateDataScaled(1.0f);
// 可传入单独的 Depth 帧,或包含 Depth 帧的 FrameSet
auto pointCloudFrame = pointCloudFilter->process(depthFrame);
if(pointCloudFrame) {
auto points = pointCloudFrame->as<ob::PointsFrame>();
// 使用点云数据 ...
}
示例二:RGBD 点云
生成 RGBD 点云需要深度帧与彩色帧完成空间对齐后,才能传入 PointCloudFilter。对齐方式有两种,优先使用硬件 D2C(性能更优),若使用的分辨率不支持硬件 D2C 则可使用软件 Align Filter。
方式 1:硬件 D2C 对齐(推荐,分辨率支持时优先使用)
auto pointCloudFilter = std::make_shared<ob::PointCloudFilter>();
pointCloudFilter->setCreatePointFormat(OB_FORMAT_RGB_POINT);
// 在 Config 中开启硬件 D2C,Pipeline 输出的 FrameSet 已完成对齐
std::shared_ptr<ob::Config> config = std::make_shared<ob::Config>();
config->enableVideoStream(OB_STREAM_DEPTH);
config->enableVideoStream(OB_STREAM_COLOR);
config->setAlignMode(ALIGN_D2C_HW_MODE);
pipe.start(config);
auto frameSet = pipe.waitForFrameset(100);
auto rgbdPointCloudFrame = pointCloudFilter->process(frameSet);
if(rgbdPointCloudFrame) {
auto points = rgbdPointCloudFrame->as<ob::PointsFrame>();
// 每个点包含 XYZ 坐标与 RGB 颜色 ...
}
方式 2:软件 Align Filter 对齐(使用分辨率不支持硬件 D2C 时使用)
auto pointCloudFilter = std::make_shared<ob::PointCloudFilter>();
pointCloudFilter->setCreatePointFormat(OB_FORMAT_RGB_POINT);
auto alignFilter = std::make_shared<ob::Align>(OB_STREAM_COLOR);
// frameSet 来自 Pipeline(需同时开启 Depth 和 Color 流)
auto frameSet = pipe.waitForFrameset(100);
auto alignedFrameSet = alignFilter->process(frameSet); // 软件对齐后的 FrameSet
auto rgbdPointCloudFrame = pointCloudFilter->process(alignedFrameSet);
if(rgbdPointCloudFrame) {
auto points = rgbdPointCloudFrame->as<ob::PointsFrame>();
// 每个点包含 XYZ 坐标与 RGB 颜色 ...
}
Align
适用流:Depth + Color。功能:通过软件计算的方式对两路流进行空间对齐,消除深度图与彩色图之间的视差偏移。与硬件 D2C 对齐不同,Align Filter 在 CPU 上完成对齐运算,无需硬件支持,灵活性更高但有一定性能开销。若设备支持硬件 D2C 对齐,建议优先使用硬件 D2C,性能更优。
| 参数名 | 类型 | 说明 |
| AlignType | OBStreamType | 对齐目标流类型:OB_STREAM_COLOR(深度对齐到彩色,D2C)、OB_STREAM_DEPTH(彩色对齐到深度,C2D) |
// 创建时指定对齐目标(深度对齐到彩色)
auto alignFilter = std::make_shared<ob::Align>(OB_STREAM_COLOR);
// 确保 FrameSet 中 Depth 和 Color 帧都存在
auto depthFrame = frameSet->getFrame(OB_FRAME_DEPTH);
auto colorFrame = frameSet->getFrame(OB_FRAME_COLOR);
if(!depthFrame || !colorFrame) {
// Depth 或 Color 帧缺失,无法执行对齐
continue;
}
// 处理 FrameSet
auto alignedFrameSet = alignFilter->process(frameSet);
if(alignedFrameSet) {
auto alignedDepth = alignedFrameSet->as<ob::FrameSet>()->getFrame(OB_FRAME_DEPTH);
}
FormatConvertFilter
适用流:Color(YUYV/MJPG/NV12/NV21 等转 RGB/BGR);IR(Y16 转 RGB 等)。功能:将帧的像素格式从一种转换为另一种,常用于将相机输出的原始格式转为 OpenCV 可直接使用的格式。
| 枚举值 | 说明 |
| FORMAT_YUYV_TO_RGB | YUYV → RGB |
| FORMAT_MJPG_TO_RGB | MJPG → RGB |
| FORMAT_MJPG_TO_BGR | MJPG → BGR |
| FORMAT_MJPG_TO_NV21 | MJPG → NV21 |
| FORMAT_MJPG_TO_NV12 | MJPG → NV12 |
| FORMAT_NV12_TO_RGB | NV12 → RGB |
| FORMAT_NV21_TO_RGB | NV21 → RGB |
| FORMAT_RGB_TO_BGR | RGB → BGR |
| FORMAT_Y16_TO_RGB | Y16(IR)→ RGB |
auto formatConvertFilter = std::make_shared<ob::FormatConvertFilter>();
formatConvertFilter->setFormatConvertType(FORMAT_MJPG_TO_RGB);
auto rgbFrame = formatConvertFilter->process(colorFrame);
if(rgbFrame) {
// rgbFrame 现在是 RGB 格式,可直接用于 OpenCV 显示
}
DisparityTransform
适用流:Depth。功能:将视差图转为深度图。相机默认输出的是深度数据,仅当用户切换到了视差格式数据,且需要转换为深度格式数据时才会用到。
注意:(1)ThresholdFilter 等深度滤波器仅对 Depth(单位 mm)有效;(2)若输入为 Disparity,需先通过 DisparityTransform 转换,否则滤波结果无效。
auto disparityTransform = std::make_shared<ob::DisparityTransform>(); auto depthFrame = disparityTransform->process(disparityFrame);
2.2 流控类
SequenceIdFilter
适用流:Depth / IR。功能:从 FrameSet 中筛选出指定序列号的帧,配合 HDR 使用。仅在关闭 HDR Merge Filter 时生效。selectSequenceId(0) 表示全部通过不过滤;selectSequenceId(1) 只保留序列号为 1 的帧。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| sequenceid | int | -1 ~ 1 | 0 | 要保留的帧序列号,0 表示全部通过 |
auto seqFilter = std::make_shared<ob::SequenceIdFilter>(); seqFilter->selectSequenceId(1); // 只保留序列号为 1 的帧 auto filteredFrame = seqFilter->process(frameSet);
2.3 采样 / 阈值类
DecimationFilter
适用流:Depth / IR / Color。功能:对图像按指定倍数进行降采样,减小图像分辨率,降低后续处理的计算量。但是采样率越高细节损失也越多。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| decimate | uint8 | 1 ~ 8 | 2 | 降采样倍数,例如 2 表示分辨率缩小为原来的 1/2 |
auto decimationFilter = std::make_shared<ob::DecimationFilter>(); // 查询支持的倍数范围 auto scaleRange = decimationFilter->getScaleRange(); std::cout << "scale range: " << (int)scaleRange.min << " ~ " << (int)scaleRange.max << std::endl; decimationFilter->setScaleValue(2); // 分辨率缩小为原来的 1/2 auto outFrame = decimationFilter->process(depthFrame);
注意:降采样后帧的分辨率会发生变化,后续 Filter 或算法需注意适配新分辨率。
1/2 降采样前后的深度效果如下:

ThresholdFilter
适用流:Depth。功能:将深度值不在指定范围 [min, max](单位:mm)内的像素置零,用于过滤过近或过远的无效深度值。仅对 Depth 数据(mm)有效,对 Disparity 数据无效。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| min | uint32 | 0 ~ 16000 | 0 | 最小有效深度值(mm) |
| max | uint32 | 0 ~ 16000 | 16000 | 最大有效深度值(mm) |
auto thresholdFilter = std::make_shared<ob::ThresholdFilter>(); // 查询支持的范围 auto minRange = thresholdFilter->getMinRange(); auto maxRange = thresholdFilter->getMaxRange(); // 只保留 300mm~3000mm 范围内的深度值 thresholdFilter->setValueRange(300, 3000); auto outFrame = thresholdFilter->process(depthFrame);
2.4 降噪类
NoiseRemovalFilter
适用流:Depth。功能:对深度图进行聚类处理,识别出噪声区域并将其滤除。作为运行在SDK内部的基础去噪滤波器,一般设备都会默认开启,无需用户自己创建,建议在”推荐Filter列表“处设置使能状态与调参。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| min_diff | uint16 | 1 ~ 51200 | 256 | 深度空间滤波范围,值越大去噪效果越弱(保留更多细节),值越小去噪越强 |
| max_size | uint16 | 1 ~ 1000 | 80 | 噪声块的最大像素面积,值越大去噪越激进(滤除更大的噪声块),但深度填充率会降低 |
开启NoiseRemovalFilter前后的深度效果如下:


FalsePositiveFilter
适用流:Depth。功能:滤除深度图中的错误深度值(鬼影噪声)。该滤波器在功能上覆盖了NoiseRemovalFilter,对平台资源消耗也更高。因此在开启FalsePositiveFilter时建议同时关闭NoiseRemovalFilter。
由于该滤波器参数过多,在单独创建该滤波器时,用户难以传入所有参数。因此仅支持通过 filter->enable(bool) 启用或禁用,无需设置其他参数。强烈建议使用”推荐 Filter 列表“的调用方式。
auto fpFilter = std::make_shared<ob::FalsePositiveFilter>(); // 启用滤波器 fpFilter->enable(true); auto outFrame = fpFilter->process(depthFrame);
该滤波器由三个子滤波器组成,分别针对三种细分场景下的噪声进行滤除。由于滤波过程可能产生误判而去除正常深度,每个子滤波器都开放了 ROI 参数,用于精确控制滤波作用区域,避免误伤有效深度,用户可按需调整ROI范围。
FalsePositiveFilter::EdgeBleedFilter
功能:滤除物体边缘横向延伸的错误深度。典型场景:半室外窗户边缘、室外过曝天空等。判断规则:在深度图 ROI 区域内,当水平方向上有连续超过 fpebfMinBleedLength 个像素的深度值完全相同时,该区域将被判定为边缘误生长噪声并予以滤除。例如:设置 fpebfMinBleedLength = 40,即连续 40 个以上像素深度值完全相同时触发滤波。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| fpEdgeBleedFilterEnable | bool | 0 ~ 1 | 0 | 边缘误生长滤波开关 |
| fpebfROIMinXRatio | float | 0.0 ~ 1.0 | 0.0 | ROI 左边界(占图像宽度的比例,0.0表示最左侧) |
| fpebfROIMaxXRatio | float | 0.0 ~ 1.0 | 1.0 | ROI 右边界(占图像宽度的比例,1.0表示最右侧) |
| fpebfROIMinYRatio | float | 0.0 ~ 1.0 | 0.0 | ROI 上边界(占图像高度的比例,0.0表示最顶部) |
| fpebfROIMaxYRatio | float | 0.0 ~ 1.0 | 0.6 | ROI 下边界(占图像高度的比例,1.0表示最底部) |
| fpebfMinBleedLength | int | 1 ~ 256 | 40 | 最小连续生长长度(像素),连续深度值相同的像素数超过此阈值时触发滤波 |
开启EdgeBleedFilter前后深度效果如下(横向延伸噪声已被滤除):

在近距离处深度值更接近,拍摄平面场景时容易误判产生深度横向缺失:

FalsePositiveFilter::TextureSparsityFilter
功能:滤除弱纹理场景产生的错误深度。典型场景:室外白墙、不过曝天空等区域。判断规则:在深度图ROI 区域内,同时满足以下两个条件的噪声区域将被滤除:
- 噪声区域的平均深度值 < fptsfMaxNoiseLevel
- 噪声块的像素面积 < fptsfMaxSpeckleSize
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| fpTextureSparsityFilterEnable | bool | 0 ~ 1 | 0 | 弱纹理滤波开关 |
| fptsfROIMinXRatio | float | 0.0 ~ 1.0 | 0.0 | ROI 左边界(占图像宽度的比例,0.0表示最左侧) |
| fptsfROIMaxXRatio | float | 0.0 ~ 1.0 | 1.0 | ROI 右边界(占图像宽度的比例,1.0表示最右侧) |
| fptsfROIMinYRatio | float | 0.0 ~ 1.0 | 0.0 | ROI 上边界(占图像高度的比例,0.0表示最顶部) |
| fptsfROIMaxYRatio | float | 0.0 ~ 1.0 | 0.45 | ROI 下边界(占图像高度的比例,1.0表示最底部) |
| fptsfMaxNoiseLevel | int | 1 ~ 65535 | 6000 | 噪声最大深度值(mm),仅去除深度小于此值的噪声 |
| fptsfMaxSpeckleSize | int | 1 ~ 65535 | 1300 | 噪声块最大像素面积,仅去除面积小于此值的噪声块 |
开启 TextureSparsityFilter 前后的深度效果(天空中的噪声已被滤除):

FalsePositiveFilter::PatternAmbiguityFilter
功能:滤除重复纹理场景产生的错误深度。典型场景:栅栏、建筑物窗户等区域。判断规则:
在深度图 ROI 区域内,同时满足以下全部条件的噪声区域将被滤除:
- 噪声区域平均深度值 < fppafMaxNoiseLevel
- 噪声块面积 < fppafMaxSpeckleSize
- 噪声块宽度 < 图像宽度 × fppafMaxWidthRatio
- 噪声块高度 < 图像高度 × fppafMaxHeightRatio
- 噪声的 Tolerance 特征 > fppafTolerance
- 噪声的 Score 特征 > fppafScore
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| fpPatternAmbiguityFilterEnable | bool | 0 ~ 1 | 0 | 重复纹理滤波开关 |
| fppafROIMinXRatio | float | 0.0 ~ 1.0 | 0.0 | ROI 左边界(占图像宽度的比例,0.0表示最左侧) |
| fppafROIMaxXRatio | float | 0.0 ~ 1.0 | 0.99 | ROI 右边界(占图像宽度的比例,1.0表示最右侧) |
| fppafROIMinYRatio | float | 0.0 ~ 1.0 | 0.0 | ROI 上边界(占图像高度的比例,0.0表示最顶部) |
| fppafROIMaxYRatio | float | 0.0 ~ 1.0 | 0.9 | ROI 下边界(占图像高度的比例,1.0表示最底部) |
| fppafMaxNoiseLevel | int | 1 ~ 65535 | 6000 | 噪声最大深度值(mm),仅去除深度小于此值的噪声 |
| fppafMaxSpeckleSize | int | 1 ~ 65535 | 4000 | 噪声块最大像素面积,仅去除面积小于此值的噪声块 |
| fppafMaxWidthRatio | float | 0.0 ~ 1.0 | 0.3 | 噪声块最大宽度占图像宽度的比例 |
| fppafMaxHeightRatio | float | 0.0 ~ 1.0 | 0.3 | 噪声块最大高度占图像高度的比例 |
| fppafTolerance | float | 0.0 ~ 1.0 | 0.15 | 噪声容忍度特征阈值,仅当噪声的 Tolerance > 该值时滤除 |
| fppafScore | int | 1 ~ 65535 | 50 | 噪声评分阈值,仅当噪声的 Score > 该值时滤除 |
开启 PatternAmbiguityFilter 前后深度效果(建筑物外墙因重复纹理产生的噪声已被滤除)

FalsePositiveFilter调参指引:
| 参数名 | 子滤波器 | 抑制噪声时的调节方向 |
| fpebfMinBleedLength | EdgeBleedFilter | ↓ 调小以更积极滤除 |
| fptsfMaxNoiseLevel | TextureSparsityFilter | ↑ 调大以覆盖更远噪声 |
| fptsfMaxSpeckleSize | TextureSparsityFilter | ↑ 调大以滤除更大噪声块 |
| fppafMaxNoiseLevel | PatternAmbiguityFilter | ↑ 调大以覆盖更远噪声 |
| fppafMaxSpeckleSize | PatternAmbiguityFilter | ↑ 调大以滤除更大噪声块 |
| fppafMaxWidthRatio | PatternAmbiguityFilter | ↑ 调大以滤除宽度跨度更大的噪声块 |
| fppafMaxHeightRatio | PatternAmbiguityFilter | ↑ 调大以滤除高度跨度更大的噪声块 |
| fppafTolerance | PatternAmbiguityFilter | ↓ 调小以更积极滤除 |
| fppafScore | PatternAmbiguityFilter | ↓ 调小以更积极滤除 |
2.5. 空间平滑类
SpatialAdvancedFilter
适用流:Depth。功能:边缘保持型空间平滑。通过 alpha 和 disp_diff 参数控制平滑强度与边缘保护,在平坦区域平滑深度值的同时保留物体边缘,是深度图空间平滑的首选,但资源占用也最高。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| alpha | float | 0.1 ~ 1 | 0.5 | 当前像素权重,值越大平滑效果越弱(保留原始值),调节步长为0.01 |
| disp_diff | uint16 | 1 ~ 10000 | 160 | 深度梯度阈值,超过此值的像素不参与平滑(保护边缘) |
| radius | uint16 | 0 ~ 8 | 1 | 平滑半径,影响平滑范围 |
| magnitude | int | 1 ~ 5 | 1 | 迭代次数,次数越多平滑效果越强 |
auto spatialFilter = std::make_shared<ob::SpatialAdvancedFilter>(); // 获取当前参数(包含默认值) auto params = spatialFilter->getFilterParams(); // 按需修改参数 params.alpha = 0.5f; params.disp_diff = 160; params.radius = 2; params.magnitude = 1; spatialFilter->setFilterParams(params); auto outFrame = spatialFilter->process(depthFrame);
SpatialFastFilter
适用流:Depth。功能:基于增强中值平滑算法的快速空间滤波,CPU 占用低,适合对性能敏感的场景。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| radius | uint8 | 3 ~ 5 | 3 | 平滑半径,值越大平滑范围越广,调节步长为2,即取 3 或 5 |
auto spatialFastFilter = std::make_shared<ob::SpatialFastFilter>(); // 获取当前参数(包含默认值) auto params = spatialFastFilter->getFilterParams(); // 按需修改参数 params.radius = 2; spatialFastFilter->setFilterParams(params); auto outFrame = spatialFastFilter->process(depthFrame);
SpatialModerateFilter
适用流:Depth。功能:基于优化均值平滑算法,在处理速度与平滑质量之间取得平衡。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| magnitude | uint8 | 1 ~ 3 | 1 | 迭代次数,次数越多平滑越强 |
| radius | uint8 | 3 ~ 7 | 5 | 平滑半径,调节步长为2,即取 3、5 或 7 |
| disp_diff | uint16 | 1 ~ 10000 | 160 | 深度梯度阈值,超过此值不参与平滑(保护边缘) |
auto spatialModFilter = std::make_shared<ob::SpatialModerateFilter>(); // 获取当前参数(包含默认值) auto params = spatialModFilter->getFilterParams(); // 按需修改参数 params.magnitude = 2; params.radius = 2; params.disp_diff = 64; spatialModFilter->setFilterParams(params); auto outFrame = spatialModFilter->process(depthFrame);
HoleFillingFilter
适用流:Depth。功能:填充深度图中值为 0 的空洞像素,填充值来源取决于所选模式。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 | |
| hole_filling_mode | OBHoleFillingMode | 0 ~ 2 | 0(TOP) | 填充模式(见下表) | |
| 枚举值 | 说明 | ||||
| OB_HOLE_FILL_TOP | 用空洞正上方最近的有效深度值填充 | ||||
| OB_HOLE_FILL_NEAREST | 用周围最近的有效深度值填充 | ||||
| OB_HOLE_FILL_FAREST | 用周围最远的有效深度值填充 | ||||
auto holeFillingFilter = std::make_shared<ob::HoleFillingFilter>(); holeFillingFilter->setFilterMode(OB_HOLE_FILL_TOP); auto outFrame = holeFillingFilter->process(depthFrame);
该滤波器会填充所有空洞,可能引入虚假数据,一般不推荐使用。但在需要完整深度的特殊场景下,可自行开启,并使用推荐的OB_HOLE_FILL_FAREST 模式。
HoleFillingFilter开启前后的深度效果(深度为零的区域已被填充)如下:


2.6 时序平滑类
TemporalFilter
适用流:Depth。功能:融合当前帧与历史帧的深度数据进行时序平滑,有效抑制帧间抖动噪声。
| 参数名 | 类型 | 取值范围 | 默认值 | 说明 |
| diff_scale | float | 0.1 ~ 1 | 0.1 | 允许的深度变化比例阈值,超过此比例的像素不参与融合,调节步长为0.01 |
| weight | float | 0.1 ~ 1 | 0.4 | 当前帧的融合权重,值越大越偏向原始数据(平滑弱),值越小平滑越强,调节步长为0.01 |
auto temporalFilter = std::make_shared<ob::TemporalFilter>();
// 查询参数允许范围
auto diffScaleRange = temporalFilter->getDiffScaleRange();
auto weightRange = temporalFilter->getWeightRange();
// 按需设置参数(在允许范围内)
temporalFilter->setDiffScale(0.1f); // 范围:[diffScaleRange.min, diffScaleRange.max]
temporalFilter->setWeight(0.4f); // 范围:[weightRange.min, weightRange.max]
auto outFrame = temporalFilter->process(depthFrame);
// 注意:前几帧历史数据不足时,process() 可能返回 nullptr,需判断
if(outFrame) {
// 使用处理后的帧
}
3.快速创建一个后处理滤波
以 ThresholdFilter 为例,3 步完成一次后处理:
#include <libobsensor/ObSensor.hpp>
// 第 1 步:创建 Filter
auto thresholdFilter = std::make_shared<ob::ThresholdFilter>();
// 第 2 步:设置参数(只保留 300mm~3000mm 范围内的深度值)
thresholdFilter->setValueRange(300, 3000);
// 第 3 步:处理帧(depthFrame 来自 Pipeline 获取的 FrameSet)
auto outFrame = thresholdFilter->process(depthFrame);
if(outFrame) {
auto processedDepth = outFrame->as<ob::DepthFrame>();
// 使用 processedDepth ...
}
多个 Filter 可以依次串联,将上一个 Filter 的输出作为下一个 Filter 的输入。
串联顺序(深度流)
格式转换(FormatConvertFilter) → 降采样(DecimationFilter) → 序列筛选(SequenceIdFilter) → 阈值过滤(ThresholdFilter) → 降噪(EdgeNoiseRemovalFilter/FalsePositiveFilter/ MgcNoiseRemovalFilter/LutNoiseRemovalFilter) → 空间平滑(SpatialAdvancedFilter/SpatialFastFilter/ SpatialModerateFilter) → 时序平滑(TemporalFilter) → 填孔(HoleFillingFilter) → 软件对齐(Align) → 点云(PointCloudFilter)
注意:斜杠(/)表示同一阶段可选其一,根据设备型号和场景需求选择。使用时保持各 Filter 的相对顺序不变,调整顺序可能产生非预期的效果。
代码示例(以阈值过滤 → 降噪 → 空间平滑 → 软件对齐 → 点云为例):
auto thresholdFilter = std::make_shared<ob::ThresholdFilter>();
thresholdFilter->setValueRange(300, 3000);
thresholdFilter->enable(true);
auto edgeFilter = std::make_shared<ob::EdgeNoiseRemovalFilter>();
edgeFilter->enable(true);
auto spatialFilter = std::make_shared<ob::SpatialAdvancedFilter>();
spatialFilter->enable(true);
auto alignFilter = std::make_shared<ob::Align>(OB_STREAM_COLOR);
alignFilter->enable(true);
auto pointCloudFilter = std::make_shared<ob::PointCloudFilter>();
pointCloudFilter->setCreatePointFormat(OB_FORMAT_RGB_POINT);
pointCloudFilter->enable(true);
// 每帧处理应在独立线程中进行,不要在获取帧数据的线程或回调线程中直接调用
if(!frameSet) return;
auto depthFrame = frameSet->getFrame(OB_FRAME_DEPTH);
auto colorFrame = frameSet->getFrame(OB_FRAME_COLOR);
if(!depthFrame || !colorFrame) return;
std::shared_ptr<ob::Frame> outFrame = frameSet;
for(auto &filter : std::vector<std::shared_ptr<ob::Filter>>{
thresholdFilter, edgeFilter, spatialFilter,
alignFilter, pointCloudFilter}) {
if(outFrame) {
outFrame = filter->process(outFrame);
}
}
// outFrame 是经过完整处理链后的点云帧
// 关闭 Filter filter->enable(false); // 开启 Filter filter->enable(true); // 查询当前是否启用 bool enabled = filter->isEnabled();
4.推荐后处理滤波列表
#include <libobsensor/ObSensor.hpp>
ob::Pipeline pipe;
auto device = pipe.getDevice();
// 第 1 步:获取目标 Sensor(以深度流为例)
auto sensor = device->getSensor(OB_SENSOR_DEPTH);
// 第 2 步:获取推荐 Filter 列表
auto filters = sensor->createRecommendedFilters();
// 第 3 步:检查是否有推荐 Filter
if(filters.empty()) {
std::cout << "该 Sensor 不支持推荐后处理,直接使用原始帧即可。" << std::endl;
return 0;
}
// 第 4 步:查看各 Filter 的初始启用状态
for(auto &filter : filters) {
std::cout << filter->getName()
<< " : " << (filter->isEnabled() ? "enabled" : "disabled")
<< std::endl;
}
// 第 5 步:启动数据流
std::shared_ptr<ob::Config> config = std::make_shared<ob::Config>();
config->enableVideoStream(OB_STREAM_DEPTH);
pipe.start(config);
while(true) {
auto frameSet = pipe.waitForFrameset(100);
if(!frameSet) continue;
auto depthFrame = frameSet->getFrame(OB_FRAME_DEPTH);
if(!depthFrame) continue;
// 第 6 步:依次应用启用的 Filter
std::shared_ptr<ob::Frame> outFrame = depthFrame;
for(auto &filter : filters) {
if(filter->isEnabled()) {
auto result = filter->process(outFrame);
if(result) outFrame = result;
}
}
// outFrame 是处理后的深度帧
}
注意:推荐 Filter 列表与获取它的 Sensor 流类型绑定,只能处理对应类型的帧。例如从深度 Sensor 获取的推荐列表只能处理深度帧,传入其他类型帧会导致处理失败或返回 `nullptr`。
第一步:查看推荐 Filter 列表
auto filters = sensor->createRecommendedFilters();
std::cout << "推荐 Filter 列表(共 " << filters.size() << " 个):" << std::endl;
for(auto &filter : filters) {
std::cout << " - " << filter->getName()
<< " [" << (filter->isEnabled() ? "enabled" : "disabled") << "]"
<< std::endl;
}
第二步:查看某个 Filter 的可调参数
确定目标 Filter 后,通过 getConfigSchemaVec() 查看它支持哪些参数及其范围、默认值:
| 字段 | 说明 |
| name | 参数名称 |
| type | 参数类型(”int” / “float” / “bool”) |
| min | 最小值 |
| max | 最大值 |
| step | 步长 |
| def | 默认值 |
| desc | 参数描述 |
// 以 TemporalFilter 为例,查看其可调参数
for(auto &filter : filters) {
if(filter->getName() == "TemporalFilter") {
for(auto &item : filter->getConfigSchemaVec()) {
std::cout << " " << item.name
<< " 类型=" << item.type
<< " 范围=[" << item.min << ", " << item.max << "]"
<< " 步长=" << item.step
<< " 默认=" << item.def
<< std::endl;
}
break;
}
}
第三步:读取当前参数值
getConfigSchemaVec() 返回的是参数的静态定义(范围、默认值),getConfigValue() 返回的是当前运行时实际生效的值。
for(auto &filter : filters) {
if(filter->getName() == "TemporalFilter") {
double diffScale = filter->getConfigValue("diff_scale");
double weight = filter->getConfigValue("weight");
std::cout << "diff_scale=" << diffScale
<< " weight=" << weight << std::endl;
break;
}
}
第四步:修改参数
方式一:通用方式(推荐)——适合运行时动态调整,无需关心 Filter 的具体类型:
for(auto &filter : filters) {
if(filter->getName() == "TemporalFilter") {
filter->setConfigValue("diff_scale", 0.1);
filter->setConfigValue("weight", 0.4);
break;
}
}
方式二:强类型方式——用 is<T>() 判断类型,as<T>() 转型为子类,调用专属 API,IDE 有补全:
for(auto &filter : filters) {
if(filter->is<ob::TemporalFilter>()) {
auto temporalFilter = filter->as<ob::TemporalFilter>();
temporalFilter->setDiffScale(0.1f);
temporalFilter->setWeight(0.4f);
}
}
第五步:启用 / 禁用某个 Filter
for(auto &filter : filters) {
if(filter->getName() == "TemporalFilter") {
filter->enable(false); // 临时禁用时序滤波
}
}
注意事项
• 推荐列表中每个 Filter 的参数默认值是 SDK 针对当前连接设备的最优配置,直接使用通常可获得较好效果。
• 如需恢复默认值,重新调用 sensor->createRecommendedFilters() 即可,参数会重置为设备默认值。
注意:推荐 Filter 列表与获取它的 Sensor 流类型绑定,列表中的 Filter 只能处理该 Sensor 对应流类型的帧。请确保传给 Filter 的帧类型与 Sensor 流类型一致。详情请参见 3.1 节注意事项。
不同流类型的 Sensor 返回不同的 Filter 列表:深度 Sensor 返回深度专用 Filter,彩色 Sensor 返回彩色专用 Filter。
// 深度流推荐 Filter auto depthSensor = device->getSensor(OB_SENSOR_DEPTH); auto depthFilters = depthSensor->createRecommendedFilters(); // 彩色流推荐 Filter auto colorSensor = device->getSensor(OB_SENSOR_COLOR); auto colorFilters = colorSensor->createRecommendedFilters();
不同设备型号返回的列表内容也不同。请务必通过 filter->getName() 按名称查找目标 Filter,不要用索引硬编码。
// 正确做法:按名称查找
for(auto &filter : filters) {
if(filter->getName() == "ThresholdFilter") { /* ... */ }
}
// 错误做法:硬编码索引(不同设备顺序可能不同)
// auto thresholdFilter = filters[2]; // 不要这样用
推荐列表为空,说明该 Sensor 的数据流不支持推荐后处理,直接使用原始帧即可。
| 直接创建 Filter | 推荐 Filter 列表 | |
| 上手难度 | 需了解各 Filter 用途和参数 | 无需了解细节,开箱即用 |
| 参数配置 | 手动设置,完全可控 | 设备最优默认值,按需微调 |
| 设备兼容 | 需自行确认当前设备是否支持目标 Filter | SDK 自动只返回当前设备支持的 Filter |
| Filter 选择 | 完全自主选择 | 由 SDK 根据设备型号决定 |
| 默认参数 | 需手动设置合适值 | 已是当前设备的最优配置 |
| 典型场景 | 产品定制、算法调优 | 快速集成、通用 Demo |
选择建议
• 如果你是第一次使用,或者只是想快速看到效果,使用推荐 Filter 列表,几行代码即可跑通。
• 如果你需要选择特定的 Filter 组合,或者对参数有精确要求,使用直接创建 Filter。
• 两种方式可以混合使用:先通过推荐列表了解设备支持哪些 Filter,再按需直接创建并精细调参。