Initial commit: Speckle-Scanner 3D pipeline with setup README

This commit is contained in:
2026-06-10 03:09:05 +05:00
commit 1765934846
375 changed files with 123081 additions and 0 deletions
+408
View File
@@ -0,0 +1,408 @@
# 02 Calibration
Two-step calibration pipeline:
| Step | Script | What it does |
|------|--------|--------------|
| **1. Detection** | `detect_features.py` | Chessboard corners / IR ellipses → **JSON next to each image** |
| **2. Calibration** | `calibrate.py` | Mono intrinsics per camera + stereo **lc vs rc/rg/ir** |
`main.py` runs both steps by default (`--step all`).
---
## Troubleshooting flag
All calibration scripts accept `--troubleshooting` (default: **off**).
| `--troubleshooting` | Logs | Disk output |
|---------------------|------|-------------|
| **False** (default) | Minimal summary per camera / stereo pair | Step 1: `*.json` only (required for step 2). Step 2: **`params/` only** |
| **True** | Detailed per-image / per-pair logs, progress bars | Step 1: + `corners/<camera>/` overlays. Step 2: + `pairing_reports/`, `rectified/` |
```bash
# Default — minimal logs, only params/ from step 2
python main.py --project Olsen_wings --date 2026-05-12 --calib_name calib1
# Debug — verbose logs + intermediate folders
python main.py --project Olsen_wings --date 2026-05-12 --calib_name calib1 --troubleshooting
```
Legacy mode (`--legacy`) also respects `--troubleshooting` (corners, local_coords, images_ncb, rectified).
---
## All CLI parameters (reference)
| Parameter | Default | Used in |
|-----------|---------|---------|
| `--project` | required | all |
| `--date` | required | all |
| `--calib_name` | `calib1` | all |
| `--chessboard_size` | `8,7` | all |
| `--square_size` | `0.045` | all |
| `--left_chessboard_size` | = `--chessboard_size` | all |
| `--right_chessboard_size` | = `--chessboard_size` | all |
| `--left_square_size` | = `--square_size` | all |
| `--right_square_size` | = `--square_size` | all |
| `--preprocessing` | `None` | step 1 (`G`, `C`, `T` chain) |
| `--cameras` | all present | `detect_features.py` |
| `--ir_mode` | `auto` | step 1 (`auto` / `chessboard` / `ellipse`) |
| `--step` | `all` | `main.py` (`detect`/`calibrate`/`all`); `calibrate.py` (`mono`/`stereo`/`all`) |
| `--left_camera` | `lc` | step 2 stereo (`lc` / `lc-ir`) |
| `--time_window` | `0.1` | step 2 stereo (seconds) |
| `--partners` | `rc,rg,ir` | step 2 stereo |
| `--legacy` | off | `main.py` only |
| `--right_camera` | `rc` | `main.py --legacy` only |
| `--troubleshooting` | off | all (`False` = minimal; `True` = debug output) |
---
## Folder structure
```
~/Calib-data/<project>/<date>/<calib_name>/
├── lc/
│ ├── lc_1778599872850705.bmp
│ └── lc_1778599872850705.json ← step 1 (always)
├── rc/
├── rg/ (or rgb/)
├── ir/ (or IR/)
├── corners/ ← step 1, only with --troubleshooting
├── pairing_reports/ ← step 2, only with --troubleshooting
├── rectified/ ← step 2, only with --troubleshooting
└── params/ ← step 2 (always)
├── lc_intrinsics.npz
├── rc_intrinsics.npz
├── lc-rc_parameters.npz
├── lc-rc_stereo_cam_model.yaml
├── lc-rc_Q.cvstore
├── lc-rg_*
└── lc-ir_*
```
Nested layout (`<calib_name>/images/lc/`, …) is also supported.
---
## Quick start (full pipeline)
```bash
cd ~/Speckle-Scanner/02_Calibration
python main.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--chessboard_size 8,7 --square_size 0.045
```
Or run steps separately:
```bash
# Step 1 — detect features, write JSON
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--chessboard_size 8,7 --square_size 0.045
# Step 2 — calibrate from JSON (writes params/ only)
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--chessboard_size 8,7 --square_size 0.045 \
--time_window 0.1
```
---
## Step 1 — Feature detection (per camera)
For every image in each camera folder (`lc`, `rc`, `rg`, `ir`, `lc-ir`):
- Detects **chessboard corners** (default for lc/rc/rg)
- For **IR**: tries chessboard first (`--ir_mode auto`), falls back to **ellipse center**
- Writes `<image>.json` in the **same folder** as the image (always, even without `--troubleshooting`)
### LC only
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--cameras lc \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--preprocessing None
```
### RC only
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--cameras rc \
--chessboard_size 8,7 --square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045 \
--preprocessing None
```
### RG only
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--cameras rg \
--chessboard_size 8,7 --square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045 \
--preprocessing None
```
### IR only
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--cameras ir \
--chessboard_size 8,7 --square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045 \
--preprocessing C \
--ir_mode auto
```
### LC-IR folder only
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--cameras lc-ir \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--preprocessing None
```
### All cameras
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045 \
--preprocessing None \
--ir_mode auto
```
### Step 1 with troubleshooting
```bash
python detect_features.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--cameras lc,rc,ir \
--chessboard_size 8,7 --square_size 0.045 \
--preprocessing C \
--ir_mode auto \
--troubleshooting
```
### JSON contents (chessboard example)
```json
{
"version": 1,
"image": "lc_1778599872850705.bmp",
"camera_folder": "lc",
"feature_type": "chessboard",
"success": true,
"board_size": [8, 7],
"square_size": 0.045,
"timestamp_sec": 1778599872.850705,
"pair_key": "1778599872850705",
"corners": [[412.3, 287.1], ...]
}
```
---
## Step 2 — Calibration
### 2a. Mono intrinsics
Reads chessboard JSONs from each camera folder, runs `cv2.calibrateCamera`, saves:
- `params/<camera>_intrinsics.npz`
- `params/<camera>_intrinsics.yaml`
Requires **≥ 3** successful chessboard detections per camera.
### 2b. Stereo calibration
- **Left camera:** `lc` by default (`--left_camera`)
- **Partners:** `rc`, `rg`, `ir` — each available folder is calibrated against lc
- **Pairing:** time-window match (`--time_window`, default **0.1 s**), then filename `pair_key` fallback for IR scan ids
- Uses mono intrinsics with `CALIB_FIX_INTRINSIC`
- Saves `lc-rc_*`, `lc-rg_*`, `lc-ir_*` under `params/`
### Full step 2 (mono + all stereo pairs)
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step all \
--left_camera lc \
--partners rc,rg,ir \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045
```
### Stereo: LC ↔ RC only
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step stereo \
--left_camera lc \
--partners rc \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045
```
### Stereo: LC ↔ RG only
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step stereo \
--left_camera lc \
--partners rg \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045
```
### Stereo: LC ↔ IR only
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step stereo \
--left_camera lc \
--partners ir \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045
```
### Stereo: left = LC-IR folder
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step stereo \
--left_camera lc-ir \
--partners rc,rg,ir \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045
```
### Mono intrinsics only
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step mono \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045
```
### Step 2 with troubleshooting
```bash
python calibrate.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step all \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045 \
--troubleshooting
```
Writes `params/` plus `pairing_reports/<pair>.txt` and `rectified/<pair>/`.
---
## Full pipeline (`main.py`)
```bash
python main.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--step all \
--left_camera lc \
--partners rc,rg,ir \
--time_window 0.1 \
--chessboard_size 8,7 --square_size 0.045 \
--left_chessboard_size 8,7 --left_square_size 0.045 \
--right_chessboard_size 8,7 --right_square_size 0.045 \
--preprocessing None \
--ir_mode auto
```
With troubleshooting:
```bash
python main.py \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--troubleshooting \
--chessboard_size 8,7 --square_size 0.045
```
---
## Legacy one-shot mode
The old in-memory flow (single `--right_camera`, filename pairing) still works:
```bash
# LC-RC
python main.py --legacy \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--left_camera lc --right_camera rc \
--chessboard_size 8,7 --square_size 0.045
# LC-RG
python main.py --legacy \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--left_camera lc --right_camera rg \
--chessboard_size 8,7 --square_size 0.045
# LC-IR
python main.py --legacy \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--left_camera lc --right_camera ir \
--chessboard_size 8,7 --square_size 0.045 \
--preprocessing C
# LC-IR folder + IR partner (with debug output)
python main.py --legacy \
--project Olsen_wings --date 2026-05-12 --calib_name calib1 \
--left_camera lc-ir --right_camera ir \
--chessboard_size 8,7 --square_size 0.045 \
--preprocessing C --troubleshooting
```
---
## Dependencies
```bash
pip install -r ~/Speckle-Scanner/02_Calibration/requirements.txt
# or full pipeline:
pip install -r ~/Speckle-Scanner/requirements.txt
```
---
## Notes
- Stereo pairing uses **timestamps** parsed from filenames (`ts…` tokens or long numeric ids); `ck…` suffixes are ignored.
- **Ellipse-only** IR JSONs are stored but cannot produce mono intrinsics (need full chessboard grids). Use chessboard IR images for calibration.
- Per-camera board overrides apply to detection and calibration (`--left_chessboard_size`, etc.).
- Re-run **step 1** if images change; re-run **step 2** freely when tuning `time_window` or partners.
- With `--troubleshooting` off, step 2 writes **only** `params/` (no `pairing_reports/`, no `rectified/`).