DeepStream-3D 自定义应用和库教程#
ds3d
框架、接口和自定义库专为 DeepStream-3D 处理而设计。ds3d
与 Gstreamer/Glib 框架无关。这些接口能够进行不同类型的数据融合。开发人员可以为 dataloader
、datafilter
和 datarender
实现不同类型的自定义库。该接口具有 ABI 兼容层和现代 C++ 接口。开发人员只需专注于现代 C++ 接口进行应用程序或自定义库开发。
DS3D dataloader
由 GstAppSrc
加载,使其可用于深度相机(如立体相机和飞行时间相机)来捕获图像/深度数据或从文件系统加载数据。此外,它还可用于从传感器或激光雷达数据文件捕获激光雷达数据。datafilter
由 nvds3dfilter
Gst-plugin 加载。它可用于 2D 深度数据处理、从深度提取 3D 点云数据、其他 2D 深度或 3D 点数据过滤器以及激光雷达或 3D 数据推理。datarender
由 GstAppSink
加载。它可用于 2D 深度渲染以及 3D 点云和激光雷达数据渲染。它也可用于文件转储。
DS3D 应用示例#
DeepStream-3D 多模态激光雷达和相机传感器融合应用 示例应用程序展示了使用 DS3D 框架的激光雷达和相机数据的多模态传感器融合管线。示例中包含 2 个多模态传感器融合管线示例。示例应用位于
/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion
。请参阅 DeepStream 3D 多模态激光雷达和相机传感器融合应用 以查看
deepstream-3d-lidar-sensor-fusion
的更多详细信息DS3D BEVFusion 管线通过
deepstream-3d-lidar-sensor-fusion
显示了 6 个相机加 1 个激光雷达数据融合推理和渲染管线的概述。DS3D V2XFusion 管线通过
deepstream-3d-lidar-sensor-fusion
显示了 1 个相机加 1 个激光雷达,批量为 4 的数据输入融合推理和渲染管线的概述。
deepstream-lidar-inference 具有加载这些自定义库并将这些组件以简单方式连接在一起的示例代码。除此之外,DS3D 还具有用于 Gstreamer 组件的简单 C++ 安全指针。接口位于
/opt/nvidia/deepstream/deepstream/sources/libs/ds3d/gst/
中的头文件中。
deepstream-3d-depth-camera 是 ds3d 管线的另一个示例。
所有组件均以 YAML 格式配置。它们由 Gst-plugins 加载。有 3 个主要组件,它们都可以加载到 deepstream 管线中。
DS3D 数据格式 ds3d/datamap
#
ds3d/datamap
识别 DS3D 框架中使用的数据格式。在 GStreamer 插件之间流动的数据缓冲区将属于此数据类型。ds3d/datamap
是键值对,其中键是字符串,值是指针、结构或张量帧到数据。缓冲区上的所有操作均由 GuardDataMap
管理。
示例
创建 GuardDataMap
datamap
并设置标量键值。#include <ds3d/common/hpp/datamap.hpp> using namespace ds3d; GuardDataMap datamap(NvDs3d_CreateDataHashMap(), true); // creat a empty datamap TimeStamp ts{0}; datamap.setData("DS3D::Timestamp", ts); // set timestamp float score = 0.1; datamap.setData("DS3D::Score", score); // copy score into datamap
用户定义的结构添加到 ds3d
datamap
中。ds3d datamap 要求每种数据类型在将数据添加到 datamap 之前都具有
typeid: uint64_t
。这可以防止运行时出现任何错误的数据类型转换。为了实现这一点,有两种方法可以为结构启用 typeid。示例 1,直接在自定义数据结构定义中使用
REGISTER_TYPE_ID
。这主要在用户定义新结构时使用。#define DS3D_TYPEID_TIMESTAMP 0x20002 struct TimeStamp { uint64_t t0 = 0; uint64_t t1 = 0; uint64_t t2 = 0; REGISTER_TYPE_ID(DS3D_TYPEID_TIMESTAMP) }; // Add the shared_ptr into datamap std::shared_ptr<TimeStamp> timePtr(new TimeStamp); datamap.setPtrData("DS3D::Timestamp0", timePtr); // Add a copy of the TimeStamp into datamap TimeStamp time1; datamap.setData("DS3D::Timestamp1", time1);
示例 2,实例化模板
struct TpId<> { static constexpr TIdType __typeid(); }
,当将第三方数据结构添加到 datamap 且无法修改第三方现有 DataStructure 时,这很有帮助。// this is the 3rd-party structure struct Existing3rdpartData { float v0; int v1; }; // derive ds3d::__TypeID for any 3rdparty data structure. #incude "ds3d/common/type_trait.h" #define DS3D_TYPEID_EXISTING_3RDPART_DATA 0x80001 namespace ds3d { template <> struct TpId<Existing3rdpartData>: __TypeID<DS3D_TYPEID_EXISTING_3RDPART_DATA> {}; } // Add the shared_ptr into datamap std::shared_ptr<Existing3rdpartData> dataPtr(new Existing3rdpartData); datamap.setPtrData("3rdpartyData0", dataPtr); // Add a copy of the Existing3rdpartData into datamap Existing3rdpartData data3rdparty{0.0f, 0}; datamap.setData("3rdpartyData1", data3rdparty);
创建 LiDAR 张量帧并添加到 GuardDataMap
datamap
中。std::vector<vec4f> lidardata = { {{-5.0f, -5.0f, -3.0f, 0.6f}}, {{-5.0f, -5.0f, -3.0f, 0.85f}}, {{1.0f, 0.5f, -1.0f, 0.82f}}, {{-5.0f, -5.0f, -3.0f, 0.8f}}, }; void* pointPtr = (void*)(&lidardata[0]); uint32_t pointsN = lidardata.size(); FrameGuard lidarFrame = wrapLidarXYZIFrame<float>( (void*)pointPtr, pointsN, MemType::kCpu, 0, [holder = std::move(lidardata)](void*) {}); // lambda deleter const std::string keyName = "DS3D::LidarXYZI"; // user define a key name. // setGuardData holds a reference_count on the lidarFrame without deep-copy datamap.setGuardData(keyName, lidarFrame);
创建 2D 图像张量帧并添加到 GuardDataMap
datamap
中。std::vector<vec4b> imagedata = { {{255, 0, 0, 255}}, {{0, 255, 0, 255}}, {{0, 255, 0, 255}}, {{0, 0, 255, 255}}, {{255, 255, 0, 255}}, {{0, 255, 0, 255}}, }; uint32_t width = 3, height = 2; Frame2DPlane colorPlane = {width, height, (uint32_t)sizeof(vec4b) * width, sizeof(vec4b), 0}; void* colorPtr = (void*)(&imagedata[0]); uint32_t bytes = colorPlane.pitchInBytes * colorPlane.height; Frame2DGuard imageFrame = impl::Wrap2DFrame<uint8_t, FrameType::kColorRGBA>( colorPtr, {colorPlane}, bytes, MemType::kCpu, 0, [holder = std::move(imagedata)](void*) {}); // lambda deleter const std::string keyName = "DS3D::ColorFrame"; // user define a key name. // setGuardData holds a reference_count on the imageFrame without deep-copy datamap.setGuardData(keyName, imageFrame);
创建自定义形状的张量帧并添加到 GuardDataMap
datamap
中。std::vector<float> tensordata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.0f }; void* tensorPtr = (void*)(&tensordata[0]); Shape tensorShape{3, {1, 3, 4}}; // tensor shape (1, 3, 4) uint32_t bytes = tensordata.size() * sizeof(tensordata[0]); FrameGuard tensorFrame = impl::WrapFrame<float, FrameType::kCustom>( tensorPtr, bytes, tensorShape, MemType::kCpu, 0, [holder = std::move(imagedata)](void*) {}); // lambda deleter const std::string keyName = "DS3D::dataarray"; // user define a key name. // setGuardData holds a reference_count on the tensorFrame without deep-copy datamap.setGuardData(keyName, tensorFrame);
从 GuardDataMap
datamap
查询数据值GuardDataMap::getGuardData
,返回安全引用计数保护数据 GuardDataT<DataStructure>,例如 Frame2DGuard、FrameGuard、GuardDataT<TimeStamp>GuardDataMap::getPtrData
,返回引用计数 std::shared_ptr<DataStructure>,例如 std::shared_ptr<TimeStamp>GuardDataMap::getData
,返回 DataStructure 的副本。例如 TimeStamp// example to use different ways to get timestamp. std::string timeKey = "DS3D::Timestamp"; if (datamap.hasData(timeKey)) { // get a COPY of Timestamp TimeStamp t0; DS_ASSERT(isGood(datamap.getData(timeKey, t0)); // get a std::shared_ptr of Timestamp std::shared_ptr<TimeStamp> tPtr; DS_ASSERT(isGood(datamap.getPtrData(timeKey, tPtr)); // get a reference-counted GuardDataT<Timestamp> GuardDataT<TimeStamp> timeGuard; DS_ASSERT(isGood(datamap.getPtrData(timeKey, timeGuard)); // example to get a lidar tensor frame FrameGuard pointFrame; std::string lidarKey = "DS3D::LidarXYZI"; if (datamap.hasData(lidarKey)) { // get lidar tensor frame // pointFrame holds a reference count DS_ASSERT(isGood(dataMap.getGuardData(lidarKey, pointFrame))); DataType dType = pointFrame->dataType(); FrameType frameType = pointFrame->frameType(); MemType memType = pointFrame->memType(); Shape pShape = pointFrame->shape(); void *dataPtr = pointFrame->base(); size_t dataBytes = pointFrame->bytes(); } // example to get a RGBA image tensor frame Frame2DGuard rgbaImage; std::string imageKey = "DS3D::ColorFrame"; if (datamap.hasData(imageKey)) { // get 2D image tensor frame // rgbaImage holds a reference count DS_ASSERT(isGood(dataMap.getGuardData(imageKey, rgbaImage))); DataType dType = rgbaImage->dataType(); FrameType frameType = rgbaImage->frameType(); MemType memType = rgbaImage->memType(); Shape pShape = rgbaImage->shape(); void *dataPtr = rgbaImage->base(); size_t dataBytes = rgbaImage->bytes(); DS_ASSERT(rgbaImage->planes() == 1); // RGBA image has 1 plane. Frame2DPlane plane = rgbaImage->getPlane(0); } // example to get a custom shaped tensor frame, e.g. data_array FrameGuard tensorFrame; std::string tensorKey = "DS3D::dataarray"; if (datamap.hasData(tensorKey)) { // get any tensor frame // tensorFrame holds a reference count DS_ASSERT(isGood(dataMap.getGuardData(tensorKey, tensorFrame))); DataType dType = tensorFrame->dataType(); FrameType frameType = tensorFrame->frameType(); MemType memType = tensorFrame->memType(); Shape pShape = tensorFrame->shape(); void *dataPtr = tensorFrame->base(); size_t dataBytes = tensorFrame->bytes(); }
DS3D DataMap 与 GstBuffer 互操作#
DS3D DataMap 具有 ABI 兼容类 ds3d::abiRefDataMap
。因此,定义了 NvDs3DBuffer
以存储 DS3D datamap 以及 GstBuffer。头文件为 ds3d/gst/nvds3d_meta.h
。
struct NvDs3DBuffer { uint32_t magicID; // must be 'DS3D' ds3d::abiRefDataMap* datamap; };
警告
请勿直接使用 datamap。访问它的简单且安全的方法是通过 GuardDataMap
。请参阅以下示例
从
GstBuffer
获取 datamap 的示例
#include <ds3d/common/hpp/datamap.hpp> #include <ds3d/common/hpp/frame.hpp> using namespace ds3d; GstBuffer *gstBuf = ; // get the gstBuf from probe function or Gstreamer plugins if (NvDs3D_IsDs3DBuf(gstBuf)) { const abiRefDataMap* refDataMap = nullptr; ErrCode c = NvDs3D_Find1stDataMap(gstBuf, refDataMap); if (refDataMap) { GuardDataMap dataMap(*refDataMap); FrameGuard lidarFrame; c = dataMap.getGuardData("DS3D::LidarXYZI", pointFrame); // get lidar points reference. FrameGuard uvCoord; c = dataMap.getGuardData("DS3D::TextureCoordKey", uvCoord); // get 3D points UV coordinates reference. Frame2DGuard depthFrame; c = dataMap.getGuardData("DS3D::DepthFrame", depthFrame); // get depth frame reference. DepthScale scale; c = dataMap.getData("DS3D::DepthScaleUnit", scale); // copy depth scale } }
在新的
GstBuffer
中创建一个ds3d::datamap
的示例#include <ds3d/common/hpp/datamap.hpp> #include <ds3d/common/hpp/frame.hpp> #include <ds3d/common/impl/impl_frames.h> GuardDataMap datamap(NvDs3d_CreateDataHashMap(), true); // set true to take the reference ownership. /* Create color image frame and store them into ds3d datamap. */ // Assume format is RGBA { Frame2DPlane colorPlane = {1920, 1080, 1920 * sizeof(uint8_t) , sizeof(uint8_t), 0}; uint32_t colorBytesPerFrame = colorPlane.pitchInBytes * colorPlane.height; std::vector<uint8_t> data(colorBytesPerFrame); // Image data void* dataPtr = &data[0]; // create color 2D frame Frame2DGuard frame = Wrap2DFrame<uint8_t, FrameType::kColorRGBA>( dataPtr, {_config.colorPlane}, bytesPerFrame, MemType::kCpu, 0, [data = std::move(data)](void*) {}); c = datamap.setGuardData(kColorFrame, colorFrame); // store colorFrame reference into datamap. ... // check error code }
准备好
datamap
后,您可以创建一个带有 DS3D datamap 的新 GstBuffer。// ``GuardDataMap datamap`` is ready GstBuffer* gstBuf = nullptr; ErrCode c = NvDs3D_CreateGstBuf(gstBuf, datamap.abiRef(), false); // set false to increase reference count. ... // check error code
使用新的
ds3d
datamap 更新现有DS3D
GstBuffer 的示例。// Assume ``GuardDataMap datamap`` is ready // Assume ``GstBuffer* gstBuf`` is created by another compoment ErrCode c = NvDs3D_UpdateDataMap(gstBuf, datamap.abiRef(), false); // set false to increase reference count. ... // check error code
ds3d::dataloader
- 加载用于数据捕获的自定义库#
加载和管理 DS3D Dataloader#
示例
name: realsense_dataloader
type: ds3d::dataloader
out_caps: ds3d/datamap
custom_lib_path: libnvds_3d_dataloader_realsense.so
custom_create_function: createRealsenseDataloader
config_body:
streams: [color, depth]
自定义 dataloader 必须具有 type: ds3d::dataloader
。它通过显式调用 NvDs3D_CreateDataLoaderSrc(srcConfig, loaderSrc, start)
以及完整的组件 YAML 内容来创建。在此调用期间,将加载 custom_lib_path
,并通过 custom_create_function
创建特定的数据加载器。GstAppsrc 对象也将在 loaderSrc.gstElement
中创建。
GstAppsrc 管理 ds3d::dataloader 数据流。此 ds3d::dataloader
组件可以由 gst-pipeline 自动启动,也可以由应用程序调用手动启动。
GuardDataLoader dataloader = loaderSrc.customProcessor;
ErrCode c = dataloader.start();
要停止 dataloader,用户可以将 GstAppsrc 状态设置为 GST_STATE_READY
或手动停止它。
GuardDataLoader dataloader = loaderSrc.customProcessor;
ErrCode c = dataloader.stop();
DeepStream 用户应用程序中的 DS3D Dataloader#
DS3D 自定义数据加载器与 Gstreamer/Glib 框架无关。但它也可以与 Gstramer 一起工作。ds3d::dataloader
可以与 GstAppSrc 交互式地协同工作。它们可以通过 NvDs3D_CreateDataLoaderSrc
创建。
示例
#include <ds3d/common/config.h>
#include <ds3d/gst/nvds3d_gst_plugin.h>
std::string yamlStr = R"(
name: ds3d_lidar_file_source
type: ds3d::dataloader
out_caps: ds3d/datamap
custom_lib_path: libnvds_lidarfileread.so
custom_create_function: createLidarFileLoader
config_body:
data_config_file: lidar_data_list.yaml
points_num: 242180
mem_type: gpu # choose [cpu gpu]
gpu_id: 0
mem_pool_size: 6
element_size: 4
output_datamap_key: DS3D::LidarXYZI
)";
ErrCode c = ErrCode::kGood;
ComponentConfig config;
c = parseComponentConfig(yamlStr.c_str(), "./config_lidar_loader.yaml", config);
DS_ASSERT(config.type == ComponentType::kDataLoader);
DS_ASSERT(config.customLibPath == "libnvds_lidarfileread.so");
DS_ASSERT(config.customCreateFunction == "createLidarFileLoader");
gst::DataLoaderSrc appLoader;
c = NvDs3D_CreateDataLoaderSrc(c, appLoader, true);
// get DS3D custom dataloader.
GuardDataLoader dataLoader = appLoader.customProcessor;
// get GstAppSrc from this appLoader;
GstElement* appsrc = appLoader.gstElement.get();
// gstreamer pipeline setup and running.
// during each read_data from GstAppSrc callback. it would simultaneously reading data from dataloader
// GuardDataMap datamap;
// dataloader.read_data(datamap);
// DS3D dataloader would stop qutomatically when Gstpipeline is stopped.
// But in the case if user want to stop it early or manually.
// Obtain DS3D custom dataloader and stop manually.
c = dataloader.flush();
c = dataloader.stop();
GuardDataLoader
提供对 abiDataLoader
的安全访问。创建后,它将维护对 dataloader 的引用指针。
实现 DS3D 自定义 Dataloader#
示例
#include <ds3d/common/impl/impl_dataloader.h>
class TestTimeDataLoader : public ds3d::impl::SyncImplDataLoader {
public:
TestTimeDataLoader() = default;
protected:
ErrCode startImpl(const std::string& content, const std::string& path) override
{
setOutputCaps("ds3d/datamap");
return ErrCode::kGood;
}
ErrCode readDataImpl(GuardDataMap& datamap) override
{
datamap.reset(NvDs3d_CreateDataHashMap());
static uint64_t iTime = 0;
TimeStamp t{iTime++, 0, 0};
datamap.setData("time", t);
emitError(ErrCode::kGood, "timstamp added");
return ErrCode::kGood;
}
ErrCode stopImpl() override { return ErrCode::kGood; }
ErrCode flushImpl() override { return ErrCode::kGood; }
};
DS3D_EXTERN_C_BEGIN
DS3D_EXPORT_API abiRefDataLoader*
createTestTimeDataloader()
{
return NewAbiRef<abiDataLoader>(new TestTimeDataLoader);
}
DS3D_EXTERN_C_END
如上面的示例所示,您需要从 ds3d::impl::SyncImplDataLoader
类派生 dataloader,并为以下内容实现接口
ErrCode startImpl(const std::string& content, const std::string& path) override; ErrCode readDataImpl(GuardDataMap& datamap) override; ErrCode stopImpl() override; ErrCode flushImpl() override;
ds3d::databridge
- 加载自定义库以实现与 DS3D 之间的数据转换。#
此插件和自定义库有助于将数据类型转换为 ds3d/datamap
和从 ds3d/datamap
转换数据类型
更多详细信息:Gst-nvds3dbridge。
ds3d::datafilter
- DS3D 自定义 DataFilter#
DS3D DataFilter 处理来自 ds3d::datamap
的输入,并生成输入新的 ds3d::datamap
输出。用户可以为其用例实现自定义 datafilter 库。
在 DeepStream 应用中创建和管理 DS3D Datafilter#
示例
#include <ds3d/common/config.h>
#include <ds3d/gst/nvds3d_gst_ptr.h>
#include <ds3d/gst/nvds3d_gst_plugin.h>
std::string yamlStr = R"(
name: fusion_inference
type: ds3d::datafilter
in_caps: ds3d/datamap
out_caps: ds3d/datamap
custom_lib_path: libnvds_tritoninferfilter.so
custom_create_function: createLidarInferenceFilter
config_body:
mem_pool_size: 2
model_inputs:
config_file: model_config_files/config_triton_bev_fusion_infer_grpc.pbtxt
- name: input_image_0
datatype: UINT8
shape: [1, 900, 1600, 4]
from: DS3D::ColorFrame_0+1
is_2d_frame: true
- name: input_lidar
datatype: FP32
shape: [242180, 4]
from: DS3D::LidarXYZI+0
)";
gst::ElePtr gstPlugin = gst::elementMake("nvds3dfilter", "ds3d-custom-filter");
g_object_set(G_OBJECT(gstPlugin.get()), "config-content", yamlStr.c_str(), nullptr);
GstElement* ele = gstPlugin.get();
自定义 datafilter 必须具有 type: ds3d::datafilter
。它通过 nvds3dfilter
Gst-plugin 加载。它由 gst_element_set_state(GST_STATE_READY)
启动。在此调用期间,将加载 custom_lib_path
,并通过 custom_create_function
创建特定的数据过滤器。nvds3dfilter
Gst-plugin 具有 config-content
和 config-file
属性。必须设置其中一个属性才能创建 datafilter 对象。
实现自定义 DS3D Datafilter#
示例
#include <ds3d/common/impl/impl_datafilter.h>
class TestFakeDataFilter : public impl::BaseImplDataFilter {
public:
TestFakeDataFilter() = default;
protected:
ErrCode startImpl(const std::string& content, const std::string& path) override
{
setInputCaps(kFakeCapsMetaName);
setOutputCaps(kFakeCapsMetaName);
return ErrCode::kGood;
}
ErrCode processImpl(
GuardDataMap datamap, OnGuardDataCBImpl outputDataCb,
OnGuardDataCBImpl inputConsumedCb) override
{
DS_ASSERT(datamap);
TimeStamp t;
ErrCode c = datamap.getData("time", t);
if (!isGood(c)) {
return c;
}
t.t0 += 1;
inputConsumedCb(ErrCode::kGood, datamap);
c = datamap.setData("time", t);
if (!isGood(c)) {
return c;
}
outputDataCb(ErrCode::kGood, datamap);
return ErrCode::kGood;
}
ErrCode flushImpl() override { return ErrCode::kGood; }
ErrCode stopImpl() override { return ErrCode::kGood; }
};
DS3D_EXTERN_C_BEGIN
DS3D_EXPORT_API abiRefdatafilter*
createTestFakeDatafilter()
{
return NewAbiRef<abidatafilter>(new TestFakeDataFilter);
}
DS3D_EXTERN_C_END
如上面的示例所示,您需要从 ds3d::impl::BaseImplDataFilter
类派生 datafilter,并为以下内容实现接口
ErrCode startImpl(const std::string& content, const std::string& path) override;
ErrCode processImpl(
GuardDataMap datamap, OnGuardDataCBImpl outputDataCb,
OnGuardDataCBImpl inputConsumedCb) override;
ErrCode stopImpl() override;
ErrCode flushImpl() override;
要通过 nvds3dfilter
Gst-plugin 加载此自定义库,您还需要导出特定的符号 createTestFakeDatafilter
。
ds3d::datarender
- 加载 DS3D 自定义 DataRender#
DS3D 自定义 DataRender 与 Gstreamer/Glib 框架无关。但它也可以与 Gstramer 一起工作。ds3d::datarender
可以与 GstAppSink 交互式地协同工作。它们可以通过 NvDs3D_CreateDataRenderSink
创建。
示例
加载和管理 DS3D Datarender#
示例
#include <ds3d/common/config.h>
#include <ds3d/gst/nvds3d_gst_plugin.h>
std::string yamlStr = R"(
name: lidar_render
type: ds3d::datarender
in_caps: ds3d/datamap
custom_lib_path: libnvds_3d_gl_datarender.so
custom_create_function: createLidarDataRender
gst_properties:
sync: True
async: False
drop: False
config_body:
title: ds3d-lidar-render
streams: [lidardata]
width: 1280
height: 720
block: True
view_position: [0, 0, 60]
view_target: [0, 0, 0]
view_up: [0, 1, 0]
near: 0.3
far: 100
fov: 50
lidar_color: [0, 255, 0]
lidar_data_key: DS3D::LidarXYZI
element_size: 4
lidar_bbox_key: DS3D::Lidar3DBboxRawData
enable_label: True
)";
ErrCode c = ErrCode::kGood;
ComponentConfig config;
c = parseComponentConfig(yamlStr.c_str(), "./config_lidar_loader.yaml", config);
DS_ASSERT(config.type == ComponentType::kDataRender);
DS_ASSERT(config.customLibPath == "libnvds_3d_gl_datarender.so");
DS_ASSERT(config.customCreateFunction == "createLidarDataRender");
gst::DataRenderSink appRender;
c = NvDs3D_CreateDataRenderSink(config, appRender, true);
// get DS3D custom datarender.
GuardDataRender datarender = appRender.customProcessor;
// get GstAppSink from this appRender;
GstElement* appsink = appRender.gstElement.get();
// gstreamer pipeline setup and running.
// during each render_data from GstAppSink callback. it would simultaneously reading data from datarender
// datarender.render(datamap, consumed_callback);
// DS3D datarender would stop qutomatically when Gstpipeline is stopped.
// But in the case if user want to stop it early or manually.
// Obtain DS3D custom datarender and stop manually.
c = datarender.stop();
自定义 datarender 必须具有 type: ds3d::datarender
。它通过显式调用 NvDs3D_CreateDataRenderSink(sinkConfig, renderSink, start)
以及完整的组件 YAML 内容来创建。在此调用期间,将加载 custom_lib_path
,并通过 custom_create_function
创建特定的数据加载器。GstAppsink 对象也将在 renderSink.gstElement
中创建。
GstAppsink 管理 ds3d::datarender 数据流。此 ds3d::datarender 组件可以由 gst-pipeline 自动启动,也可以由应用程序调用手动启动。
GuardDataRender datarender = renderSink.customProcessor; ErrCode c = datarender.start();
要停止 datarender,您可以将 GstAppsink 状态设置为 GST_STATE_READY
,或手动停止。.. code-block:: text
GuardDataRender datarender = renderSink.customProcessor; ErrCode c = datarender.stop();
GuardDataRender
提供对 abidatarender
的安全访问。创建后,它将维护对 datarender 的引用指针。preroll
仅调用一次以初始化某些资源。
实现 DS3D 自定义 Datarender#
示例
#include <ds3d/common/impl/impl_datarender.h> class TestFakeDataRender : public impl::BaseImplDataRender { public: TestFakeDataRender() = default; protected: ErrCode startImpl(const std::string& content, const std::string& path) override { setInputCaps("ds3d/datamap"); return ErrCode::kGood; } ErrCode prerollImpl(GuardDataMap datamap) override { return ErrCode::kGood; } ErrCode renderImpl(GuardDataMap datamap, OnGuardDataCBImpl dataDoneCb) override { DS_ASSERT(datamap); emitError(ErrCode::kGood, "data rendered"); dataDoneCb(ErrCode::kGood, datamap); return ErrCode::kGood; } ErrCode flushImpl() override { return ErrCode::kGood; } ErrCode stopImpl() override { return ErrCode::kGood; } }; DS3D_EXTERN_C_BEGIN DS3D_EXPORT_API abiRefdatarender* createTestFakedatarender() { return NewAbiRef<abiDataRender>(new TestFakeDataRender()); } DS3D_EXTERN_C_END
如上面的示例所示,您需要从 ds3d::impl::BaseImplDataRender
类派生 datarender,并为以下内容实现接口
ErrCode startImpl(const std::string& content, const std::string& path) override; ErrCode prerollImpl(GuardDataMap datamap) override; ErrCode renderImpl(GuardDataMap datamap, OnGuardDataCBImpl dataDoneCb) override; ErrCode stopImpl() override; ErrCode flushImpl() override;
要通过 NvDs3D_CreateDataRenderSink
加载此自定义库,您还需要导出特定的符号 createTestFakedatarender
。
自定义库配置规范#
组件通用配置规范#
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
type |
自定义处理器类型 |
字符串,[ds3d::dataloader, ds3d::datafilter, ds3d::datarender] |
type: ds3d::dataloader |
name |
指示用户定义的组件名称 |
字符串 |
name: depthloader |
in_caps |
指示组件的 Gst sink caps |
字符串 |
in_caps: ds3d/datamap |
out_caps |
指示组件的 Gst sink caps |
字符串 |
out_caps: ds3d/datamap |
custom_lib_path |
指示自定义库路径 |
字符串 |
custom_lib_path: libnvds_3d_gl_datarender.so |
custom_create_function |
指示用于创建特定 ds3d 处理组件的自定义函数 |
字符串 |
custom_create_function: createPointCloudDataRender |
config_body |
指示自定义组件的 YAML 特定内容 |
字符串 |
|
这些自定义库是 DeepStream 发布包的一部分。
支持的 DS3D 自定义处理库#
DS3D 处理类型 |
功能 |
DS3D 自定义库 |
DS3D 创建实例函数 |
描述 |
---|---|---|---|---|
dataloader |
激光雷达文件读取器 |
libnvds_lidarfileread.so |
|
激光雷达文件数据读取器库,请参阅 自定义 Dataloader libnvds_lidarfileread 配置规范 中的详细信息 |
dataloader |
realsense 相机深度/图像捕获 |
libnvds_3d_dataloader_realsense.so |
|
RealSense 相机捕获数据加载器库,请参阅 自定义 Dataloader libnvds_3d_dataloader_realsense 配置规范 中的详细信息 |
datafilter |
多传感器 triton 推理库 |
libnvds_tritoninferfilter.so |
|
多模态传感器 triton 推理库,请参阅 libnvds_tritoninferfilter 配置规范 中的详细信息 |
datafilter |
data_alignment |
libnvds_3d_alignment_datafilter.so |
|
激光雷达/相机传感器内部和外部参数以及对齐,请参阅 自定义 ds3d::datafilter 库:libnvds_3d_alignment_datafilter.so 中的详细信息 |
datafilter |
lidar_data_preprocess |
libnvds_3d_lidar_preprocess_datafilter.so |
|
激光雷达数据体素处理,请参阅 自定义 Datafilter libnvds_3d_lidar_preprocess_datafilter 规范 中的详细信息 |
datafilter |
depth-to-point-cound |
libnvds_3d_depth2point_datafilter.so |
|
将图像深度数据转换为 3D 点云数据,请参阅 自定义 datafilter libnvds_3d_depth2point_datafilter 配置规范 中的详细信息 |
databridge |
将 2D 桥接到 DS3D |
libnvds_3d_video_databridge.so |
|
将 DeepStream 2D batchmeta 和 surface 转换为 |
datamixer |
用于视频和激光雷达/雷达的混合器 |
libnvds_3d_multisensor_mixer.so |
|
将视频数据 (2D) 和 LiDAR 数据 (3D) 组合到单个 |
datarender |
3D 多视图场景渲染 |
libnvds_3d_gles_ensemble_render.so |
|
使用 GLES 渲染 3D 多视图场景,其中包含 |
datarender |
具有纹理的 3D 点云数据渲染 |
libnvds_3d_gl_datarender.so |
|
使用 |
datarender |
3D 激光雷达 (XYZI/XYZ) 数据渲染 |
libnvds_3d_gl_datarender.so |
|
渲染 |
datarender |
深度图像 2D 渲染 |
libnvds_3d_gl_datarender.so |
|
渲染 |
libnvds_tritoninferfilter 配置规范#
具有 ds3d::datamap
中键值对的多模态张量 Triton 推理,支持用户定义的自定义预处理和后处理。
多模态 triton 推理标头的配置
name: multimodal_triton_infer type: ds3d::datafilter in_caps: ds3d/datamap out_caps: ds3d/datamap custom_lib_path: libnvds_tritoninferfilter.so custom_create_function: createLidarInferenceFilter
Config body 规范
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
in_streams |
将处理哪种数据类型 |
字符串列表,可选 |
in_streams: [lidar] |
gpu_id |
GPU 设备 ID |
整数,默认值:0 |
gpu_id: 0 |
config_file |
nvinferserver(triton) 底层库配置文件,支持 gRPC 和 CAPI,请参阅 底层 libnvds_infer_server.so 配置文件规范 中的更多详细信息 |
路径字符串 |
config_file: model_config_files/config_triton_bev_fusion_infer_grpc.pbtxt |
mem_pool_size |
输入张量池的大小 |
整数 |
mem_pool_size: 8 |
model_inputs |
模型 ‘s 输入层信息,如果没有定义 custom_preprocess,inferencefilter 会将 |
字典列表 |
|
input_tensor_mem_type |
预处理后的输入张量内存类型 |
字符串:[GpuCuda CpuCuda] |
input_tensor_mem_type: GpuCuda |
custom_preprocess_lib_path |
自定义预处理库路径 |
字符串 |
custom_preprocess_lib_path: /opt/nvidia/deepstream/deepstream/lib/libnvds_lidar_custom_preprocess_impl.so |
custom_preprocess_func_name |
自定义预处理函数名称 |
字符串 |
custom_preprocess_func_name: CreateInferServerCustomPreprocess |
postprocess |
用户定义的后处理信息 |
字典 |
|
labels |
用户为自定义后处理定义的标签 |
字典列表 |
|
model_inputs
包含所有输入层信息。如果在 config body 中指定了自定义预处理函数/库。该库将搜索输入 ds3d::datamap
的 from
键名,并将帧/张量数据转发到 Triton 服务器的输入张量。from
键名必须是 ds3d::datamap
内的帧、2D 帧或张量
model_inputs
的配置规范
属性 |
描述 |
类型和范围 |
示例 |
---|---|---|---|
name |
模型的输入张量名称 |
字符串 |
name: input_image_0 |
datatype |
模型的输入数据类型 |
字符串值,取值范围:[FP32, FP16, INT8, INT32, INT16, UINT8, UINT16, UINT32, FP64, INT64, UINT64, BYTES, BOOL] |
datatype: FP32 |
shape |
模型的输入张量形状 |
整数列表 |
shape: [1, 900, 1600, 4] |
from |
输入 |
字符串 |
from: DS3D::ColorFrame_5 |
is_2d_frame |
指示 |
布尔值 |
is_2d_frame: true |
triton 推理之前的自定义预处理
如果指定了 custom_preprocess_lib_path
和 custom_preprocess_func_name
,则将加载自定义处理,并解析配置主体,获取所有通用和用户定义的信息。然后处理每个输入 ds3d::datamap
并生成用于 triton 推理输入的 batchArray
。
用户可以从 sources/includes/ds3d/common/hpp/lidar_custom_process.hpp
派生接口 IInferCustomPreprocessor
。请参阅 sources/libs/ds3d/inference_custom_lib/ds3d_v2x_infer_custom_preprocess/nvinferserver_custom_preprocess.cpp
中的示例
#include <ds3d/common/hpp/datamap.hpp>
#include <ds3d/common/hpp/frame.hpp>
#include <ds3d/common/hpp/lidar_custom_process.hpp>
using namespace ds3d;
using namespace nvdsinferserver;
class NvInferServerCustomPreProcess : public IInferCustomPreprocessor {
public:
// process key-values from datamap and generate into model inputs batchArray.
NvDsInferStatus preproc(GuardDataMap &datamap, SharedIBatchArray batchArray, cudaStream_t stream) override {...}
};
extern "C" {
IInferCustomPreprocessor *CreateInferServerCustomPreprocess() {
return new NvInferServerCustomPreProcess();
} }
Triton 推理后的自定义后处理
后处理对于每个模型都非常具体。您需要根据推理输出张量结果来实现自己的后处理函数。自定义后处理库和函数在 nvdsinferserver 的配置中指定。例如,在 apps/sample_apps/deepstream-3d-lidar-sensor-fusion/model_config_files/config_triton_bev_fusion_infer_grpc.pbtxt
中。
infer_config {
backend {
triton {
model_name: "bevfusion"
grpc {...}
} }
extra {
output_buffer_pool_size: 4
# specify custom postprocess function
custom_process_funcion: "Nvds3d_CreateLidarDetectionPostprocess"
}
custom_lib {
# specify custom postprocess library
path: "libnvds_3d_infer_postprocess_lidar_detection.so"
}
}
此处提供了一个自定义后处理实现的示例:sources/libs/ds3d/inference_custom_lib/ds3d_lidar_detection_postprocess/ds3d_infer_postprocess_lidar_detection.cpp
#include "infer_custom_process.h"
#include <ds3d/common/hpp/frame.hpp>
#include <ds3d/common/hpp/datamap.hpp>
using namespace ds3d;
using namespace nvdsinferserver;
class DS3DTritonLidarInferCustomPostProcess : public IInferCustomProcessor {
public:
// process key-values from datamap and generate into model inputs batchArray.
NvDsInferStatus inferenceDone(const IBatchArray* batchArray, const IOptions* inOptions) override {
...
// get ``ds3d::datamap`` from ``inOptions``
abiRefDataMap* refDataMap = nullptr;
if (inOptions->hasValue(kLidarRefDataMap)) {
INFER_ASSERT(inOptions->getObj(kLidarRefDataMap, refDataMap) == NVDSINFER_SUCCESS);
}
GuardDataMap dataMap(*refDataMap);
...
// parsing output tensors from batchArray
TensorMap outTensors;
for (uint32_t i = 0; i < batchArray->getSize(); ++i) {
auto buf = batchArray->getSafeBuf(i);
outTensors[buf->getBufDesc().name] = buf;
}
std::vector<Lidar3DBbox> bboxes;
ret = parseLidar3Dbbox(outTensors, bboxes);
// warp data into ds3d frame ``bboxFrame``
size_t bufBytes = sizeof(Lidar3DBbox) * bboxes.size();
void* bufBase = (void*)bboxes.data();
Shape shape{3, {1, (int)bboxes.size(), sizeof(Lidar3DBbox)}};
FrameGuard bboxFrame = impl::WrapFrame<uint8_t, FrameType::kCustom>(
bufBase, bufBytes, shape, MemType::kCpu, 0, [outdata = std::move(bboxes)](void*) {});
// add key-value fram into ds3d::datamap
ErrCode code = dataMap.setGuardData(_3dBboxKey, bboxFrame);
...
return ret;
}
};
extern "C" {
IInferCustomProcessor *Nvds3d_CreateLidarDetectionPostprocess() {
return new DS3DTritonLidarInferCustomPostProcess();
} }
自定义数据过滤器 libnvds_3d_alignment_datafilter 规范#
可以使用 DeepStreamSDK 提供的自定义库完成激光雷达和视频数据的Data alignment(数据对齐)。
更多详细信息请参见此处: 自定义 ds3d::datafilter 库:libnvds_3d_alignment_datafilter.so。
自定义数据过滤器 libnvds_3d_lidar_preprocess_datafilter 规范#
在 V2X 模型传感器融合推理之前,将 LiDAR 数据预处理为体素数据格式。源文件位于 /opt/nvidia/deepstream/deepstream/sources/libs/ds3d/datafilter/lidar_preprocess
LiDAR 数据预处理
ds3d::datafilter
标头配置name: lidarpreprocess type: ds3d::datafilter out_caps: ds3d/datamap custom_lib_path: libnvds_3d_lidar_preprocess_datafilter.so custom_create_function: createLidarPreprocessFilter
配置主体规范
例如
config_body: mem_pool_size: 4 filter_input_datamap_key: DS3D::LidarXYZI_0 model_inputs: - name: feats datatype: FP16 shape: [4, 8000, 10, 9] - name: coords datatype: INT32 shape: [4, 8000, 4] - name: N datatype: INT32 shape: [4, 1] gpu_id: 0 input_tensor_mem_type: GpuCuda lidar_data_from: [DS3D::LidarXYZI_0, DS3D::LidarXYZI_1, DS3D::LidarXYZI_2, DS3D::LidarXYZI_3] output_features_tensor_key: DS3D::LidarFeatureTensor output_coords_tensor_key: DS3D::LidarCoordTensor output_num_tensor_key: DS3D::LidarPointNumTensor
属性 |
描述 |
类型和范围 |
示例 |
---|---|---|---|
mem_pool_size |
内存缓冲区池大小 |
整数 |
mem_pool_size: 4 |
filter_input_datamap_key |
指定输入激光雷达数据键名 |
字符串 |
filter_input_datamap_key: DS3D::LidarXYZI_0 |
model_inputs |
指定模型输入层信息 |
字典 |
请参阅 deepstrem-3d-lidar-sensor-fusion/ds3d_lidar_video_sensor_v2xfusion.yml 中的示例 |
gpu_id |
指定 GPU ID |
整数 |
gpu_id: 0 |
input_tensor_mem_type |
指定模型输入张量内存类型 |
字符串,从 [GpuCuda, CpuCuda] 中选择值 |
input_tensor_mem_type: GpuCuda |
lidar_data_from |
指定激光雷达数据键名 |
字符串列表 |
lidar_data_from: [DS3D::LidarXYZI_0] |
output_features_tensor_key |
指定输出激光雷达特征张量键名 |
字符串 |
DS3D::LidarFeatureTensor |
output_coords_tensor_key |
指定输出激光雷达坐标张量键名 |
字符串 |
output_coords_tensor_key: DS3D::LidarCoordTensor |
output_num_tensor_key |
指定输入张量的激光雷达数据数量的键名 |
字符串 |
output_num_tensor_key: DS3D::LidarPointNumTensor |
自定义数据加载器 libnvds_lidarfileread 配置规范#
该库逐帧读取激光雷达数据文件,它为每帧创建一个新的 ds3d::datamap
并传递给下一个组件。源文件位于 /opt/nvidia/deepstream/deepstream/sources/libs/ds3d/dataloader/lidarsource
激光雷达文件读取器
ds3d::dataloader
标头配置name: ds3d_lidar_file_source type: ds3d::dataloader out_caps: ds3d/datamap custom_lib_path: libnvds_lidarfileread.so custom_create_function: createLidarFileLoader
配置主体规范
例如
config_body: data_config_file: lidar_nuscene_data_list.yaml points_num: 242180 fixed_points_num: True lidar_datatype: FP32 mem_type: gpu gpu_id: 0 mem_pool_size: 6 element_size: 4 output_datamap_key: DS3D::LidarXYZI file_loop: True
属性 |
描述 |
类型和范围 |
示例 |
---|---|---|---|
data_config_file |
激光雷达数据列表文件路径 |
路径字符串或路径字符串列表 |
data_config_file: lidar_data_list.yaml |
source_id |
指定加载器实例的唯一源 ID |
整数 |
source_id: 0 |
points_num |
指定每帧的点数 |
整数 |
points_num: 70000 |
fixed_points_num |
指示点数始终与 |
布尔值 |
fixed_points_num: False |
lidar_datatype |
指定激光雷达数据类型 |
字符串,目前仅支持 FP32。 |
lidar_datatype: FP32 |
mem_type |
指定处理数据的内存类型,支持 [cpu, gpu] |
字符串, [cpu, gpu] |
mem_type: gpu |
mem_pool_size |
指定为帧分配的缓冲区池大小 |
整数 |
mem_pool_size: 16 |
gpu_id |
在 |
整数 |
gpu_id: 0 |
element_size |
指定每个点将读取多少个元素。 3 表示 XYZ,4 表示 XYZI。 |
整数 |
element_size: 4 |
element_stride |
指定 2 个连续点之间的元素步幅。例如,XYZI,步幅:4,XYZIT,5 |
整数 |
element_stride: 4 |
file_loop |
指示是否循环文件列表而不带 EOS |
布尔值 |
file_loop: True |
output_datamap_key |
指定输出帧键名到 |
字符串或字符串列表 |
output_datamap_key: DS3D::LidarXYZI_0 |
激光雷达数据配置文件
该库从 data_config_file
读取帧,这是一个单独的文件容器,包含多个激光雷达文件。每个激光雷达文件都是一个单独的激光雷达帧文件,这些文件在 source-list
内部列出。每个项目的键名是激光雷达帧的时间戳(毫秒)。
data_config_file
的示例。
source-list: - 0: /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion/data/nuscene/LIDAR_TOP/000000-LIDAR_TOP.bin - 50: /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion/data/nuscene/LIDAR_TOP/000001-LIDAR_TOP.bin - 100: /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-3d-lidar-sensor-fusion/data/nuscene/LIDAR_TOP/000002-LIDAR_TOP.bin
自定义数据加载器 libnvds_3d_dataloader_realsense 配置规范#
Realsense Dataloader 标头配置
name: realsense_dataloader type: ds3d::dataloader out_caps: ds3d/datamap custom_lib_path: libnvds_3d_dataloader_realsense.so custom_create_function: createRealsenseDataloader
libnvds_3d_dataloader_realsense.so
需要您安装 librealsense2 SDK。 对于 x86,请按照 IntelRealSense/librealsense 中的说明进行操作。 对于 Jetson 平台,请按照 IntelRealSense/librealsense 中的说明进行操作。
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
streams |
指定要启用的流 |
List[String],从 [color, depth] 中选择 |
streams: [color, depth] |
aligned_image_to_depth |
指示颜色图像是否与深度对齐 |
布尔值 |
aligned_image_to_depth: False |
自定义数据过滤器 libnvds_3d_depth2point_datafilter 配置规范#
将 2D 深度数据转换为 3D 点云 (XYZ) 数据到 ds3d::datamap
中
深度到点标头配置
name: depth2points
type: ds3d::datafilter
in_caps: ds3d/datamap
out_caps: ds3d/datamap
custom_lib_path: libnvds_3d_depth2point_datafilter.so
custom_create_function: createDepth2PointFilter
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
streams |
指定要启用的流 |
List[String],从 [color, depth] 中选择 |
streams: [color, depth] |
max_points |
指示要分配的最大 3D 点数 |
Uint32 |
max_points: 407040 |
mem_pool_size |
指示最大缓冲区池大小 |
Uint32 |
mem_pool_size: 8 |
自定义数据渲染器 libnvds_3d_gles_ensemble_render 配置规范#
使用 OpenGL ES (GLES) 渲染 3D 场景,其中包含各种元素(纹理、LiDAR 点、边界框),从而实现灵活的布局自定义。用户可以将窗口拆分为多个视图,并将来自 ds3d::datamap
的每个张量数据或帧投影到单独的视图或同时投影到多个视图中。如果多个帧渲染到单个视图位置重叠,它也可能支持叠加,这取决于渲染图顺序。
配置标头
name: ds3d_sensor_fusion_render
type: ds3d::datarender
in_caps: ds3d/datamap
custom_lib_path: libnvds_3d_gles_ensemble_render.so
custom_create_function: NvDs3D_CreateGlesEnsembleRender
配置主体
具有 render_graph
的多视图配置示例。在同一个 ds3d::datamap
内渲染了 2 个视图。2D 彩色图像由 texture3d_render
渲染到视图区域 [0, 0, 640, 360]
中;LiDAR 数据由 lidar3d_render
渲染到视图区域 [640, 0, 1280, 360]
中。
config_body:
window_width: 1280 # window size
window_height: 360 # window size
color_clear: true
window_title: DS3D-Lidar-6-Cameras-BEVFusion
render_graph:
- texture3d_render: # 2D texture view
layout: [0, 0, 640, 360] # layout [x0, y0, x1, y1]
max_vertex_num: 6
color_clear: false
texture_frame_key: DS3D::ColorFrame_2 # image data key
- lidar3d_render: # lidar top view
layout: [640, 0, 1280, 360] # layout [x0, y0, x1, y1]
color_clear: false
view_position: [0, 0, 30]
view_target: [0, 0, 0]
view_up: [0, 1, 0]
lidar_color: [0, 0, 255]
lidar_data_key: DS3D::LidarXYZI
lidar_bbox_key: DS3D::Lidar3DBboxRawData
element_size: 4
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
window_title |
指定窗口标题 |
字符串 |
window_title: DS3D-Lidar-6-Cameras-BEVFusion |
window_width |
指定窗口宽度 |
uint32 |
window_width: 1920 |
window_height |
指定窗口高度 |
uint32 |
window_height: 1080 |
color_clear |
指定当新帧到达时是否清除整个窗口 |
布尔值 |
color_clear: true |
render_graph |
指定不同视图中多个渲染器的列表 |
List[Dict] |
render_graph:
- texture3d_render:
layout: [0, 0, 640, 360]
color_clear: false
texture_frame_key: DS3D::ColorFrame
- lidar3d_render:
layout: [640, 0, 1280, 360]
color_clear: false
lidar_data_key: DS3D::LidarXYZI
|
渲染图
render_graph
它支持 2 种不同的视图模式
texture3d_render
,它将 2D 图像数据渲染到指定的视图区域。
lidar3d_render
,它将激光雷达数据和 3D 边界框数据渲染到指定的视图区域。
每种模式都可以在同一个 render_graph
中配置多次。单个 ds3d::datamap
内的多个摄像头数据可以配置到不同的视图区域。类似地,同一个 ds3d::datamap
内的多个激光雷达数据也可以在不同的视点(顶视图、前视图、侧视图)配置到不同的视图区域。
texture3d_render
的配置规范
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
layout |
指定 [x0, y0, x1, y1] 的视图位置 |
List[Float] |
layout: [0, 0, 640, 360] x0 = 0; y0 = 0; x1 = 640; y1 = 360; |
color_clear |
指示在新帧到来之前是否清除此视图。 |
布尔值 |
color_clear: false |
texture_frame_key |
从 |
字符串 |
texture_frame_key: DS3D::ColorFrame_1+1 |
max_vertex_num |
指定用于纹理绘制的 vertex_num,默认值为 6 |
uint32 |
max_vertex_num: 6 |
texture_vetex_key |
从 |
字符串 |
texture_vetex_key: DS3D::TextureVertexKey |
texture_coord_key |
从 |
字符串 |
texture_coord_key: DS3D::TextureCoordKey |
lidar3d_render
的配置规范
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
layout |
指定 [x0, y0, x1, y1] 的视图位置 |
List[Float] |
layout: [0, 0, 640, 360] x0 = 0; y0 = 0; x1 = 640; y1 = 360; |
color_clear |
指示在新帧到来之前是否清除此视图。 |
布尔值 |
color_clear: false |
lidar_color |
指定激光雷达数据颜色 RGB |
list[uint8] |
lidar_color: [0, 0, 255] |
lidar_data_key |
从 |
字符串 |
lidar_data_key: DS3D::LidarXYZI+0 |
element_size |
指定激光雷达数据元素大小。从 [3, 4] 中选择,默认值 4 用于 xyzi。值 3 用于 xyz。 |
uint32 |
element_size: 4 |
lidar_bbox_key |
从 |
字符串 |
lidar_bbox_key: DS3D::Lidar3DBboxRawData |
project_lidar_to_image |
指示是否需要将激光雷达数据和边界框投影到相机图像中,默认值:false |
布尔值 |
project_lidar_to_image: false |
intrinsics_mat_key |
从 |
intrinsics_mat_key: DS3D::Cam2_IntrinsicMatrix |
|
extrinsics_mat_key |
从 |
extrinsics_mat_key: DS3D::LidarToCam2_ExtrinsicMatrix |
|
image_width |
指定原始相机内参图像宽度,当 project_lidar_to_image: true 时需要此项 |
image_width: 1600 |
|
image_height |
指定原始相机内参图像高度,当 project_lidar_to_image: true 时需要此项 |
image_height: 900 |
|
view_position |
指定视图位置 [x, y, z] 坐标 |
List[Float] |
view_position: [0, 0, -1] |
view_target |
指定视图目标 [x, y, z] 坐标 |
List[Float] |
view_target: [0, 0, 1] |
view_up |
指定视图向上方向 [x, y, z] 坐标 |
List[Float] |
view_up: [0, -1.0, 0] |
perspective_near |
指定透视投影近平面 |
浮点数 |
perspective_near: 0.1 |
perspective_far |
指定透视投影远平面 |
浮点数 |
perspective_far: 10.0 |
perspective_fov |
指定透视投影视场,角度 |
浮点数 |
perspective_fov: 40.0 |
perspective_ratio |
指定宽度/高度的透视比率。默认值 0.0f 表示视图宽度/视图高度 |
浮点数 |
perspective_ratio: 0.0 |
enable_label |
指示是否启用标签文本渲染。默认值:false |
布尔值 |
enable_label: true |
自定义数据渲染器 libnvds_3d_gl_datarender 配置规范#
libnvds_3d_gl_datarender 的通用标头配置
name: depth-point-render type: ds3d::datarender in_caps: ds3d/datamap custom_lib_path: libnvds_3d_gl_datarender.so
通用部分的配置主体
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
title |
指定窗口标题 |
字符串 |
title: ds3d-point-cloud-test |
streams |
指示要渲染的流。深度渲染必须具有 [depth],3D 点渲染必须具有 [points] |
List[String],从 [color, depth, points] 中选择 |
streams: [color, depth] |
width |
指定窗口宽度 |
UINT32 |
width: 1280 |
height |
指定窗口高度 |
UINT32 |
height: 720 |
block |
指示渲染线程作为阻塞模式 |
布尔值 |
block: True |
点云渲染的配置标头
name: point-3D-render
type: ds3d::datarender
in_caps: ds3d/datamap
custom_lib_path: libnvds_3d_gl_datarender.so
custom_create_function: createPointCloudDataRender # specific function for 3D point rendering
激光雷达数据渲染的配置标头
name: lidar-data-render
type: ds3d::datarender
in_caps: ds3d/datamap
custom_lib_path: libnvds_3d_gl_datarender.so
custom_create_function: createLidarDataRender # specific function for Lidar point cloud rendering
3D 点云和激光雷达渲染部分的配置主体
有关 3D 坐标系的更多详细信息,请参阅 https://learnopengl.com/Getting-started/Coordinate-Systems。要了解 view_position
、view_target
和 view_up
的值含义,请参阅 gluLookAt
:https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml。要了解 near
、far
和 fov
的值含义,请参阅 gluPerspective
:https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml。
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
view_position |
指定视图位置 [x, y, z] 坐标 |
List[Float] |
view_position: [0, 0, -1] |
view_target |
指定视图目标 [x, y, z] 坐标 |
List[Float] |
view_target: [0, 0, 1] |
view_up |
指定视图向上方向 [x, y, z] 坐标 |
List[Float] |
view_up: [0, -1.0, 0] |
near |
指定透视投影近平面 |
浮点数 |
near: 0.01 |
far |
指定透视投影远平面 |
浮点数 |
far: 10.0 |
fov |
指定透视投影视场,角度 |
浮点数 |
fov: 40.0 |
coord_y_opposite |
指定纹理贴图 V 方向,Realsense 坐标与 GLES 默认坐标不同 |
布尔值 |
coord_y_opposite: False |
positive_z_only |
指定是否显示负深度值 |
布尔值 |
positive_z_only: False |
激光雷达渲染特定部分的配置主体
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
view_position |
指定视图位置 [x, y, z] 坐标 |
List[Float] |
view_position: [0, 0, -1] |
view_target |
指定视图目标 [x, y, z] 坐标 |
List[Float] |
view_target: [0, 0, 1] |
view_up |
指定视图向上方向 [x, y, z] 坐标 |
List[Float] |
view_up: [0, -1.0, 0] |
near |
指定透视投影近平面 |
浮点数 |
near: 0.01 |
far |
指定透视投影远平面 |
浮点数 |
far: 10.0 |
fov |
指定透视投影视场,角度 |
浮点数 |
fov: 40.0 |
lidar_color |
指定用于显示的激光雷达数据颜色 |
List[Uint32] |
lidar_color: [0, 255, 0] |
element_size |
指定激光雷达数据元素大小。例如,XYZI 为 4,XYZ 为 3 |
Uint32 |
element_size: 4 |
lidar_data_key |
指定 datamap 中的激光雷达数据帧,默认值为 DS3D::LidarXYZI |
字符串 |
lidar_data_key: DS3D::LidarXYZI |
lidar_bbox_key |
指定 datamap 中的激光雷达 3D 边界框数据,默认值为 DS3D::Lidar3DBboxRawData |
字符串 |
lidar_bbox_key: DS3D::Lidar3DBboxRawData |
深度和彩色 2D 渲染的配置标头
name: depth-2D-render
type: ds3d::datarender
in_caps: ds3d/datamap
custom_lib_path: libnvds_3d_gl_datarender.so
custom_create_function: createDepthStreamDataRender # specific function for 2D depth rendering
深度和彩色 2D 特定部分的配置主体
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
min_depth |
指定最小深度值。小于此值的其他值将在渲染中移除 |
浮点数 |
min_depth: 0.3 |
max_depth |
指定最大深度值。小于此值的其他值将在渲染中移除 |
浮点数 |
max_depth: 2.0 |
min_depth_color |
指定最小深度渲染颜色,格式为 [R, G, B] |
List[Uint32] |
min_depth_color: [255, 128, 0] |
max_depth_color |
指定最大深度渲染颜色,格式为 [R, G, B] |
浮点数 |
max_depth_color: [0, 128, 255] |
libnvds_3d_depth_datasource 深度文件源特定配置规范#
配置标头
name: depthfilesource
type: ds3d::dataloader
out_caps: ds3d/datamap, framerate=30/1
custom_lib_path: libnvds_3d_depth_datasource.so
custom_create_function: createDepthColorLoader
配置主体
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
depth_source |
指定深度源的文件路径 |
字符串 |
depth_source: depth_uint16_640x480.bin |
color_source |
指定彩色图像源的文件路径 |
字符串 |
color_source: color_rgba_1920x1080.bin |
depth_scale |
指示每个深度值的深度单位,单位为米 |
浮点数 |
depth_scale: 0.0010 |
depth_datatype |
指示深度数据类型,此版本仅支持 [uint16] |
字符串,值必须为 uint16 |
depth_datatype: uint16 |
depth_size |
指示深度分辨率,格式为 [宽度, 高度] |
List[Uint32],必须为 [宽度, 高度] |
depth_size: [640, 480] |
color |
指示颜色格式。仅支持 rgba |
字符串。值必须为 rgba |
color: rgba |
color_size |
指示颜色分辨率,格式为 [宽度, 高度] |
List[Uint32],必须为 [宽度, 高度] |
color_size: [1920, 1080] |
depth_intrinsic |
指示深度传感器内参参数组 |
内参配置组 |
|
color_intrinsic |
指示彩色传感器内参参数组 |
内参配置组 |
|
depth_to_color_extrinsic |
指示从深度传感器到彩色传感器的外参参数 |
外参配置组 |
|
内参参数的配置主体
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
width |
指定传感器宽度,单位为像素 |
Uint32 |
width: 848 |
height |
指定传感器高度,单位为像素 |
Uint32 |
height: 480 |
centerX |
指定水平方向的坐标轴位置,单位为像素 |
浮点数 |
centerX: 424.06 |
centerY |
指定垂直方向的坐标轴位置,单位为像素 |
浮点数 |
centerY: 533.28 |
fx |
指定 X 方向的焦距,单位为像素 |
浮点数 |
fx: 1358.21 |
fy |
指定 Y 方向的焦距,单位为像素 |
浮点数 |
fy: 1358.25 |
外参参数的配置主体
属性 |
含义 |
类型和范围 |
示例 |
---|---|---|---|
rotation |
指定用于旋转的外参 3x3 矩阵。值采用列优先顺序 |
List[Float],值采用列优先顺序 |
rotation: [1, -0.0068, 0.0010, 0.0068, 1, 0, -0.0010, 0, 1] |
translation |
指定用于平移的外参 3x1 矩阵。值采用列优先顺序 |
List[Float],值采用列优先顺序 |
translation: [0.01481, -0.0001, 0.0002] |