可视化
Holoviz 提供了将帧的实时流与多个不同的其他层(如分割掩码层、几何层和 GUI 层)进行合成的功能。
为了获得最佳性能,Holoviz 使用了 Vulkan,它已经作为 NVIDIA GPU 驱动程序的一部分安装。
Holoscan 提供了 Holoviz 算子,它足以满足许多甚至复杂的可视化任务。Holoviz 算子 被多个 Holoscan 示例应用程序 使用。
此外,对于更高级的用例,可以使用 Holoviz 模块 来创建特定于应用程序的可视化算子。Holoviz 模块 提供了 C++ API,并且也被 Holoviz 算子 使用。
术语 Holoviz 用于指代 Holoviz 算子 和 Holoviz 模块。算子和模块大致支持相同的功能集。在适用的情况下,会提供有关如何将功能与算子和模块一起使用的信息。当算子不支持某些功能时,将在下面明确提及。
Holoviz 的核心实体是层。层是一个二维图像对象。多个层被合成为最终输出。
Holoviz 支持以下层类型
图像层
几何层
GUI 层
所有层都具有通用属性,这些属性定义了外观以及最终合成层的方式。
优先级决定了层的渲染顺序。在渲染之前,层按优先级排序。优先级最低的层首先渲染,因此优先级最高的层渲染在所有其他层之上。如果层具有相同的优先级,则这些层的渲染顺序未定义。
下面的示例在图像层之上绘制了一个透明的几何层(代码中省略了几何数据和图像数据的创建)。尽管几何层首先被指定,但由于其优先级 (1
) 高于图像层 (0
),因此它是最后绘制的。
算子有一个 receivers
端口,它接受其他算子生成的张量和视频缓冲区。每个张量或视频缓冲区将产生一个层。
对于某些输入类型(例如,视频缓冲区将产生图像层),算子会自动检测层类型。
对于其他输入类型或更复杂的用例,可以在初始化时作为参数提供输入规范,或者在运行时动态提供。
std::vector<ops::HolovizOp::InputSpec> input_specs;
auto& geometry_spec =
input_specs.emplace_back(ops::HolovizOp::InputSpec("point_tensor", ops::HolovizOp::InputType::POINTS));
geometry_spec.priority_ = 1;
geometry_spec.opacity_ = 0.5;
auto& image_spec =
input_specs.emplace_back(ops::HolovizOp::InputSpec("image_tensor", ops::HolovizOp::InputType::IMAGE));
image_spec.priority_ = 0;
auto visualizer = make_operator<ops::HolovizOp>("holoviz", Arg("tensors", input_specs));
// the source provides two tensors named "point_tensor" and "image_tensor" at the "outputs" port.
add_flow(source, visualizer, {{"outputs", "receivers"}});
层的定义从调用层开始函数 viz::BeginImageLayer()
、viz::BeginGeometryLayer()
或 viz::BeginImGuiLayer()
之一开始。层定义以 viz::EndLayer()
结束。
层定义的开始是将层属性(如优先级和不透明度)重置为其默认值。因此,对于图像层,无需将不透明度设置为 1.0
,因为默认值已经是 1.0
。
namespace viz = holoscan::viz;
viz::Begin();
viz::BeginGeometryLayer();
viz::LayerPriority(1);
viz::LayerOpacity(0.5);
/// details omitted
viz::EndLayer();
viz::BeginImageLayer();
viz::LayerPriority(0);
/// details omitted
viz::EndLayer();
viz::End();
图像层
图像数据可以在主机或设备 (GPU) 上;张量和视频缓冲区都被接受。
std::vector<ops::HolovizOp::InputSpec> input_specs;
auto& image_spec =
input_specs.emplace_back(ops::HolovizOp::InputSpec("image", ops::HolovizOp::InputType::IMAGE));
auto visualizer = make_operator<ops::HolovizOp>("holoviz", Arg("tensors", input_specs));
// the source provides an image named "image" at the "outputs" port.
add_flow(source, visualizer, {{"output", "receivers"}});
函数 viz::BeginImageLayer()
启动一个图像层。图像层显示一个矩形 2D 图像。
图像数据通过调用 viz::ImageCudaDevice()
、viz::ImageCudaArray()
或 viz::ImageHost()
定义。支持各种输入格式,请参阅 viz::ImageFormat
。
对于单通道图像格式,可以通过使用 viz::LUT()
定义查找表来查找图像颜色。
viz::BeginImageLayer();
viz::ImageHost(width, height, format, data);
viz::EndLayer();
支持的图像格式
为 nvidia::gxf::VideoBuffer
支持的格式。
nvidia::gxf::VideoFormat | 支持 | 描述 |
---|---|---|
GXF_VIDEO_FORMAT_CUSTOM | - | |
GXF_VIDEO_FORMAT_YUV420 | ✓ | BT.601 多平面 4:2:0 YUV |
GXF_VIDEO_FORMAT_YUV420_ER | ✓ | BT.601 多平面 4:2:0 YUV ER |
GXF_VIDEO_FORMAT_YUV420_709 | ✓ | BT.709 多平面 4:2:0 YUV |
GXF_VIDEO_FORMAT_YUV420_709_ER | ✓ | BT.709 多平面 4:2:0 YUV ER |
GXF_VIDEO_FORMAT_NV12 | ✓ | BT.601 多平面 4:2:0 YUV,带交错 UV |
GXF_VIDEO_FORMAT_NV12_ER | ✓ | BT.601 多平面 4:2:0 YUV ER,带交错 UV |
GXF_VIDEO_FORMAT_NV12_709 | ✓ | BT.709 多平面 4:2:0 YUV,带交错 UV |
GXF_VIDEO_FORMAT_NV12_709_ER | ✓ | BT.709 多平面 4:2:0 YUV ER,带交错 UV |
GXF_VIDEO_FORMAT_RGBA | ✓ | RGBA-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_BGRA | ✓ | BGRA-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_ARGB | ✓ | ARGB-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_ABGR | ✓ | ABGR-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_RGBX | ✓ | RGBX-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_BGRX | ✓ | BGRX-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_XRGB | ✓ | XRGB-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_XBGR | ✓ | XBGR-8-8-8-8 单平面 |
GXF_VIDEO_FORMAT_RGB | ✓ | RGB-8-8-8 单平面 |
GXF_VIDEO_FORMAT_BGR | ✓ | BGR-8-8-8 单平面 |
GXF_VIDEO_FORMAT_R8_G8_B8 | - | RGB - 无符号 8 位多平面 |
GXF_VIDEO_FORMAT_B8_G8_R8 | - | BGR - 无符号 8 位多平面 |
GXF_VIDEO_FORMAT_GRAY | ✓ | 8 位灰度单平面 |
GXF_VIDEO_FORMAT_GRAY16 | ✓ | 16 位灰度单平面 |
GXF_VIDEO_FORMAT_GRAY32 | - | 32 位灰度单平面 |
GXF_VIDEO_FORMAT_GRAY32F | ✓ | float 32 位灰度单平面 |
GXF_VIDEO_FORMAT_RGB16 | - | RGB-16-16-16 单平面 |
GXF_VIDEO_FORMAT_BGR16 | - | BGR-16-16-16 单平面 |
GXF_VIDEO_FORMAT_RGB32 | - | RGB-32-32-32 单平面 |
GXF_VIDEO_FORMAT_BGR32 | - | BGR-32-32-32 单平面 |
GXF_VIDEO_FORMAT_R16_G16_B16 | - | RGB - 有符号 16 位多平面 |
GXF_VIDEO_FORMAT_B16_G16_R16 | - | BGR - 有符号 16 位多平面 |
GXF_VIDEO_FORMAT_R32_G32_B32 | - | RGB - 有符号 32 位多平面 |
GXF_VIDEO_FORMAT_B32_G32_R32 | - | BGR - 有符号 32 位多平面 |
GXF_VIDEO_FORMAT_NV24 | - | 多平面 4:4:4 YUV,带交错 UV |
GXF_VIDEO_FORMAT_NV24_ER | - | 多平面 4:4:4 YUV ER,带交错 UV |
GXF_VIDEO_FORMAT_R8_G8_B8_D8 | - | RGBD 无符号 8 位多平面 |
GXF_VIDEO_FORMAT_R16_G16_B16_D16 | - | RGBD 无符号 16 位多平面 |
GXF_VIDEO_FORMAT_R32_G32_B32_D32 | - | RGBD 无符号 32 位多平面 |
GXF_VIDEO_FORMAT_RGBD8 | - | RGBD 8 位无符号单平面 |
GXF_VIDEO_FORMAT_RGBD16 | - | RGBD 16 位无符号单平面 |
GXF_VIDEO_FORMAT_RGBD32 | - | RGBD 32 位无符号单平面 |
GXF_VIDEO_FORMAT_D32F | ✓ | 深度 32 位浮点单平面 |
GXF_VIDEO_FORMAT_D64F | - | 深度 64 位浮点单平面 |
GXF_VIDEO_FORMAT_RAW16_RGGB | - | RGGB-16-16-16-16 单平面 |
GXF_VIDEO_FORMAT_RAW16_BGGR | - | BGGR-16-16-16-16 单平面 |
GXF_VIDEO_FORMAT_RAW16_GRBG | - | GRBG-16-16-16-16 单平面 |
GXF_VIDEO_FORMAT_RAW16_GBRG | - | GBRG-16-16-16-16 单平面 |
用于 nvidia::gxf::Tensor
的图像格式检测。张量没有附加图像格式信息。Holoviz 算子从张量配置中检测图像格式。
nvidia::gxf::PrimitiveType | 通道 | 颜色格式 | 颜色查找索引 |
---|---|---|---|
kUnsigned8 | 1 | 8 位灰度单平面 | ✓ |
kInt8 | 1 | 有符号 8 位灰度单平面 | ✓ |
kUnsigned16 | 1 | 16 位灰度单平面 | ✓ |
kInt16 | 1 | 有符号 16 位灰度单平面 | ✓ |
kUnsigned32 | 1 | - | ✓ |
kInt32 | 1 | - | ✓ |
kFloat32 | 1 | float 32 位灰度单平面 | ✓ |
kUnsigned8 | 3 | RGB-8-8-8 单平面 | - |
kInt8 | 3 | 有符号 RGB-8-8-8 单平面 | - |
kUnsigned8 | 4 | RGBA-8-8-8-8 单平面 | - |
kInt8 | 4 | 有符号 RGBA-8-8-8-8 单平面 | - |
kUnsigned16 | 4 | RGBA-16-16-16-16 单平面 | - |
kInt16 | 4 | 有符号 RGBA-16-16-16-16 单平面 | - |
kFloat32 | 4 | RGBA float 32 单平面 | - |
有关支持的图像格式,请参阅 viz::ImageFormat
。此外,viz::ImageComponentMapping()
可用于将图像的颜色分量映射到输出的颜色分量。
几何层
几何层用于绘制 2d 或 3d 几何图元。2d 图元是点、线、线段、矩形、椭圆或文本,并使用 2d 坐标 (x, y) 定义。3d 图元是点、线、线段或三角形,并使用 3d 坐标 (x, y, z) 定义。
对于 2d 图元,坐标从左上角的 (0, 0) 开始,到右下角的 (1, 1) 结束。
有关 2d 几何图元,请参阅 holoviz_geometry.cpp 和 holoviz_geometry.py,有关 3d 几何图元,请参阅 holoviz_geometry.py。
函数 viz::BeginGeometryLayer()
启动一个几何层。
有关支持的几何图元拓扑,请参阅 viz::PrimitiveTopology
。
有一些函数可以设置几何图元的属性,例如颜色 (viz::Color()
)、线宽 (viz::LineWidth()
) 和点大小 (viz::PointSize()
)。
下面的代码绘制了一个红色矩形和一个绿色文本。
namespace viz = holoscan::viz;
viz::BeginGeometryLayer();
// draw a red rectangle
viz::Color(1.f, 0.f, 0.f, 0.f);
const float data[]{0.1f, 0.1f, 0.9f, 0.9f};
viz::Primitive(viz::PrimitiveTopology::RECTANGLE_LIST, 1, sizeof(data) / sizeof(data[0]), data);
// draw green text
viz::Color(0.f, 1.f, 0.f, 0.f);
viz::Text(0.5f, 0.5f, 0.2f, "Text");
viz::EndLayer();
ImGui 层
使用 Holoviz 算子时,不支持 ImGui 层。
Holoviz 模块支持使用 Dear ImGui 创建的用户界面层。
对 Dear ImGui API 的调用允许在 viz::BeginImGuiLayer()
和 viz::EndImGuiLayer()
之间进行,并用于绘制到 ImGui 层。ImGui 层的行为与其他层类似,并以层的不透明度和优先级进行渲染。
下面的代码创建了一个 Dear ImGui 窗口,其中包含一个复选框,用于有条件地显示图像层。
namespace viz = holoscan::viz;
bool show_image_layer = false;
while (!viz::WindowShouldClose()) {
viz::Begin();
viz::BeginImGuiLayer();
ImGui::Begin("Options");
ImGui::Checkbox("Image layer", &show_image_layer);
ImGui::End();
viz::EndLayer();
if (show_image_layer) {
viz::BeginImageLayer();
viz::ImageHost(...);
viz::EndLayer();
}
viz::End();
}
ImGUI 是一个静态库,没有稳定的 API。因此,应用程序和 Holoviz 必须使用相同的 ImGUI 版本。当导出链接目标 holoscan::viz::imgui
时,请确保将您的应用程序链接到该目标。
深度图层
深度图是单通道 2d 数组,其中每个元素代表一个深度值。数据使用点、线或三角形渲染为 3D 对象。还可以指定元素的颜色。
深度图支持的格式
具有单个 8 位深度分量的 8 位无符号归一化格式
具有单个 32 位深度分量的 32 位有符号浮点格式
深度颜色图支持的格式
32 位无符号归一化格式,在字节 0 中具有 8 位 R 分量,在字节 1 中具有 8 位 G 分量,在字节 2 中具有 8 位 B 分量,在字节 3 中具有 8 位 A 分量
深度图以 3D 渲染,并支持相机移动。
std::vector<ops::HolovizOp::InputSpec> input_specs;
auto& depth_map_spec =
input_specs.emplace_back(ops::HolovizOp::InputSpec("depth_map", ops::HolovizOp::InputType::DEPTH_MAP));
depth_map_spec.depth_map_render_mode_ = ops::HolovizOp::DepthMapRenderMode::TRIANGLES;
auto visualizer = make_operator<ops::HolovizOp>("holoviz",
Arg("tensors", input_specs));
// the source provides an depth map named "depth_map" at the "output" port.
add_flow(source, visualizer, {{"output", "receivers"}});
请参阅 holoviz 深度图演示。
默认情况下,层将填充整个窗口。当使用视图时,层可以自由放置在窗口内。
通过指定 3D 变换矩阵,层也可以放置在 3D 空间中。
对于几何层,有一个默认矩阵,它允许坐标范围为 [0 … 1],而不是 Vulkan 的 [-1 … 1] 范围。当为几何层指定矩阵时,此默认矩阵将被覆盖。
当指定多个视图时,该层将使用指定的层视图绘制多次。
可以为高度指定负值项,这将翻转图像。当使用负高度时,您还应该调整 y 值以指向视口的左下角而不是左上角。
请参阅 holoviz_views.py。
使用 viz::LayerAddView()
向层添加视图。
当使用具有 3d 图元的几何层或深度图层渲染 3d 几何体时,相机属性可以由应用程序设置,也可以由用户交互式更改。
要交互式更改相机,请使用鼠标
轨道 (LMB)
平移 (LMB + CTRL | MMB)
推拉 (LMB + SHIFT | RMB | 鼠标滚轮)
环顾四周 (LMB + ALT | LMB + CTRL + SHIFT)
缩放 (鼠标滚轮 + SHIFT)
请参阅 holoviz_camera.cpp。
使用 viz::SetCamera()
更改相机。
通常,Holoviz 在 Linux 桌面上打开一个普通窗口。在这种情况下,桌面合成器将 Holoviz 图像与桌面上的所有其他元素组合在一起。为了避免额外的合成步骤,Holoviz 可以直接渲染到显示器。
配置显示器以供独占使用
SSH 进入机器并停止 X 服务器
sudo systemctl stop display-manager
要恢复 显示管理器
,请运行
sudo systemctl start display-manager
要在独占模式下使用的显示器需要在 NVIDIA 设置应用程序 (nvidia-settings
) 中禁用:打开 X Server Display Configuration
选项卡,选择显示器,然后在 Configuration
下选择 Disabled
。按 Apply
。
在 Holoviz 中启用独占显示器
传递给 Holoviz 算子的参数
auto visualizer = make_operator<ops::HolovizOp>("holoviz",
Arg("use_exclusive_display", true), // required
Arg("display_name", "DP-2"), // optional
Arg("width", 2560), // optional
Arg("height", 1440), // optional
Arg("framerate", 240) // optional
);
将显示器的名称和所需的显示模式属性提供给 viz::Init()
。
如果名称为 nullptr
,则选择第一个显示器。
显示器的名称可以是 NVIDIA 设置中显示的 EDID 名称,也可以是 xrandr
或 hwinfo --monitor
提供的输出名称。
在此 xrandr
的示例输出中,DP-2
将是适合使用的显示器名称
Screen 0: minimum 8 x 8, current 4480 x 1440, maximum 32767 x 32767
DP-0 disconnected (normal left inverted right x axis y axis)
DP-1 disconnected (normal left inverted right x axis y axis)
DP-2 connected primary 2560x1440+1920+0 (normal left inverted right x axis y axis) 600mm x 340mm
2560x1440 59.98 + 239.97* 199.99 144.00 120.00 99.95
1024x768 60.00
800x600 60.32
640x480 59.94
USB-C-0 disconnected (normal left inverted right x axis y axis)
在此 hwinfo
的示例输出中,`MSI MPG343CQR 将是适合使用的显示器名称
$ hwinfo --monitor | grep Model
Model: "MSI MPG343CQR"
默认情况下,Holoviz 对所有 CUDA 操作使用 CUDA 流 0
。使用默认流可能会影响 CUDA 操作的并发性,有关更多信息,请参阅 流同步行为。
如果 cuda_stream_pool
参数提供了 holoscan::CudaStreamPool
实例,则算子将使用该实例。流池用于创建 Holoviz 所有操作使用的 CUDA 流。
const std::shared_ptr<holoscan::CudaStreamPool> cuda_stream_pool =
make_resource<holoscan::CudaStreamPool>("cuda_stream", 0, 0, 0, 1, 5);
auto visualizer =
make_operator<holoscan::ops::HolovizOp>("visualizer",
Arg("cuda_stream_pool") = cuda_stream_pool);
当通过 (例如,viz::ImageCudaDevice()
) 向 Holoviz 提供 CUDA 资源时,Holoviz 将使用 CUDA 操作来使用该内存。可以通过调用 viz::SetCudaStream()
来设置这些操作使用的 CUDA 流。流可以随时更改。
可以读回渲染的帧缓冲区。这在进行离屏渲染或在无头环境中运行 Holoviz 时非常有用。
使用 Holoviz 算子时,不支持读取深度缓冲区。
要读回颜色帧缓冲区,请将 enable_render_buffer_output
参数设置为 true
,并为算子提供分配器。
帧缓冲区在 render_buffer_output
端口上发出。
std::shared_ptr<holoscan::ops::HolovizOp> visualizer =
make_operator<ops::HolovizOp>("visualizer",
Arg("enable_render_buffer_output", true),
Arg("allocator") = make_resource<holoscan::UnboundedAllocator>("allocator"),
Arg("cuda_stream_pool") = cuda_stream_pool);
add_flow(visualizer, destination, {{"render_buffer_output", "input"}});
可以使用 viz::ReadFramebuffer()
读回渲染的颜色或深度缓冲区。
图像和帧缓冲区都支持 sRGB 色彩空间。默认情况下,Holoviz 使用线性编码的帧缓冲区。
要切换帧缓冲区颜色格式,请将 framebuffer_srgb
参数设置为 true
。
要使用 sRGB 编码的图像,请将 InputSpec
结构的 image_format
字段设置为 sRGB 图像格式。
使用 viz::SetSurfaceFormat()
将帧缓冲区表面格式设置为 sRGB 颜色格式。
要使用 sRGB 编码的图像,请将 viz::ImageCudaDevice()
、viz::ImageCudaArray()
或 viz::ImageHost()
的 fmt
参数设置为 sRGB 图像格式。
Holoviz 支持选择帧缓冲区表面图像格式和色彩空间。要启用 HDR,请选择 HDR 色彩空间。
将 framebuffer_color_space
参数设置为支持的 HDR 色彩空间。
使用 viz::GetSurfaceFormats()
查询可用的表面格式。
使用 viz::SetSurfaceFormat()
将帧缓冲区表面格式设置为具有 HDR 色彩空间的表面格式。
支持 HDR 的发行版
在撰写本文时 (2024 年 8 月),目前 Linux 上尚无官方 HDR 支持。但是,Gnome 44 版和 KDE Plasma 6 具有实验性 HDR 支持。
KDE Plasma 6
此 博客文章 中描述了实验性 HDR 支持。将 HDR 与 Holoviz 一起使用需要三个步骤
在显示配置中启用 HDR
安装 Vulkan HDR 层
将
ENABLE_HDR_WSI
环境变量设置为1
。
运行 vulkaninfo
以验证是否报告了 HDR 色彩空间
> vulkaninfo
...
GPU id : 0 (NVIDIA RTX 6000 Ada Generation):
Surface type = VK_KHR_wayland_surface
Formats: count = 11
SurfaceFormat[0]:
format = FORMAT_A2B10G10R10_UNORM_PACK32
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[1]:
format = FORMAT_A2R10G10B10_UNORM_PACK32
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[2]:
format = FORMAT_R8G8B8A8_SRGB
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[3]:
format = FORMAT_R8G8B8A8_UNORM
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[4]:
format = FORMAT_B8G8R8A8_SRGB
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[5]:
format = FORMAT_B8G8R8A8_UNORM
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[6]:
format = FORMAT_R16G16B16A16_SFLOAT
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR
SurfaceFormat[7]:
format = FORMAT_A2B10G10R10_UNORM_PACK32
colorSpace = COLOR_SPACE_HDR10_ST2084_EXT
SurfaceFormat[8]:
format = FORMAT_A2R10G10B10_UNORM_PACK32
colorSpace = COLOR_SPACE_HDR10_ST2084_EXT
SurfaceFormat[9]:
format = FORMAT_R16G16B16A16_SFLOAT
colorSpace = COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
SurfaceFormat[10]:
format = FORMAT_R16G16B16A16_SFLOAT
colorSpace = COLOR_SPACE_BT709_LINEAR_EXT
...
Gnome 44 版
Gnome 44 版是 Ubuntu 24.04 的一部分。
此 MR 添加了实验性 HDR 支持。要启用 HDR,请确保使用 Wayland(X11 没有 HDR),按 Alt+F2
,然后在提示符中键入 lg
以启动 looking glass
控制台。输入 global.compositor.backend.get_monitor_manager().experimental_hdr = 'on'
以启用 HDR,global.compositor.backend.get_monitor_manager().experimental_hdr = 'off'
以禁用 HDR。
Gnome 尚未将 HDR 色彩空间传递给 Vulkan。可以使用 drm_info
查询色彩空间和其他信息,检查 HDR_OUTPUT_METADATA
不为 0
的模式。
对于以下情况(Microstep MSI MPG343CQR
显示器),HDR 色彩空间为 BT2020_RGB
,EOTF 为 SMPTE ST 2084 (PQ)
。最大亮度为 446 尼特。
> drm_info | grep -B 1 -A 11 HDR
...
│ │ ├───"Colorspace": enum {Default, BT2020_RGB, BT2020_YCC} = BT2020_RGB
│ │ ├───"HDR_OUTPUT_METADATA": blob = 114
│ │ │ ├───Type: Static Metadata Type 1
│ │ │ ├───EOTF: SMPTE ST 2084 (PQ)
│ │ │ ├───Display primaries:
│ │ │ │ ├───Red: (0.6768, 0.3096)
│ │ │ │ ├───Green: (0.2764, 0.6445)
│ │ │ │ └───Blue: (0.1514, 0.0693)
│ │ │ ├───White point: (0.3135, 0.3291)
│ │ │ ├───Max display mastering luminance: 446 cd/m²
│ │ │ ├───Min display mastering luminance: 0.0001 cd/m²
│ │ │ ├───Max content light level: 446 cd/m²
│ │ │ └───Max frame average light level: 446 cd/m²
-
...
回调可用于接收有关按键、鼠标位置和按钮以及窗口大小的更新。
C++
visualizer = make_operator<ops::HolovizOp>(
"holoviz",
Arg("key_callback",
ops::HolovizOp::KeyCallbackFunction([](ops::HolovizOp::Key key,
ops::HolovizOp::KeyAndButtonAction action,
ops::HolovizOp::KeyModifiers modifiers) -> void {
HOLOSCAN_LOG_INFO(
"key {} action {} modifiers {}", int(key), int(action), *(uint32_t*)(&modifiers));
}))
)
Python
def callback(
key: HolovizOp.Key, action: HolovizOp.KeyAndButtonAction, modifiers: HolovizOp.KeyModifiers
):
print(key, action, modifiers)
visualizer = HolovizOp(
self,
name="holoviz",
key_callback=callback)
void key_callback(void *user_pointer, Key key, KeyAndButtonAction action, KeyModifiers modifiers) {
...
}
...
viz::SetKeyCallback(user_pointer, &key_callback);
...
概念
Holoviz 模块的 API 使用即时模式设计模式的概念,灵感来自 Dear ImGui 库。与保留模式(大多数 API 都为此设计)的不同之处在于,应用程序不会创建和存储对象。这使得在 Holoscan 应用程序中快速轻松地进行可视化更改。
实例
Holoviz 模块使用线程本地实例对象来存储其内部状态。当首次从线程调用 Holoviz 模块时,将创建实例对象。从该线程调用的所有 Holoviz 模块函数都使用此实例。
当从 Holoviz 模块函数首次调用的线程以外的其他线程调用 Holoviz 模块时,请确保在相应的线程中调用 viz::GetCurrent()
和 viz::SetCurrent()
。
在某些使用情况下,需要多个实例;例如,打开多个窗口。可以通过调用 viz::Create()
来创建实例。在调用要为实例所属窗口执行的 Holoviz 模块函数之前,调用 viz::SetCurrent()
使该实例成为当前实例。
入门指南
下面的代码创建了一个窗口并显示图像。
首先,需要初始化 Holoviz 模块。这通过调用 viz::Init()
完成。
要显示的元素在渲染循环中定义;循环的终止使用 viz::WindowShouldClose()
检查。
显示内容的定义以 viz::Begin()
开始,并以 viz::End()
结束。viz::End()
启动渲染并显示渲染结果。
最后,使用 viz::Shutdown()
关闭 Holoviz 模块。
#include "holoviz/holoviz.hpp"
namespace viz = holoscan::viz;
viz::Init("Holoviz Example");
while (!viz::WindowShouldClose()) {
viz::Begin();
viz::BeginImageLayer();
viz::ImageHost(width, height, viz::ImageFormat::R8G8B8A8_UNORM, image_data);
viz::EndLayer();
viz::End();
}
viz::Shutdown();
结果

图 20 Holoviz 示例应用程序
API
Holoviz 模块示例
有多个 示例 展示了如何使用 Holoviz 模块的各种功能。