| name | 3d-object-detection |
| description | 3D 目标检测技能 - PointPillars、PointRCNN、LaserNet++ ROS2 部署 |
| argument-hint | 3D检测 OR PointPillars OR pointcloud OR 3D detection OR 物体检测 |
| user-invocable | true |
3D 目标检测技能
基于点云和图像融合的 3D 目标检测
何时使用
当需要以下帮助时使用此技能:
- 3D 目标检测网络
- 点云处理与分析
- 激光雷达-相机融合
- 障碍物检测与跟踪
- 自动驾驶感知
核心实现
PointPillars ROS2 节点
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import PointCloud2
from vision_msgs.msg import Detection3DArray
import numpy as np
import torch
from torch import nn
class PointPillarsNode(Node):
def __init__(self):
super().__init__('pointpillars_node')
self.pointcloud_sub = self.create_subscription(
PointCloud2, '/lidar_points', self.callback, 10)
self.det_pub = self.create_publisher(Detection3DArray, '/detections_3d', 10)
self.init_model()
self.declare_parameter('nms_iou_threshold', 0.5)
self.declare_parameter('score_threshold', 0.5)
def init_model(self):
pass
def callback(self, msg):
points = self.parse_pointcloud(msg)
pillars, coords = self.create_pillars(points)
with torch.no_grad():
boxes = self.model(pillars, coords)
detections = self.nms(boxes)
self.publish_detections(detections)
def parse_pointcloud(self, msg):
"""解析 PointCloud2 消息"""
points = []
for i in range(0, len(msg.data), msg.point_step):
x = msg.data[i:i+4]
points.append([x[0], x[1], x[2], x[3]])
return np.array(points, dtype=np.float32)
def create_pillars(self, points):
"""创建 Pillar"""
pillar_features = np.random.randn(100, 32, 100)
coords = np.zeros((100, 3), dtype=np.int32)
return pillar_features, coords
def nms(self, boxes):
"""非极大值抑制"""
return boxes
def publish_detections(self, detections):
msg = Detection3DArray()
for det in detections:
detection = Detection3D()
detection.bbox.center.position.x = det['x']
detection.bbox.center.position.y = det['y']
detection.bbox.center.position.z = det['z']
detection.bbox.size.x = det['length']
detection.bbox.size.y = det['width']
detection.bbox.size.z = det['height']
detection.bbox.center.orientation = det['orientation']
msg.detections.append(detection)
self.det_pub.publish(msg)
PointPillars 网络结构
class PillarEncoder(nn.Module):
"""Pillar Encoder"""
def __init__(self, in_channels=9, out_channels=64):
super().__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_channels, 32, 1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.Conv2d(32, out_channels, 1),
nn.BatchNorm2d(out_channels),
nn.ReLU()
)
def forward(self, pillars, coords):
x = self.conv(pillars)
return x
class Backbone(nn.Module):
"""SSD Backbone"""
def __init__(self, in_channels=64):
super().__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_channels, 128, 3, stride=2, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Conv2d(128, 256, 3, stride=2, padding=1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Conv2d(256, 256, 3, stride=, padding=),
nn.BatchNorm2d(),
nn.ReLU()
)
():
.conv(x)
(nn.Module):
():
().__init__()
.cls = nn.Conv2d(in_channels, num_classes, )
.box = nn.Conv2d(in_channels, * num_classes, )
():
cls = .cls(x)
box = .box(x)
cls, box