在 Librealsense SDK 中将 OpenCV Mat 转换为 Realsense 的帧类型
Posted
技术标签:
【中文标题】在 Librealsense SDK 中将 OpenCV Mat 转换为 Realsense 的帧类型【英文标题】:Convert OpenCV Mat to Frame type of Realsense in Librealsense SDK 【发布时间】:2018-10-01 06:52:23 【问题描述】:我有 RGB 数据作为 rs2::frame,我将其转换为 cv::Mat 并通过 TCP 连接发送,在服务器(接收器)端我将缓冲区存储到 cv::Mat 中。我的问题是如何在接收端将 cv::Mat 转换为 rs2::frame,以便使用支持 rs2::frame 类型的 SDK 函数?
【问题讨论】:
【参考方案1】:您需要模拟软件设备才能拥有 rs2::frame。
在this example 之后,您可以编写自己的类来创建合成流,从 cv::Mat 实例中获取数据。
例如,这是我为解决问题所做的一些事情。
rsImageConverter.h
#include <librealsense2/rs.hpp>
#include <librealsense2/hpp/rs_internal.hpp>
class rsImageConverter
public:
rsImageConverter(int w, int h, int bpp);
bool convertFrame(uint8_t* depth_data, uint8_t* color_data);
rs2::frame getDepth() const;
rs2::frame getColor() const;
private:
int w = 640;
int h = 480;
int bpp = 2;
rs2::software_device dev;
rs2::software_sensor depth_sensor;
rs2::software_sensor color_sensor;
rs2::stream_profile depth_stream;
rs2::stream_profile color_stream;
rs2::syncer syncer;
rs2::frame depth;
rs2::frame color;
int ind = 0;
;
rsImageConverter.cpp
#include "rsimageconverter.h"
rsImageConverter::rsImageConverter(int w, int h, int bpp) :
w(w),
h(h),
bpp(bpp),
depth_sensor(dev.add_sensor("Depth")), // initializing depth sensor
color_sensor(dev.add_sensor("Color")) // initializing color sensor
rs2_intrinsics depth_intrinsics w, h, (float)(w / 2), (float)(h / 2), (float) w , (float) h , RS2_DISTORTION_BROWN_CONRADY , 0,0,0,0,0 ;
depth_stream = depth_sensor.add_video_stream( RS2_STREAM_DEPTH, 0, 0,
w, h, 60, bpp,
RS2_FORMAT_Z16, depth_intrinsics );
depth_sensor.add_read_only_option(RS2_OPTION_DEPTH_UNITS, 0.001f); // setting depth units option to the virtual sensor
rs2_intrinsics color_intrinsics = w, h,
(float)w / 2, (float)h / 2,
(float)w / 2, (float)h / 2,
RS2_DISTORTION_BROWN_CONRADY , 0,0,0,0,0 ;
color_stream = color_sensor.add_video_stream( RS2_STREAM_COLOR, 0, 1, w,
h, 60, bpp,
RS2_FORMAT_RGB8, color_intrinsics );
dev.create_matcher(RS2_MATCHER_DLR_C); // create the matcher with the RGB frame
depth_sensor.open(depth_stream);
color_sensor.open(color_stream);
depth_sensor.start(syncer);
color_sensor.start(syncer);
depth_stream.register_extrinsics_to(color_stream, 1,0,0,0,1,0,0,0,1 , 0,0,0 );
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*bpp, bpp, // Stride and Bytes-per-pixel
(rs2_time_t)ind * 16, RS2_TIMESTAMP_DOMAIN_HARDWARE_CLOCK, ind, // Timestamp, Frame# for potential sync services
depth_stream );
color_sensor.on_video_frame( color_data, // Frame pixels from capture API
[](void*) , // Custom deleter (if required)
w*bpp, bpp, // Stride and Bytes-per-pixel
(rs2_time_t)ind * 16, RS2_TIMESTAMP_DOMAIN_HARDWARE_CLOCK, ind, // Timestamp, Frame# for potential sync services
color_stream );
ind++;
rs2::frameset fset = syncer.wait_for_frames();
depth = fset.first_or_default(RS2_STREAM_DEPTH);
color = fset.first_or_default(RS2_STREAM_COLOR);
return (depth && color); // return true if everything went good
rs2::frame rsImageConverter::getDepth() const
return depth;
rs2::frame rsImageConverter::getColor() const
return color;
然后你可以这样使用它(假设depth和rgb为两个cv::Mat,其中depth在CV_16U中转换,rgb是CV_8UC3,从BGR到RGB的转换):
rsImageConverter* converter = new rsImageConverter(640, 480, 2);
...
if(converter->convertFrame(depth.data, rgb.data))
rs2::frame rs2depth = converter->getDepth();
rs2::frame rs2rgb = converter->getColor();
... // Here you use these frames
顺便说一句,我设计这个类时同时使用了深度和 RGB。要仅转换其中一个,您只需将空框架传递给另一个参数,或更改类。
【讨论】:
以上是关于在 Librealsense SDK 中将 OpenCV Mat 转换为 Realsense 的帧类型的主要内容,如果未能解决你的问题,请参考以下文章
在 ubuntu 中使用 librealsense 的 C++ 构建错误
c_cpp librealsense2手动从差异变换到深度,反之亦然
如何在 iphone sdk 中将 NSArray/NSMutableArray 转换为 NSFetchedResultsController?