# Stage 1 report: K-Lane input and coordinate gate

Date: 14 July 2026  
Project: `classical-lidar-lane-detection`  
Architecture plan: <https://qld-popularity-smoke-likely.trycloudflare.com/lidar_lane_detection_architecture_plan.html>

## 1. Scope and boundary

This is a new LiDAR-only, rule-based/classical codebase. K-Lane is used only as
the dataset, label, coordinate, and later evaluation contract.

Nothing in this project imports or runs K-Lane's ML detector. The new package
has no Torch, CUDA, Open3D, neural model, training runner, checkpoint, or PyQt
dependency. The runtime dependencies are only NumPy and Pillow. The local
K-Lane checkout at commit `82c613a` was read as a reference to verify the public
file semantics and label orientation; none of its detector implementation was
copied into the new pipeline.

This stage stops before detector ROI cropping. The only bounds operation is a
diagnostic coordinate probe used to compare raw reflectivity with K-Lane's
stored 144 x 144 label. It is not a detector stage or threshold.

## 2. Workspace layout and untouched inputs

All work created in this session is contained under:

```text
classical-lidar-lane-detection/
├── artifacts/stage1/
├── docs/
├── src/lidar_lane_detection/
├── tests/
├── .gitignore
├── pyproject.toml
├── README.md
└── uv.lock
```

The following pre-existing items were not moved, edited, deleted, stopped, or
otherwise modified:

- `../K-Lane/`
- `../XR9J_CiKoMaFour_PerceptionSystem-develop/`
- `../download_klane_dataset.sh`
- `../klane-download.log`
- `../klane-download-2.log`
- `/mnt/arnavs_hdd/data/02-lane-detection/`

No signal or termination command was sent to the downloader/extractor. The
dataset was treated as read-only. At inspection time all 16 archives were
already present (about 43 GB); sequences 1 and 2 were extracted and sequence 3
was partially extracted. The extraction log had not yet advanced past
`Checking and extracting seq_03.zip`, so this report does not claim that the
external process has completed.

## 3. Is sequence 1 directly usable?

Yes, for stage-1 input development and labeled smoke checks.

The extracted directory is:

```text
/mnt/arnavs_hdd/data/02-lane-detection/K-Lane/seq_01
```

The archive central directory and extracted files agree on all 1,708 PCD
frames. Every PCD timestamp has a matching BEV image, BEV image label, BEV
tensor, and frontal image. No modality has an orphan timestamp.

| Asset | Count | Missing relative to PCD |
|---|---:|---:|
| PCD | 1,708 | 0 |
| BEV image | 1,708 | 0 |
| BEV image label | 1,708 | 0 |
| BEV tensor | 1,708 | 0 |
| Frontal image | 1,708 | 0 |
| 144 x 150 tensor label | 850 | 858 |

Therefore:

- All 1,708 frames are usable as raw stage-1 inputs.
- 850 frames are directly usable for label-aligned visual and metric checks.
- The 858 PCD frames without a local tensor label are still valid raw inputs;
  the reader represents their label as optional instead of rejecting them.
- Sequence 1 alone is not a complete benchmark. It covers only the sequence
  condition metadata `urban, night, uncrowded`, and it does not provide the
  full dataset's condition diversity or held-out evaluation arrangement.

The machine-readable audit is in
[`../artifacts/stage1/seq_01_audit.json`](../artifacts/stage1/seq_01_audit.json).

## 4. Actual input contract verified from data

### PCD

The sampled files are PCD v0.7 with `DATA ascii` and this schema:

| Field | PCD type | Size |
|---|---|---:|
| `x` | float | 4 bytes |
| `y` | float | 4 bytes |
| `z` | float | 4 bytes |
| `intensity` | float | 4 bytes |
| `reflectivity` | unsigned integer | 2 bytes |

Each sampled frame declares and loads exactly `2048 x 64 = 131,072` points.
The new reader returns all 131,072 points; it does not crop them. The five
sampled frames contained no non-finite values in any of the five fields.

### Labels

Each available tensor label is a NumPy `uint8` pickle with shape `144 x 150`:

- columns `0:144` are the 144 x 144 lane-class map;
- class IDs `0..5` indicate lane cells;
- value `255` is background;
- columns `144:150` contain six row-wise lane-existence values.

The binary confidence label is therefore `class_map != 255`. It is not
`class_map > 0`. The first real-data run exposed this distinction, and the
implementation and test fixture were corrected before the stage was accepted.

K-Lane publishes these arrays as pickle files. Pickle can execute code, so the
reader explicitly assumes the official trusted dataset rather than arbitrary
third-party pickle input.

### Frame matching and metadata

Frames are paired by the complete timestamp in each filename; directory order
is never used. The sequence-level `description.txt` and `calib_seq.txt` are
read once and attached immutably to every frame record. Every secondary asset
is optional in the record, while PCD is the only required modality.

### Coordinate geometry and orientation

The confirmed K-Lane contract is:

- longitudinal `x`: `0.0 .. 46.08 m`;
- lateral `y`: `-11.52 .. +11.52 m`;
- high-resolution projection geometry: `1152 x 1152`, or `0.04 x 0.02 m` per
  cell;
- confidence label geometry: `144 x 144`, or `0.32 x 0.16 m` per cell;
- label row 0 is far/forward and row 143 is near;
- label column 0 is positive lateral `y` and column 143 is negative lateral
  `y`.

The label is therefore a 180-degree rotation of K-Lane's unflipped raw
projection indices. The first diagnostic implementation intentionally passed
through the golden check and revealed the wrong orientation; it was fixed to
match K-Lane's public `get_point_from_pixel_in_m()` mapping. A synthetic unit
test now locks both corner mappings.

## 5. New classical project implementation

The main files are:

- [`../src/lidar_lane_detection/klane.py`](../src/lidar_lane_detection/klane.py):
  validated PCD header/body parser, label decoder, immutable records, direct or
  `train/` layout discovery, timestamp pairing, metadata, frame loading, and
  sequence audit.
- [`../src/lidar_lane_detection/diagnostics.py`](../src/lidar_lane_detection/diagnostics.py):
  numeric per-field reports and the raw-reflectivity/label coordinate panel.
- [`../src/lidar_lane_detection/cli.py`](../src/lidar_lane_detection/cli.py):
  `audit` and `inspect` commands, including deterministic evenly spaced labeled
  sampling.
- [`../tests/test_klane_reader.py`](../tests/test_klane_reader.py): five unit
  tests for discovery, optional asset pairing, uncropped point loading, label
  decoding, coordinate corners, audit behavior, and required-field rejection.
- [`../README.md`](../README.md): concise setup, run instructions, and the
  human coordinate gate.

## 6. Verification performed

### Unit and syntax checks

The isolated project environment was synchronized from inside the new project
directory. The result was:

```text
Ran 5 tests in 0.089s
OK
```

The source and test trees also pass Python bytecode compilation.

### Five-frame real-data gate

Five labeled frames were selected evenly across sequence 1 rather than taking
five adjacent frames:

1. `001270427447090`
2. `001334120928180`
3. `001413813614490`
4. `001463808561830`
5. `001501204924330`

For all five:

- the schema was exactly `x, y, z, intensity, reflectivity`;
- declared and loaded point count was 131,072;
- total non-finite field values was zero;
- raw label shape was 144 x 150;
- condition metadata was `urban, night, uncrowded`;
- the raw-to-label coordinate probe produced an overlay successfully.

Positive lane-cell counts were `861, 648, 408, 397, 195`. Points inside the
coordinate-probe bounds were `42,488, 40,739, 37,898, 40,739, 41,677`.

The sample manifest is in
[`../artifacts/stage1/seq_01_validation.json`](../artifacts/stage1/seq_01_validation.json),
and each frame has its own numeric JSON report beside its panel.

## 7. Human visual sign-off — approved

The requested human assessment was approved on 14 July 2026. The five reviewed
overlay panels are retained as the accepted evidence for the coordinate gate:

1. [`001270427447090`](../artifacts/stage1/seq_01_001270427447090_coordinate_check.png)
2. [`001334120928180`](../artifacts/stage1/seq_01_001334120928180_coordinate_check.png)
3. [`001413813614490`](../artifacts/stage1/seq_01_001413813614490_coordinate_check.png)
4. [`001463808561830`](../artifacts/stage1/seq_01_001463808561830_coordinate_check.png)
5. [`001501204924330`](../artifacts/stage1/seq_01_001501204924330_coordinate_check.png)

The approved coordinate contract confirms:

- green label traces follow plausible longitudinal reflective lane-marking
  structure in the grayscale raw reflectivity;
- the image is not mirrored or transposed;
- top-as-forward/far, bottom-as-near, left-as-positive-y, and
  right-as-negative-y look consistent.

Programmatically the mapping matches the published K-Lane conversion, and the
human approval closes the remaining visual ambiguity around mirror/transpose
orientation. ROI crop and road-plane work may now begin without reopening this
stage-1 gate.

## 8. Reproduction commands

Run from `classical-lidar-lane-detection/`:

```bash
env UV_CACHE_DIR=/tmp/uv-cache uv sync

env UV_CACHE_DIR=/tmp/uv-cache uv run klane-stage1 audit \
  /mnt/arnavs_hdd/data/02-lane-detection/K-Lane \
  --sequence 1 \
  --output artifacts/stage1/seq_01_audit.json

env UV_CACHE_DIR=/tmp/uv-cache uv run klane-stage1 inspect \
  /mnt/arnavs_hdd/data/02-lane-detection/K-Lane \
  --sequence 1 \
  --sample-count 5 \
  --output-dir artifacts/stage1

env UV_CACHE_DIR=/tmp/uv-cache uv run python -m unittest discover -s tests -v
```

## 9. Stage status and next boundary

Stage 1 is implemented, programmatically verified, and human-approved.
Sequence 1 is directly usable for this work. There are no remaining stage-1
gates.

No ROI crop, ground-plane RANSAC, reflectivity threshold, morphology, line
fitting, metric, ML model, or ROS integration has been implemented. The next
code change can begin the new classical ROI/road-surface stage.
