---
kind: concept
slug: bezier-curve-parameterization
title: Bezier curve parameterization
summary: >-
  Predicts an open curve, such as a lane, as a few learned control points and evaluates a Bezier curve through them to get dense points. Compact and smooth by construction; the trade-off is a fixed control-point count. The wiki has one card so far.
tags: [curves, lane-detection, autonomous-driving, output-representation]
papers: ["2310.06753"]
related: [object-queries, bipartite-matching, multi-layer-perceptron, bird-eye-view-perception, bev-representation]
status: draft
updated_at: 2026-10-19
---

## Overview

Some outputs are curves, such as a lane centreline, and a network has to
predict each one as a fixed-size vector. The approach is to predict a small
number of control points per curve, then evaluate the Bezier curve through them
to get the dense points used for the loss and for downstream heads
[arxiv:2310.06753 §3.1]. The invariant is that the network outputs only control
points and every dense point is derived from them, so each predicted curve has
the shape of a Bezier curve with those control points.

## Variants

Only one card covers this concept so far. Other papers that parameterize curves
differently will be added as they are compiled.

### Learned anchors plus per-query offsets

Each lane query starts from a learned 3D anchor. Two independent MLPs predict,
for every query, a set of control-point offsets and a class score. The final
control points are the anchors plus the offsets [arxiv:2310.06753 §3.1]. The
paper uses M = 4 control points per lane [arxiv:2310.06753 §4.2] and 300 lane
queries [arxiv:2310.06753 §4.2]. In its one ablation over control points, on
OpenLane-V2 subset A with ResNet-50 and 24 epochs, OLS is 37.3 for M = 3, 38.2
for M = 4 and 37.1 for M = 5. The paper reports one run per setting and no
variance [arxiv:2310.06753 tab. 3]. Card:
[TopoMLP: A Simple yet Strong Pipeline for Driving Topology Reasoning](/papers/2310.06753).

## When to use which

| Situation | Use | Why |
|---|---|---|
| Open curve (lane, boundary) that must come out as a few points | Bezier with M = 4 control points | The paper's default. M = 3 and M = 5 scored lower in its single-run ablation [arxiv:2310.06753 tab. 3] |
| Regression loss needs points along the curve, not only the control points | Evaluate the curve at fixed samples, 11 per lane | The paper's loss uses 11 sampled points per lane [arxiv:2310.06753 §4.2] |
| Predicted curves must feed a second head, such as topology links | Pass the predicted curve points to that head | Topology heads read the predicted lane points [arxiv:2310.06753 §3] |
| Lanes in metres in a multi-camera bird's-eye frame | Keep control points inside a fixed range | The paper's BEV range is X ±51.2 m, Y ±25.6 m, Z from -8 to 4 m [arxiv:2310.06753 §4.2] |
| Latency or memory budget for the curve step | Not covered | No card reports the cost of the Bezier step |

## Implementation sketch

The core is two steps: the network predicts control points, then a fixed
Bernstein evaluation turns them into dense points. The Bernstein form is the
standard definition of a Bezier curve; the paper does not restate it
[arxiv:2310.06753 §3.1].

```pseudocode
# Predict M control points per lane query  [arxiv:2310.06753 §3.1]
# Input:  query_feats (N_L, C); anchors (N_L, 3), learned
# Output: control (N_L, M, 3), in BEV metres
def lane_control_points(query_feats, anchors, reg_head):
    # reg_head is an MLP that outputs M * 3 offsets per query
    offsets = reg_head(query_feats).reshape(N_L, M, 3)   # (N_L, M, 3)
    # Final control points are the anchor plus the offset  [arxiv:2310.06753 §3.1]
    return anchors[:, None, :] + offsets                 # (N_L, M, 3)
```

```pseudocode
# Evaluate one Bezier curve at parameter samples t in [0, 1]
# Input:  control (M, 3); t (T,), with T = 11 for the loss  [arxiv:2310.06753 §4.2]
# Output: points (T, 3)
def bezier_points(control, t):
    # Bernstein basis, shape (T, M): binomial coefficient times powers of t
    basis = [comb(M - 1, i) * t**i * (1 - t)**(M - 1 - i) for i in range(M)]
    # Each row of the basis weights the control points  (T, M) @ (M, 3)
    return stack(basis, axis=-1) @ control               # (T, 3)
```

## Contradictions

- **Regression target: paper vs code.** The paper gives the lane regression
  loss only as "L1 loss for lane regression" [arxiv:2310.06753 §3.1] and does
  not say on which points it acts. The repository applies L1 to 11 sampled
  points of the Bezier curve, not to the control points
  [code: projects/topomlp/models/heads/lane_head.py#L590-L596]
  [code: projects/topomlp/models/heads/lane_head.py#L737]. The TopoMLP card's
  Paper vs code section records this. Both sides are stated here; a
  reimplementation has to pick one.

## Papers

- [TopoMLP: A Simple yet Strong Pipeline for Driving Topology Reasoning](/papers/2310.06753): predicts M = 4 Bezier control points per query for 3D lanes, evaluates them for the loss and the topology heads.
