Paper Walkthroughs
3D Object DetectionPart 6

PointRCNN: proposals grown from segmented points

What if a detector never builds a grid at all? PointRCNN segments the foreground points of a raw LiDAR scan, grows a 3D proposal from each of them, and refines every proposal in its own canonical frame — a two-stage detector on a PointNet++ backbone.

October 30, 2026 · 10 min read

Motivation & Main Contribution

  • So far the series has pushed points into grids: BEV images (MV3D), voxels (VoxelNet, SECOND), pillars (PointPillars). Every grid quantises the scan and loses some detail.
  • PointRCNN goes back to the PointNet road: no voxels, no BEV image, no camera — raw points end to end.
  • It is a two-stage, point-only detector in the spirit of Faster R-CNN:
    1. Stage 1 — bottom-up proposals. Segment foreground points and predict a 3D box from each one.
    2. Stage 2 — canonical refinement. Pool the points inside each proposal, rotate and shift them into the proposal’s own frame, and refine the box and its confidence.
  • Main contributions: proposals from segmented points instead of anchors; refinement in canonical coordinates; a bin-based box loss (classify a bin, then regress inside it).
  • At submission it ranked first among published methods on the KITTI 3D car test board, using LiDAR only.

Challenges at the Time

  • Anchors in 3D are expensive. AVOD places 80–100k anchor boxes in 3D space and pools multi-view features for each one.
  • Image-first pipelines miss objects. F-PointNet crops a frustum from a 2D detection; an object the camera misses (occlusion, darkness) can never be recovered in 3D.
  • Quantisation. BEV projection and voxelization lose information, and dense 3D CNNs are slow.
  • Large search space. A 3D box has 7 parameters, including a heading angle; direct regression of all of them from scratch is hard to train.

Naive Questions

  • Where do the segmentation labels come from? For free: in driving scenes objects do not overlap, so every point inside a ground-truth box is foreground.
  • Why predict a box from every foreground point? Each point sees its object through the backbone’s receptive field; NMS then keeps a few good proposals.
  • Why not regress the centre offset directly? The paper finds that classifying a bin and regressing a small residual is more accurate and converges faster.
  • Why rotate the pooled points into the proposal’s frame? Then every car looks “the same way round”, and stage 2 only has to learn small corrections.
  • Doesn’t the canonical frame throw away distance? Yes — so the distance to the sensor is added back as an extra feature.
  • Is PointNet++ fast enough for a full scan? It runs on 16,384 sampled points; sampling and grouping cost is the price of staying point-based.

Key Idea

Key idea. In 3D the boxes already give a segmentation mask for free — so segment the foreground points first, grow a proposal from each of them, and refine each proposal in its own coordinate frame.

Bin-based localisation for a foreground point pp at (x(p),z(p))(x^{(p)}, z^{(p)}) whose object centre is (xp,zp)(x^p, z^p):

binu(p)=⌊up−u(p)+Sδ⌋,resu(p)=1C(up−u(p)+S−(binu(p)⋅δ+δ2)),u∈{x,z}\mathrm{bin}_u^{(p)} = \left\lfloor \frac{u^p - u^{(p)} + S}{\delta} \right\rfloor, \qquad \mathrm{res}_u^{(p)} = \frac{1}{C}\left(u^p - u^{(p)} + S - \left(\mathrm{bin}_u^{(p)} \cdot \delta + \frac{\delta}{2}\right)\right), \quad u \in \{x, z\}
  • SS: search range around the point along each ground-plane axis; δ\delta: bin length; CC: bin length for normalisation.
  • The bin is trained with cross-entropy, the residual with smooth L1. The heading θ\theta is handled the same way with nn angle bins; the height yy and size (h,w,l)(h, w, l) are plain residual regression (size relative to the class-average size).
Bin-based localisation for one foreground point of a real car (car hyper-parameters: S=3S = 3 m, δ=0.5\delta = 0.5 m, so 12 bins per axis). The point sits on the car’s surface, metres away from the centre; the head first picks the bin along xx and along zz, then only regresses a residual smaller than half a bin.

Dive into Model Architecture & Key Components

PointRCNN from raw points to boxes, laid out like the paper’s Figure 2: stage 1 (top) segments the scan and grows one proposal per foreground point; stage 2 (bottom) pools the points of each proposal, moves them into its canonical frame and refines the box. One block per row of the table below; solid blocks are learned layers, dashed ones fixed operations.

The pipeline, step by step

  1. Input. Sample 16,384 points per scene (repeat points if a scene has fewer).
  2. Backbone. PointNet++ with multi-scale grouping: four set-abstraction levels, then four feature-propagation levels back to every point (the encoder–decoder from the PointNet walkthrough).

Builds on. PointNet++ with multi-scale grouping as the backbone (walkthrough 01), and the two-stage recipe of R-CNN / Faster R-CNN from 2D detection.

  1. Stage-1 heads. Per point: a foreground score (focal loss) and a bin-based box (only foreground points are supervised).
  2. Proposal NMS. Oriented BEV IoU NMS. Training: threshold 0.85, keep top 300. Inference: threshold 0.8, keep top 100.
  3. Point cloud region pooling. Enlarge each proposal by η\eta and keep the points inside, with their stage-1 features.
  4. Canonical transformation of the pooled points, then a small PointNet++ encoder.
  5. Stage-2 heads. Confidence (cross-entropy) and bin-based box refinement; final oriented NMS with BEV IoU 0.01.

Tensor shapes

StageOperation → purposeShape
Inputraw scene points, randomly sampled → a fixed number of points per scene1638416384 points
SA 1–4 (MSG)sample and group at several radii → fewer points, each with wider context4096→1024→256→644096 \to 1024 \to 256 \to 64 points
FP 1–4interpolate back up → a rich feature for every input point16384×C16384 \times C (per-point features)
Stage-1 headsforeground mask + bin-based box → every foreground point proposes a box, no anchorsone score and one box per point
NMSoriented BEV NMS → a few good, non-overlapping proposals300 (train) / 100 (test) proposals
Region poolingpoints in the enlarged box, random sample → the points (and features) that describe each proposal, plus a little context512512 points per proposal
Canonical transformrotate + translate into the box frame, add depth → the same car looks the same wherever it is; depth keeps the distance cue512512 points per proposal
Stage-2 SA (SSG)sample and group → encode each proposal’s points into one vector128→32→1128 \to 32 \to 1
Stage-2 headsconfidence + box refinement → score and correct each proposalone score and one box per proposal
  • The paper does not state the backbone channel width CC, so it stays a symbol here.

Stage 1: segmentation as the proposal generator

  • Foreground points are a small minority in an outdoor scan → focal loss Lfocal(pt)=−αt(1−pt)γlog⁡(pt)L_{focal}(p_t) = -\alpha_t (1 - p_t)^\gamma \log(p_t) with αt=0.25\alpha_t = 0.25, γ=2\gamma = 2.
  • Ground-truth boxes are enlarged by 0.2 m on each side, and background points in that margin are ignored, because box annotations are not pixel-perfect.
  • Hyper-parameters (car): S=3S = 3 m, δ=0.5\delta = 0.5 m, n=12n = 12 heading bins.
  • Why it is cheap: no anchors at all — the number of candidates is the number of foreground points.

Builds on. Focal loss (RetinaNet) for the foreground mask, and F-PointNet’s bin-based heading, extended here to the centre location.

Stage 1 on a real LiDAR scan (PandaSet), seen from above: the per-point mask picks out the points on cars, each of them proposes one box around itself, and oriented NMS (BEV IoU 0.8) keeps a few. The proposed boxes are illustrative — ground truth plus an error that grows with the point’s distance to the centre.

Point cloud region pooling: keep a bit of context

  • Each proposal bi=(xi,yi,zi,hi,wi,li,θi)b_i = (x_i, y_i, z_i, h_i, w_i, l_i, \theta_i) is enlarged to (xi,yi,zi,hi+η,wi+η,li+η,θi)(x_i, y_i, z_i, h_i + \eta, w_i + \eta, l_i + \eta, \theta_i).
  • Every point inside keeps: coordinates, intensity r(p)r^{(p)}, predicted mask m(p)∈{0,1}m^{(p)} \in \{0, 1\}, and the stage-1 feature f(p)∈RCf^{(p)} \in \mathbb{R}^C. Proposals with no points are dropped.
  • η=1.0\eta = 1.0 m works best (Table 5): no context gives 75.68 moderate AP, η=1.0\eta = 1.0 m gives 77.67; larger margins start to swallow points of neighbouring objects.

Canonical transformation: refine in the box’s own frame

  • Each proposal gets its own coordinate system: origin at the box centre, X′X' along the heading, Z′Z' perpendicular to it on the ground plane, Y′Y' unchanged.
  • Pooled points are rotated and translated into this frame; the proposal becomes (0,0,0,h,w,l,0)(0, 0, 0, h, w, l, 0) and stage 2 learns only the residual to the ground truth.
  • The frame removes distance information, so the depth d(p)=(x(p))2+(y(p))2+(z(p))2d^{(p)} = \sqrt{(x^{(p)})^2 + (y^{(p)})^2 + (z^{(p)})^2} is added back. The local inputs [p~,r(p),m(p),d(p)][\tilde p, r^{(p)}, m^{(p)}, d^{(p)}] go through FC layers, are concatenated with f(p)f^{(p)}, and feed the stage-2 PointNet++ encoder.
  • This is the single most important step: without it, moderate AP drops from 77.67 to 13.68 (Table 4). Removing the stage-1 features f(p)f^{(p)} costs 2.71 moderate AP.
Three real cars of the scan as proposals, each enlarged by η=1\eta = 1 m. Moving the origin to the box centre and rotating by −θ-\theta maps every proposal onto the same frame, where the car points along X′X' — so stage 2 only has to learn small corrections. The distance to the sensor is gone, hence the extra per-point depth d(p)d^{(p)}.

Stage 2: bins again, but smaller

  • Targets: positive for classification if max 3D IoU > 0.6, negative if < 0.45; box regression on proposals with 3D IoU ≥ 0.55.
  • Smaller search range S=1.5S = 1.5 m, δ=0.5\delta = 0.5 m. Since IoU ≥ 0.55, the heading error is assumed to lie in [−π/4,π/4][-\pi/4, \pi/4] and is split into bins of ω=10°\omega = 10°.
  • Loss: cross-entropy on confidence over all sampled proposals + bin and residual losses over the positive ones.
  • The two stages are trained separately: stage 1 for 200 epochs (batch 16), stage 2 for 50 epochs (batch 256), both at lr 0.002.
  • Augmentation includes GT-AUG — pasting ground-truth boxes and their points from other scenes, the sampling trick from SECOND.

Builds on. SECOND’s ground-truth sampling augmentation (walkthrough 04).

Conclusion

Results

KITTI test set, 3D AP (PointRCNN, Table 1):

MethodModalityCar easy ↑Car mod. ↑Car hard ↑Ped. mod. ↑Cyc. mod. ↑
MV3DRGB + LiDAR71.0962.3555.12––
UberATG-ContFuseRGB + LiDAR82.5466.2264.04––
AVOD-FPNRGB + LiDAR81.9471.8866.3842.8152.18
F-PointNetRGB + LiDAR81.2070.3962.1944.8956.77
VoxelNetLiDAR77.4765.1157.7333.6948.36
SECONDLiDAR83.1373.6666.2042.5653.85
PointRCNNLiDAR85.9475.7668.3241.7859.60

Car (IoU 0.7) uses AP at IoU 0.7; pedestrian and cyclist at IoU 0.5.

KITTI val set, car 3D AP (Table 2) and proposal recall (Table 3, car, moderate):

MethodEasy ↑Moderate ↑Hard ↑
MV3D71.2962.6856.56
VoxelNet81.9865.4662.85
SECOND87.4376.4869.10
AVOD-FPN84.4174.4468.65
F-PointNet83.7670.9263.65
PointRCNN (no GT-AUG)88.4577.6776.30
PointRCNN88.8878.6377.38
ProposalsMethodRecall at IoU 0.5 ↑
50AVOD91.00
50PointRCNN96.01
300MV3D91.00
300PointRCNN98.21

Pros and Cons

  • Pros
    • No anchors and no grid: proposals grow from segmented points, with high recall from few proposals.
    • Segmentation labels come for free from the boxes.
    • Canonical refinement makes stage 2 learn small residuals — removing it costs most of the accuracy (Table 4).
    • LiDAR only, yet ahead of the camera + LiDAR methods on cars at the time.
  • Cons
    • A PointNet++ backbone over the whole scan is costly (sampling and grouping 16,384 points).
    • The two stages are trained separately.
    • Pedestrians lag behind camera + LiDAR methods — few points on small objects.

Future Work

  • Keep point-level refinement, but get proposals and scene features from a faster backbone.
  • Train both stages end to end.

Next

  • PV-RCNN — the same authors keep PointNet++-style set abstraction for refinement but hand proposals and scene encoding to a sparse voxel CNN, trained end to end.