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
+394
View File
@@ -0,0 +1,394 @@
# Speckle-Scanner — 3D Scanning Pipeline
A modular pipeline for stereo 3D scanning: camera calibration → image rectification → disparity computation → point cloud generation → point cloud colouring.
---
## Quick start — clone and prepare your machine
### 1. Clone into home
The pipeline expects this repository at **`~/Speckle-Scanner`**. All paths in `config.py` are anchored to your home directory.
```bash
cd ~
git clone https://gitea.subseascanning.com/AsadUllah/Speckle-Scanner.git
```
This creates `~/Speckle-Scanner/` with the code only — **no scan or calibration data** is included in the repo.
### 2. Create the required data folders (siblings of the repo)
Three folders must exist **next to** `Speckle-Scanner` under `~/`. They are **not** part of the git repository; you create or copy data into them locally.
```bash
mkdir -p ~/3D-Scans ~/Calib-data
# ~/Speckle-Scanner_Processing_data/ is created automatically by rectification (step 2)
```
| Folder | Required? | Purpose | You provide |
|--------|-----------|---------|-------------|
| `~/Speckle-Scanner/` | yes (clone) | Pipeline source code, scripts, READMEs | `git clone` |
| `~/3D-Scans/` | yes | Raw stereo scan images | Copy/mount your project data |
| `~/Calib-data/` | yes | Calibration chessboard images | Copy/mount calibration sessions |
| `~/Speckle-Scanner_Processing_data/` | auto | Rectified images, disparity, point clouds | Created by step 2 (rectification) |
**Layout after clone:**
```
~/
├── Speckle-Scanner/ ← git clone (this repo)
├── 3D-Scans/ ← you create + add raw scans
│ └── <project>/<date>/<session>/<scan>/01_raw_images/
├── Calib-data/ ← you create + add calibration images
│ └── <project>/<date>/<calib_name>/{lc,rc,rg,ir}/ + params/
└── Speckle-Scanner_Processing_data/ ← auto-created on first rectification run
└── <project>/<date>/<session>/...
```
> **Do not move the repo out of `~/`.** Scripts resolve paths via `config.py` using `Path.home() / "Speckle-Scanner"`. Cloning elsewhere will break path resolution unless you change `config.py`.
### 3. Python environment and dependencies
```bash
conda create -n speckle python=3.9 -y
conda activate speckle
pip install -r ~/Speckle-Scanner/requirements.txt
```
Per-step installs are also available (see [Per-step requirements](#per-step-requirementstxt) below).
### 4. Build libSGM (GPU disparity — one-time per machine)
Requires NVIDIA CUDA + CMake ≥ 3.18. The binary is **not** committed to git; rebuild on each machine.
```bash
cd ~/Speckle-Scanner/05_disparity/libsgm
mkdir -p build && cd build
cmake .. -DENABLE_SAMPLES=on
make stereosgm_new -j4
```
Verify:
```bash
ls ~/Speckle-Scanner/05_disparity/libsgm/build/sample/stereosgm_new
```
### 5. Copy your data and run the pipeline
**Calibration data**`~/Calib-data/<project>/<date>/<calib_name>/`
Folders: `lc/`, `rc/`, `rg/` (or `rgb/`), `ir/` with chessboard images.
**Raw scans**`~/3D-Scans/<project>/<date>/<session>/<scan>/01_raw_images/`
Files: `lc_ts*.png`, `rc_ts*.png`, `ir_*.png`, `rg_*.png`, etc.
Then run the pipeline (replace names with yours):
```bash
# Step 1 — calibrate
cd ~/Speckle-Scanner/02_Calibration
python main.py --project Olsen_wings --date 2026-05-12 --calib_name calib1
# Step 2 — rectify (creates ~/Speckle-Scanner_Processing_data/...)
cd ~/Speckle-Scanner/04_Rectification
python main.py --project Olsen_wings --date 2026-05-12 --calib_name calib1
# Steps 35 — disparity, point cloud, colouring (see sections below)
```
**Sanity check after setup:**
```bash
ls ~/Calib-data/ # your calibration projects
ls ~/3D-Scans/ # your raw scan projects
ls ~/Speckle-Scanner/config.py # repo present
```
---
## System requirements
| Requirement | Version |
|-------------|---------|
| OS | Ubuntu 20.04 / 22.04 (Linux) |
| Python | 3.9 or newer |
| NVIDIA GPU + CUDA | 11.x or 12.x (required for libSGM; optional for GPU ZNCC) |
| CMake | ≥ 3.18 (for libSGM build) |
| Conda | Recommended for environment management |
---
## Directory layout — where folders live on the machine
All four top-level directories sit directly inside the home folder (`~/`). Only **`Speckle-Scanner`** comes from git; the others are local data or auto-generated output.
```
~/
├── Speckle-Scanner/ ← clone this repository here
├── 3D-Scans/ ← raw scan images (copy/mount data here)
├── Calib-data/ ← calibration session images (copy here)
└── Speckle-Scanner_Processing_data/ ← auto-created by the rectification step
```
**Never move Speckle-Scanner out of `~/`.** All path resolution is anchored to `~/` via `config.py` — no paths ever need manual editing.
### Folder structure inside each directory
```
~/3D-Scans/
└── <project>/
└── <date>/
└── <session>/
└── <scan>/
└── 01_raw_images/ ← lc_ts*.png rc_ts*.png ir_*.png rg_*.png
~/Calib-data/
└── <project>/
└── <date>/
└── <calib_name>/ ← e.g. calib1
├── lc/ ← left camera calibration images
├── rc/ rg/ ir/ ← right camera images
└── params/ ← calibration outputs (auto-created)
~/Speckle-Scanner_Processing_data/ ← created automatically by step 2 (rectification)
└── <project>/
└── <date>/
└── <session>/
├── params_link/ ← calibration files copied here once per session
└── <scan>/
├── 01_raw_images/
├── 02_rect_images/
├── 03_sgm_disp_map/
├── 04_zncc_disp_map/
├── 05_sgm_pcl/
├── 06_zncc_pcl/
├── 07_sgm_pcl_col/
└── 08_zncc_pcl_col/
```
---
## config.py — how path resolution works
`config.py` (at the root of this repo) is the single source of truth for all directory paths. It anchors everything to `Path.home()`:
```python
HOME_DIR = Path.home()
SOURCE_CODE_DIR = HOME_DIR / "Speckle-Scanner"
RAW_DATA_DIR = HOME_DIR / "3D-Scans"
CALIB_DATA_DIR = HOME_DIR / "Calib-data"
PROCESSING_DIR = HOME_DIR / "Speckle-Scanner_Processing_data"
```
Every pipeline script imports `config` and uses these variables — no script ever has a hardcoded path. To move the pipeline to a new machine, just clone the repo to `~/Speckle-Scanner/` and copy the data folders.
### Per-step `requirements.txt`
Each pipeline step has its own `requirements.txt` for minimal installs:
| Step | File |
|------|------|
| Calibration | `02_Calibration/requirements.txt` |
| Rectification | `04_Rectification/requirements.txt` |
| SGM disparity | `05_disparity/libsgm/requirements.txt` (build deps; no pip) |
| ZNCC disparity | `05_disparity/zncc/requirements.txt` |
| Point cloud | `06_Pointcloud/requirements.txt` |
| Colouring | `09_coloring/requirements.txt` |
The root `requirements.txt` is the **merged union** of all Python steps — use it when setting up one conda/venv for the full pipeline.
---
## Setup on a new machine (summary)
If you already followed [Quick start](#quick-start--clone-and-prepare-your-machine) above, you can skip this block. It repeats the same steps in one place:
```bash
cd ~
git clone https://gitea.subseascanning.com/AsadUllah/Speckle-Scanner.git
mkdir -p ~/3D-Scans ~/Calib-data
conda create -n speckle python=3.9 -y
conda activate speckle
pip install -r ~/Speckle-Scanner/requirements.txt
# GPU ZNCC (optional — match your CUDA version)
# pip install cupy-cuda11x # CUDA 11.x
# pip install cupy-cuda12x # CUDA 12.x
cd ~/Speckle-Scanner/05_disparity/libsgm
mkdir -p build && cd build
cmake .. -DENABLE_SAMPLES=on
make stereosgm_new -j4
```
Copy calibration images to `~/Calib-data/` and raw scans to `~/3D-Scans/`, then run the pipeline steps below.
> **Note:** The libSGM binary is machine-specific (compiled CUDA C++). It must be rebuilt on every new machine. The Python code is fully portable.
---
## Full pipeline — step by step
Replace `Olsen_wings`, `2026-05-12`, `calib1` with your actual project, date, and calibration folder name.
### Step 1 — Calibrate
Two-step calibration (detect features → JSON, then mono + stereo). One command calibrates **lc vs rc, rg, and ir**:
```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: `detect_features.py` then `calibrate.py`. Results go to `~/Calib-data/<project>/<date>/<calib_name>/params/` (`lc-rc_*`, `lc-rg_*`, `lc-ir_*`).
See [02_Calibration/README.md](02_Calibration/README.md) for all options.
---
### Step 2 — Rectify
Reads raw scans from `~/3D-Scans/`, applies calibration, and creates the full `Speckle-Scanner_Processing_data/` structure (including `params_link/`, `01_raw_images/`, `02_rect_images/`).
```bash
cd ~/Speckle-Scanner/04_Rectification
# All sessions under a date
python main.py --project Olsen_wings --date 2026-05-12 --calib_name calib1
# Single session only
python main.py --project Olsen_wings --date 2026-05-12 --calib_name calib1 --session session1
```
See [04_Rectification/README.md](04_Rectification/README.md) for all options.
---
### Step 3 — Disparity
Reads rectified images from `02_rect_images/`. Choose SGM, ZNCC, or run both.
**SGM (libSGM — CUDA C++):**
```bash
cd ~/Speckle-Scanner/05_disparity/libsgm
python run_sgm_pipeline.py --project Olsen_wings --date 2026-05-12
# Single session:
python run_sgm_pipeline.py --project Olsen_wings --date 2026-05-12 --session session1
# Single scan:
python run_sgm_pipeline.py --project Olsen_wings --date 2026-05-12 --session session1 --scan Scan000001
```
**ZNCC (CPU/GPU — Python):**
```bash
cd ~/Speckle-Scanner/05_disparity/zncc
python run_zncc_pipeline.py --project Olsen_wings --date 2026-05-12
# Single scan — use only the last 3 image pairs (highest timestamps):
python run_zncc_pipeline.py \
--project Olsen_wings --date 2026-05-12 --session session1 --scan Scan000001 \
--num_images 3 --window_size 7 --zncc_threshold 0.5
```
See [05_disparity/libsgm/README.md](05_disparity/libsgm/README.md) and [05_disparity/zncc/Readme.md](05_disparity/zncc/Readme.md) for all options.
---
### Step 4 — Point Cloud
Converts disparity maps to 3D point clouds (`.ply` by default; `.txt` with `--troubleshooting`).
```bash
cd ~/Speckle-Scanner/06_Pointcloud
# Both SGM and ZNCC (PLY only)
python run_pcl_pipeline.py --project Olsen_wings --date 2026-05-12
# SGM only / ZNCC only
python run_pcl_pipeline.py --project Olsen_wings --date 2026-05-12 --mode sgm
python run_pcl_pipeline.py --project Olsen_wings --date 2026-05-12 --mode zncc
# Single scan
python run_pcl_pipeline.py \
--project Olsen_wings --date 2026-05-12 --session session1 --scan Scan000001
# Also save ASCII .txt exports
python run_pcl_pipeline.py \
--project Olsen_wings --date 2026-05-12 --troubleshooting
```
See [06_Pointcloud/README.md](06_Pointcloud/README.md) for all options.
---
### Step 5 — Colour Point Cloud
Projects IR and RGB camera images onto the point cloud. Saves dual-texture binary PLY (RGB + IR channels).
```bash
cd ~/Speckle-Scanner/09_coloring
# Both SGM and ZNCC point clouds
python run_coloring_pipeline.py --project Olsen_wings --date 2026-05-12
# SGM only / ZNCC only
python run_coloring_pipeline.py --project Olsen_wings --date 2026-05-12 --mode sgm
python run_coloring_pipeline.py --project Olsen_wings --date 2026-05-12 --mode zncc
# Single scan
python run_coloring_pipeline.py \
--project Olsen_wings --date 2026-05-12 --session session1 --scan Scan000001
```
See [09_coloring/README.md](09_coloring/README.md) for all options.
---
## Output files per scan (summary)
| Folder | Contents | Created by |
|--------|----------|-----------|
| `01_raw_images/` | Copy of source images | Step 2 |
| `02_rect_images/` | Rectified `lc_*`, `rc_*`, `rg_*`, `ir_*` images | Step 2 |
| `03_sgm_disp_map/` | `disparity.xml`, `disparity_color.png` | Step 3 SGM |
| `04_zncc_disp_map/` | `disparity.npy`, colorbar PNGs | Step 3 ZNCC |
| `05_sgm_pcl/` | `Point_cloud.ply` (+ `.txt` with `--troubleshooting`) | Step 4 |
| `06_zncc_pcl/` | `Point_cloud.ply` (+ `.txt` with `--troubleshooting`) | Step 4 |
| `07_sgm_pcl_col/` | `Point_cloud_colored.ply` (RGB + IR) | Step 5 |
| `08_zncc_pcl_col/` | `Point_cloud_colored.ply` (RGB + IR) | Step 5 |
---
## Common `--session` and `--scan` options
All step 35 pipeline runners share the same scope arguments:
| Argument | Default | Effect |
|----------|---------|--------|
| `--session` | (omit) | Process **all sessions** under the date |
| `--session session1` | — | Process only `session1` |
| `--scan` | (omit) | Process all scans in the session |
| `--scan Scan000001` | — | Process only `Scan000001` |
---
## Quick check after setup
```bash
# Verify calibration outputs
ls ~/Calib-data/Olsen_wings/2026-05-12/calib1/params/
# Expected: lc-rc_stereo_cam_model.yaml lc-rc_Q.cvstore lc-rg_* lc-ir_*
# Verify rectification created the processing structure
ls ~/Speckle-Scanner_Processing_data/Olsen_wings/2026-05-12/session1/params_link/
ls ~/Speckle-Scanner_Processing_data/Olsen_wings/2026-05-12/session1/Scan000001/02_rect_images/ | head
# Verify libSGM binary
~/Speckle-Scanner/05_disparity/libsgm/build/sample/stereosgm_new --help
```