DeepStream 9.0 的 nvdsosd 增强了两个很实用的显示能力:

  • 基于 mask 的局部模糊
  • OBB(Oriented Bounding Box)旋转框绘制

这两个功能分别解决两个问题:一个用于隐私保护,一个用于更准确地显示旋转目标检测结果。

1. blur-mask:从模糊矩形框到模糊实例区域

过去如果要做隐私保护,例如模糊人脸、车牌或某类目标,常见做法是模糊整个 bounding box。但 bbox 往往包含大量背景区域,效果不够精细。

DeepStream 9.0 在 nvdsosd 中扩展了 blur-bbox 属性:

  g_object_class_install_property (gobject_class, PROP_BLUR_BBOX,
      g_param_spec_uint ("blur-bbox", "Blur Bbox",
          "Blur mode, (0):Disable, (1)blur the entire bbox area of object,\n"
          "\t\t\t(2)Blur the mask area of object if there is a mask, swith to Blur_Bbox if no mask.",
          0, 2, 0,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
              GST_PARAM_MUTABLE_READY)));

含义是:

blur-bbox=0:不模糊

blur-bbox=1:模糊整个 bbox 区域

blur-bbox=2:如果对象有 mask,则只模糊 mask 区域;如果没有 mask,则退回到 bbox 模糊

这对实例分割模型特别有用。例如模型输出 person mask,nvdsosd 就可以只模糊人的真实轮廓区域,而不是模糊整块矩形背景。

源码中,插件会从 object_meta 里取出 bbox 和 mask:

    if (nvdsosd->blur_bbox) {
      if(nvdsosd->blur_gie_class_list != NULL) {
        for(GList *it = nvdsosd->blur_gie_class_list; it; it = it->next) {
          gint gie_id = g_array_index((GArray *)(it->data), gint, 0);
          gint class_id = g_array_index((GArray *)(it->data), gint, 1);
          GST_LOG_OBJECT (nvdsosd,"blur gie %d class %d \n", gie_id, class_id);
          if(object_meta->unique_component_id == gie_id && object_meta->class_id == class_id) {
            nvdsosd->blur_rect_params[blur_cnt] = object_meta->rect_params;
            nvdsosd->mask_params[blur_cnt] = object_meta->mask_params;

最终传给底层 OSD blur 函数:

  if (blur_cnt != 0 && nvdsosd->blur_bbox) {
    nvdsosd->frame_blur_params->num_rects = blur_cnt;
    nvdsosd->frame_blur_params->rect_params_list = nvdsosd->blur_rect_params;
    if(nvdsosd->blur_bbox == Blur_Mask)
      nvdsosd->frame_blur_params->mask_params_list = nvdsosd->mask_params;

底层 nvll_osd 中,blur 只支持 GPU mode:

int nvll_osd_blur_rectangles(NvOSDCtxHandle nvosd_ctx, NvOSD_FrameRectParams *frame_rect_params)
{
    int ret = 0;
    if(frame_rect_params->mode == MODE_GPU)
    {
        ret = nvll_osd_blur_rectangles_gpu(nvosd_ctx, frame_rect_params);
    } else {
        NVOSD_PRINT_E("Blur is only supported on GPU mode, please set the process-mode=1!");

所以使用这个功能时要注意:

nvdsosd process-mode 必须是 GPU mode,也就是 process-mode=1

典型使用场景:

实例分割模型 → object mask → nvdsosd blur-bbox=2 → 只模糊目标轮廓区域

这对于隐私保护很有价值,例如只模糊人脸、人体、车牌、敏感物体区域。

如下图,跟左边的图比起来,右边的mask被模糊了。

2. OBB:支持带角度的旋转矩形框

第二个新功能是 OBB,也就是 Oriented Bounding Box。

传统 bbox 是水平矩形:

left, top, width, height

但很多目标并不是水平放置的,例如:

  • 倾斜车辆
  • 船只
  • 航拍图像中的建筑
  • 旋转文本
  • YOLO OBB 模型输出的旋转目标

如果仍然用水平 bbox,会包含大量背景,显示不准确。OBB 则多了一个角度信息:

left, top, width, height, rotation_angle

yolov11-obb 就属于这种模型:模型不仅输出框的位置和尺寸,还输出旋转角度。

在 nvll_osd 的 CPU 绘制路径中,如果 rotation_angle 非零,会以矩形中心为旋转中心绘制:

    if (fabsf(rect_params->rotation_angle) > 0.001f)
    {
        width = rect_params->width;
        height = rect_params->height;
        // Calculate center point for rotation
        double center_x = x + width / 2.0;
        double center_y = y + height / 2.0;

        // Save current transformation matrix
        cairo_save(cr);

        // Move to center and rotate
        cairo_translate(cr, center_x, center_y);
        cairo_rotate(cr, rect_params->rotation_angle * G_PI / 180.0);

在 GPU 绘制路径中,nvdsosd 会走 cuosd_draw_rotationbox

        if (fabsf(rotation_angle) > 0.001f)
        {
            // OBB path - use cuosd_draw_rotationbox
            float center_x = (x1 + x2) / 2.0f;
            float center_y = (y1 + y2) / 2.0f;
            int width = x2 - x1;
            int height = y2 - y1;
            float yaw_rad = rotation_angle * M_PI / 180.0f;

            cuosd_draw_rotationbox(ctx->cuosd_context,

cuosd_draw_rotationbox 会根据中心点、宽高和旋转角计算四个角点:

void cuosd_draw_rotationbox(
    cuOSDContext_t _context, int cx, int cy, int width, int height, float yaw, int thickness, cuOSDColor border_color, bool interpolation, cuOSDColor bg_color
) {
    cuOSDContextImpl* context = (cuOSDContextImpl*)_context;
    if (border_color.a == 0) return;

    // a   d
    //   o
    // b   c

    float pax = -width / 2.0f;

这意味着应用不再需要把 OBB 近似成水平框,只要 metadata 中的 rect_params.rotation_angle 被正确设置,nvdsosd 就能画出旋转框。

对应用开发者意味着什么?

使用 blur-mask

如果模型输出 instance mask,并且希望进行更精细的隐私保护,可以配置:

nvdsosd process-mode=1

nvdsosd blur-bbox=2

如果只想模糊某个 GIE 的某些类别,还可以使用:

blur-on-gie-class-ids

它会根据 unique_component_id 和 class_id 过滤目标。

使用 OBB

如果使用 OBB 检测模型,例如 YOLO OBB 系列,需要保证 custom bbox parser 把角度写入检测结果。随后 DeepStream metadata 会把这个角度传到 NvOSD_RectParams.rotation_anglenvdsosd 负责最终绘制。

对用户来说,OSD 层的使用方式很自然:

模型输出旋转框

→ parser 填充 rotation angle

→ nvinfer 生成 object metadata

→ nvdsosd 根据 rotation_angle 绘制旋转框

如下图,nvdsosd画了一些斜着的bounding boxes.

总结

DeepStream 9.0 的 nvdsosd 新功能让显示层更适合现代视觉 AI 模型:

blur-mask 让隐私保护更精细,从“模糊整个矩形框”升级为“按实例 mask 模糊真实目标区域”。

OBB support 让旋转目标检测结果可以被准确显示,不再需要把旋转目标强行近似成水平 bbox。

这两个能力都体现了一个趋势:DeepStream 的 OSD 不只是画普通框和文字,而是在适配更复杂的视觉模型输出,例如实例分割和旋转框检测。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐