Openpcdet 系列 Pointpillar代码逐行解析之POST_PROCESSING模块

这篇具有很好参考价值的文章主要介绍了Openpcdet 系列 Pointpillar代码逐行解析之POST_PROCESSING模块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Openpcdet 的POST_PROCESSING模块

dpm_postprocessing,OpenPCDet专栏,目标检测,python,计算机视觉,目标跟踪,人工智能

在OpenPCDet中,POST_PROCESSING模块是用于在模型输出的点云检测结果上进行后处理的组件。

该模块主要负责对检测结果进行滤波、聚类、追踪等操作,以提高检测的准确性和稳定性。

POST_PROCESSING模块通常包含以下几个主要的子模块或步骤:

  1. 点云滤波(Point Cloud Filtering):这一步骤用于去除原始点云中的噪声和离群点,常用的滤波方法包括体素下采样(Voxel Downsampling)、统计滤波(Statistical Outlier Removal)等。

  2. 检测框聚类(Box Clustering):在一些场景中,模型可能会输出多个相似的检测框,这些框可能对应着同一个物体。通过聚类算法,可以将这些相似的框归为一类,从而得到更准确的检测结果。

  3. 对象追踪(Object Tracking):在连续帧的点云数据中,通过追踪算法可以将同一个物体在不同帧之间进行关联,从而实现物体的连续跟踪。常用的追踪算法包括卡尔曼滤波(Kalman Filtering)、匈牙利算法(Hungarian Algorithm)等。

  4. 检测结果过滤(Detection Result Filtering):根据应用需求,可以对最终的检测结果进行进一步过滤,例如根据置信度阈值进行筛选,去除不满足要求的检测结果。

Pointpillar POST_PROCESSING 配置文件

    POST_PROCESSING:
        RECALL_THRESH_LIST: [0.3, 0.5, 0.7]
        SCORE_THRESH: 0.1
        OUTPUT_RAW_SCORE: False

        EVAL_METRIC: kitti

        NMS_CONFIG:
            MULTI_CLASSES_NMS: False
            NMS_TYPE: nms_gpu
            NMS_THRESH: 0.01
            NMS_PRE_MAXSIZE: 4096
            NMS_POST_MAXSIZE: 500
  1. RECALL_THRESH_LIST: [0.3, 0.5, 0.7]:分别代表 [‘Car’, ‘Pedestrian’, ‘Cyclist’] 这是一个召回阈值列表,用于评估检测结果的召回率。在评估过程中,将计算不同召回阈值下的召回率,并输出相应的指标。

  2. SCORE_THRESH: 0.1:这是一个得分阈值,用于过滤检测结果。只有得分高于该阈值的检测结果才会被保留,低于阈值的结果将被丢弃。

  3. OUTPUT_RAW_SCORE: False:这是一个布尔值参数,用于指定是否在输出结果中包含原始的检测得分。如果设置为True,则在输出结果中将包含原始得分;如果设置为False,则只输出二值化的检测结果。

  4. EVAL_METRIC: kitti:这是一个评估指标的选择,用于衡量检测结果的性能。在这种情况下,选择了Kitti评估指标,该指标通常用于衡量目标检测在Kitti数据集上的性能。

  5. NMS_CONFIG:这是一个配置NMS(非极大值抑制)的子模块,用于在检测结果中进行框的合并和过滤。

  6. MULTI_CLASSES_NMS: False:这是一个布尔值参数,用于指定是否对多类别进行NMS。如果设置为True,则会对多个类别的检测框进行NMS;如果设置为False,则只对同一类别的检测框进行NMS。

  7. NMS_TYPE: nms_gpu:这是NMS算法的选择。在这种情况下,选择了nms_gpu算法,该算法使用GPU加速执行NMS操作。

  8. NMS_THRESH: 0.01:这是NMS的阈值,用于控制重叠度的判定。当两个框的重叠度高于该阈值时,较低得分的框将被抑制。

  9. NMS_PRE_MAXSIZE: 4096:这是NMS操作之前,每个类别最大保留的检测框数量。如果超过该数量,将根据得分进行排序并截断。

  10. NMS_POST_MAXSIZE: 500:这是NMS操作之后,每个类别最大保留的检测框数量。如果超过该数量,将根据得分进行排序并截断。

POST_PROCESSING 代码讲解

代码在OpenPCDet/pcdet/models/detectors/detector3d_template.py下面

    def post_processing(self, batch_dict):
        """
        Args:
            batch_dict:
                batch_size:
                batch_cls_preds: (B, num_boxes, num_classes | 1) or (N1+N2+..., num_classes | 1)
                                or [(B, num_boxes, num_class1), (B, num_boxes, num_class2) ...]
                multihead_label_mapping: [(num_class1), (num_class2), ...]
                batch_box_preds: (B, num_boxes, 7+C) or (N1+N2+..., 7+C)
                cls_preds_normalized: indicate whether batch_cls_preds is normalized
                batch_index: optional (N1+N2+...)
                has_class_labels: True/False
                roi_labels: (B, num_rois)  1 .. num_classes
                batch_pred_labels: (B, num_boxes, 1)
        Returns:
		        pred_dicts: 一个包含预测结果的列表,每个元素是一个字典,包含了预测框的坐标、得分和类别
        		recall_dict: 一个包含召回率信息的字典,用于评估检测结果的召回率
        """
        post_process_cfg = self.model_cfg.POST_PROCESSING
        batch_size = batch_dict['batch_size']
        recall_dict = {}
        pred_dicts = []
        
        for index in range(batch_size):
        # 根据是否包含batch_index来确定box_preds的形状
            if batch_dict.get('batch_index', None) is not None:
                assert batch_dict['batch_box_preds'].shape.__len__() == 2
                batch_mask = (batch_dict['batch_index'] == index)
            else:
                assert batch_dict['batch_box_preds'].shape.__len__() == 3
                batch_mask = index

            box_preds = batch_dict['batch_box_preds'][batch_mask]
            src_box_preds = box_preds
            # 处理分类预测结果
            if not isinstance(batch_dict['batch_cls_preds'], list):
                cls_preds = batch_dict['batch_cls_preds'][batch_mask]

                src_cls_preds = cls_preds
                assert cls_preds.shape[1] in [1, self.num_class]

                if not batch_dict['cls_preds_normalized']:
                    cls_preds = torch.sigmoid(cls_preds)
            else:
                cls_preds = [x[batch_mask] for x in batch_dict['batch_cls_preds']]
                src_cls_preds = cls_preds
                if not batch_dict['cls_preds_normalized']:
                    cls_preds = [torch.sigmoid(x) for x in cls_preds]
			 # 多类别NMS
            if post_process_cfg.NMS_CONFIG.MULTI_CLASSES_NMS:
                if not isinstance(cls_preds, list):
                    cls_preds = [cls_preds]
                    multihead_label_mapping = [torch.arange(1, self.num_class, device=cls_preds[0].device)]
                else:
                    multihead_label_mapping = batch_dict['multihead_label_mapping']

                cur_start_idx = 0
                pred_scores, pred_labels, pred_boxes = [], [], []
                for cur_cls_preds, cur_label_mapping in zip(cls_preds, multihead_label_mapping):
                    assert cur_cls_preds.shape[1] == len(cur_label_mapping)
                    cur_box_preds = box_preds[cur_start_idx: cur_start_idx + cur_cls_preds.shape[0]]
                    cur_pred_scores, cur_pred_labels, cur_pred_boxes = model_nms_utils.multi_classes_nms(
                        cls_scores=cur_cls_preds, box_preds=cur_box_preds,
                        nms_config=post_process_cfg.NMS_CONFIG,
                        score_thresh=post_process_cfg.SCORE_THRESH
                    )
                    cur_pred_labels = cur_label_mapping[cur_pred_labels]
                    pred_scores.append(cur_pred_scores)
                    pred_labels.append(cur_pred_labels)
                    pred_boxes.append(cur_pred_boxes)
                    cur_start_idx += cur_cls_preds.shape[0]

                final_scores = torch.cat(pred_scores, dim=0)
                final_labels = torch.cat(pred_labels, dim=0)
                final_boxes = torch.cat(pred_boxes, dim=0)
            else:
              # 单类别NMS
                cls_preds, label_preds = torch.max(cls_preds, dim=-1)
                if batch_dict.get('has_class_labels', False):
                    label_key = 'roi_labels' if 'roi_labels' in batch_dict else 'batch_pred_labels'
                    label_preds = batch_dict[label_key][index]
                else:
                    label_preds = label_preds + 1 
                selected, selected_scores = model_nms_utils.class_agnostic_nms(
                    box_scores=cls_preds, box_preds=box_preds,
                    nms_config=post_process_cfg.NMS_CONFIG,
                    score_thresh=post_process_cfg.SCORE_THRESH
                )

                if post_process_cfg.OUTPUT_RAW_SCORE:
                    max_cls_preds, _ = torch.max(src_cls_preds, dim=-1)
                    selected_scores = max_cls_preds[selected]

                final_scores = selected_scores
                final_labels = label_preds[selected]
                final_boxes = box_preds[selected]
             # 生成召回率记录    
            recall_dict = self.generate_recall_record(
                box_preds=final_boxes if 'rois' not in batch_dict else src_box_preds,
                recall_dict=recall_dict, batch_index=index, data_dict=batch_dict,
                thresh_list=post_process_cfg.RECALL_THRESH_LIST
            )        
 		# 构建预测结果字典,并添加到预测结果列表中
            record_dict = {
                'pred_boxes': final_boxes,
                'pred_scores': final_scores,
                'pred_labels': final_labels
            }
            pred_dicts.append(record_dict)

        return pred_dicts, recall_dict

代码里面的一些小细节,后续有人问到再讲

引用

Openpcdet 系列 Pointpillar代码逐行解析
OpenPCDet 环境安装
OpenPCDet KITTI数据加载过程 (Pointpillar模型)
Openpcdet 系列 Pointpillar代码逐行解析之Voxel Feature Encoding (VFE)模块
Openpcdet 系列 Pointpillar代码逐行解析之MAP_TO_BEV模块

Openpcdet 系列 Pointpillar代码逐行解析之BACKBONE_2D模块

Openpcdet 系列 Pointpillar代码逐行解析之检测头(DENSE_HEAD)模块

Openpcdet 系列 Pointpillar代码逐行解析之POST_PROCESSING模块
文章来源地址https://www.toymoban.com/news/detail-778191.html

到了这里,关于Openpcdet 系列 Pointpillar代码逐行解析之POST_PROCESSING模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【点云检测】OpenPCDet 教程系列 [1] 安装 与 ROS运行

    主要是介绍库的使用,做笔记区 首先搜索的时候有个问题 一直在我脑子里 hhh 就是MMlab其实还有一个叫mmdetection3d 的库,然后搜的时候发现 hhh 有网友和我一样的疑惑:OpenPCDet和mmdetection3d有什么区别 ? - 知乎 (zhihu.com) 这是OpenMMLab官方的回复: OpenPCDet 和 mmdetection3d 是两个不同的

    2024年02月14日
    浏览(28)
  • OpenPCDet系列 | 7.1 KITTI数据集测试流程predicted_boxes预测

    测试流程的结构图如下所示: generate_predicted_boxes函数 一开始的数据传入为: 首先对于各类预测的特征图进行重新reshape处理,将anchor那一维度进行拼接操作,比如:(16, 248, 216, 42) - (16, 321408, 7)。但是这里需要注意。 特征预测的box信息是基于anchor的一个偏移,也就是编码后的

    2024年02月06日
    浏览(30)
  • 3D目标检测--PointPillars论文和OpenPCDet代码解读

    解决传统基于栅格化的3D目标检测方法在面对高密度点云数据时的性能瓶颈; 栅格化方法需要将点云数据映射到规则的网格中,但是对于高密度点云,栅格化操作会导致严重的信息损失和运算效率低下; 因此,该论文提出了一种新的基于点云的3D目标检测方法——PointPillars,

    2023年04月22日
    浏览(68)
  • 基于OpenPCDet实现自定义数据集的训练,狸花猫看完要打拳系列(一)!

      最近在学习如何基于 OpenPCDet框架进行PointPillars网络训练 ,由于对框架以及完整训练过程都不了解,因此打算记录下自己的学习过程,感谢学习过程中狸花猫sensei的大力支持,目标是实现自定义数据集(因为笔者 只有激光雷达的数据,仿照kitti格式进行标注 )的训练,然后

    2024年02月09日
    浏览(27)
  • Python实现决策树算法:完整源码逐行解析

    决策树是一种常用的机器学习算法,它可以用来解决分类和回归问题。决策树的优点是易于理解和解释,可以处理数值和类别数据,可以处理缺失值和异常值,可以进行特征选择和剪枝等操作。决策树的缺点是容易过拟合,对噪声和不平衡数据敏感,可能不稳定等。 在这篇文

    2024年02月04日
    浏览(28)
  • element ui el-avatar 源码解析零基础逐行解析

    快捷配置头像的样式 属性 说明 参数 size 尺寸 type string 类型 (‘large’,‘medium’,‘small’)number类型 validator 校验 shape 形状 circle (原型) square(方形) icon 传入的icon src 传入的图片 string类型 可以是本地图片(本地图片需要在js中requir导入,不可直接使用相对路劲引用) 也可

    2024年02月03日
    浏览(28)
  • YOLOv5源码逐行超详细注释与解读(1)——项目目录结构解析

    前面简单介绍了YOLOv5的网络结构和创新点(直通车:【YOLO系列】YOLOv5超详细解读(网络详解)) 在接下来我们会进入到YOLOv5更深一步的学习,首先从源码解读开始。 因为我是纯小白,刚开始下载完源码时真的一脸懵,所以就先从最基础的 项目目录结构 开始吧~因为相关解读

    2024年02月03日
    浏览(28)
  • 【代码详解】nerf-pytorch代码逐行分析

    要想看懂instant-ngp的cuda代码,需要先对NeRF系列有足够深入的了解,原始的NeRF版本是基于tensorflow的,今天读的是MIT博士生Yen-Chen Lin实现的pytorch版本的代码。 代码链接:https://github.com/yenchenlin/nerf-pytorch 因为代码量比较大,所以我们先使用一个思维导图对项目逻辑进行梳理,然

    2024年02月22日
    浏览(25)
  • 【计算机视觉】ViT:代码逐行解读

    这段代码是一个实现了 Vision Transformer(ViT)模型的 PyTorch 实现。 ViT 是一个基于 Transformer 架构的图像分类模型,其主要思想是将图像分成一个个固定大小的 patch ,并将这些 patch 看做是一个个 token 输入到 Transformer 中进行特征提取和分类。 以下是对代码的解读: ViT类继承自

    2024年02月03日
    浏览(34)
  • StyleGAN2代码PyTorch版逐行学习(上)

     详细地记录下我看StyleGAN2代码的过程,希望大家给予我一点帮助,也希望对大家有一点帮助。如果有啥错误和问题,评论区见~(私信我不咋看的) 建议大家先去自行搜索学习GAN和StyleGAN的基本原理,这里仅仅简要介绍一下StyleGAN和StyleGAN2的生成器: 以下内容的参考文献——

    2024年02月06日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包