如何在 OpenCV Mat 上使用 RealSense 的 spatial_filter?

问题描述

我想在 OpenCV rs2::spatial_filter 上应用实感库的深度过滤 (Mat),但似乎没有应用过滤器。原始深度图像和假设过滤后的深度图像看起来完全一样。

为了将原始深度数据加载到 rs2::frame,我使用了修改后的 @Groch88's answer。我所做的更改之一是将深度格式从 RS2_FORMAT_Z16 更改为 RS2_FORMAT_disTANCE(以便能够加载 float 深度图),而不是加载帧的 RGB 部分。全文来源如下。

为什么原始图像和过滤后的图像看起来完全一样?我是否遗漏了一些明显的东西?

main.cpp:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <librealsense2/rs.hpp>
#include "rsImageConverter.h"

int main()
{
    cv::Mat rawDepthImg = load_raw_depth("/path/to/depth/image"); // loads float depth image
    rsImageConverter ic{rawDepthImg.cols,rawDepthImg.rows,sizeof(float)};

    if ( !ic.convertFrame(rawDepthImg.data,rawDepthImg.data) )
    {
        fprintf(stderr,"Could not load depth.\n");
        exit(1);
    }

    rs2::frame rsDepthFrame = ic.getDepth();

    // Filter
    // https://dev.intelrealsense.com/docs/post-processing-filters
    rs2::spatial_filter spat_filter;
    spat_filter.set_option(RS2_OPTION_FILTER_MAGNITUDE,2.0f);
    spat_filter.set_option(RS2_OPTION_FILTER_SMOOTH_ALPHA,0.5f);
    spat_filter.set_option(RS2_OPTION_FILTER_SMOOTH_DELTA,20.0f);

    // Apply filtering
    rs2::frame rsFilteredDepthFrame;
    rsFilteredDepthFrame = spat_filter.process(rsDepthFrame);

    // copy filtered depth to OpenCV Mat
    cv::Mat filteredDepth = cv::Mat::zeros(rawDepthImg.size(),CV_32F);
    memcpy(filteredDepth.data,rsFilteredDepthFrame.get_data(),rawDepthImg.cols * rawDepthImg.rows * sizeof(float));

    // display (un)filtered images
    cv::imshow("Original depth",rawDepthImg); // Original image is being shown
    cv::imshow("Filtered depth",filteredDepth); // A depth image that looks exactly like the original unfiltered depth map is shown
    cv::imshow("Diff",filteredDepth - rawDepthImg); // A black image is being shown
    cv::waitKey(0);

    return 0;
}

rsImageConverter.h(@Doch88's code 的编辑版本):

#include <librealsense2/rs.hpp>
#include <librealsense2/hpp/rs_internal.hpp>

class rsImageConverter
{
public:
    rsImageConverter(int w,int h,int bppDepth);

    bool convertFrame(uint8_t* depth_data,uint8_t*  color_data);

    rs2::frame getDepth() const;

private:
    int w = 640;
    int h = 480;
    int bppDepth = sizeof(float);

    rs2::software_device dev;
    rs2::software_sensor depth_sensor;
    rs2::stream_profile depth_stream;
    rs2::syncer syncer;

    rs2::frame depth;

    int ind = 0;
};

rsImageConverter.cpp(@Doch88's code 的编辑版本):

#include "rsImageConverter.h"

rsImageConverter::rsImageConverter(int w,int bppDepth) :
        w(w),h(h),bppDepth(bppDepth),depth_sensor(dev.add_sensor("Depth")) // initializing depth sensor
{

    rs2_intrinsics depth_intrinsics{ w,h,(float)(w / 2),(float)(h / 2),(float) w,(float) h,RS2_disTORTION_broWN_CONRADY,{ 0,0 } };
    depth_stream = depth_sensor.add_video_stream({  RS2_STREAM_DEPTH,w,60,bppDepth,RS2_FORMAT_disTANCE,depth_intrinsics });
    depth_sensor.add_read_only_option(RS2_OPTION_DEPTH_UNITS,1.f); // setting depth units option to the virtual sensor

    depth_sensor.open(depth_stream);
    depth_sensor.start(syncer);
}

bool rsImageConverter::convertFrame(uint8_t*  depth_data,uint8_t*  color_data)
{
    depth_sensor.on_video_frame({ depth_data,// Frame pixels
                                  [](void*) {},// Custom deleter (if required)
                                  w*bppDepth,// Stride and Bytes-per-pixel
                                  (rs2_time_t)ind * 16,RS2_TIMESTAMP_DOMAIN_HARDWARE_CLOCK,ind,// Timestamp,Frame# for potential sync services
                                  depth_stream });

    ind++;

    rs2::frameset fset = syncer.wait_for_frames();
    depth = fset.first_or_default(RS2_STREAM_DEPTH);

    return depth;
}

rs2::frame rsImageConverter::getDepth() const
{
    return depth;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)