Skip to content

Wand Calibration / Tracking GUI QoL + headless CLIs#3

Open
AlphabetWolf wants to merge 5 commits into
Shiyong-Tan:mainfrom
enkiduovo:main
Open

Wand Calibration / Tracking GUI QoL + headless CLIs#3
AlphabetWolf wants to merge 5 commits into
Shiyong-Tan:mainfrom
enkiduovo:main

Conversation

@AlphabetWolf

@AlphabetWolf AlphabetWolf commented Jun 15, 2026

Copy link
Copy Markdown

A batch of GUI quality-of-life features, headless CLI equivalents of the main GUI
actions, and a few bug fixes. No detection / triangulation / calibration /
tracking algorithms were modified
— these wrap or drive the existing pipelines.

Verified headless (QT_QPA_PLATFORM=offscreen, OpenLPT/lpt conda envs);
screenshots below are rendered from the actual widgets.


Summary of Changes

  • Added camera auto-load from the folder that directly contains the cam<N> folders, for Point Detection.
  • Replaced per-camera visualization tabs with a unified Cams grid and expand/collapse behavior.
  • Added editable numeric Sensitivity input synced with the slider.
  • Added Generate CLI for Point Detection, Calibration, and Tracking Settings.
  • Added Calibration-page config import/export.
  • Fixed preprocessing CLI camera indexing and output image-list naming.
  • Added headless tracking settings configuration script.
  • Improved reference-frame validation with complete coarse-to-fine block search.
  • Added reference-frame search module and tests.
  • Added Calibration-page Error Matrix popup.
  • Fixed workflow issues around frame-count validation, output path prompts, and loaded CSV reuse.

Table of Contents


1. Auto-Load Cameras from Folder — Point Detection

Adds an "Auto-Load Cameras from Folder" button (with a small info
button beside it) above the Camera Images table. Pick the folder that directly
contains
the cam<N> folders (cam0, cam1, …); it loads every cam<N>
(ascending), sets Num Cameras to match (supports >4), and loads each camera's
images into the right slot — auto-filling width/height from the first image. If
the cameras have different image counts it still loads them and shows a
warning
(only a total absence of images aborts). The button shows the
help / last-load status in a popup.

image

2. "Cams" grid + expand/collapse — visualization area

The old per-camera tab bar (Cam 1 … Cam N + 3D View) is replaced by two
tabs: "Cams" (all cameras in a 2-column grid; scrolls past 4) and
"3D View". Click any camera to expand it full-size; click again (or "← Back
to grid") to return.

02_cams_grid

3. Editable "Sensitivity" input — Point Detection

The Sensitivity control gained an editable numeric box alongside the slider
(two-way synced; range 0.5–1.0, step 0.01). See the 0.85 field next to the
slider in the Point Detection panel above.


4. "Generate CLI" — Process All Frames (Point Detection)

Green "Generate CLI" button opens a dialog (Save / Copy CLI / Close, no
auto-save) with a one-line command that runs exactly what Process All Frames
does (same detect_wand_points_generator, same wand_points.csv), headless.
Save asks where to write it; Copy CLI puts it on the clipboard. Also adds
an Output Path field so Process All Frames no longer double-prompts for a
save path (Change 7b).

image

5. "Config Load/Export" — import/export Calibration-page settings

A Config Load/Export group at the top of the Calibration tab with
Import Config and Export Config side-by-side (distinct purple colour).
Saves/restores every Calibration-page setting to/from JSON: camera model, wand
length, distortion, refraction (windows, per-camera window map, media
indices/thickness), and the error filters. Round-trip verified exact.

image

6. "Generate CLI" — Run Calibration (Calibration page)

Green "Generate CLI" below Run Calibration opens a dialog (Save / Copy
CLI / Close
, no auto-save) with a one-line command that runs the same
calibration headless and writes camFile/cam<N>.txt. Honors the UI camera model —
Pinhole (calibrate_wand) and Pinhole+Refraction
(RefractiveWandCalibrator.calibrate, passing windows / media). Reuses the
already-loaded points CSV when present. (See Calibration panel above.)


7. Bug fixes / workflow tweaks (Wand Calibration page)

  • Auto-Load Cameras loads even with differing image counts — shows a warning
    instead of aborting (only a total absence of images aborts).
  • Output Path section removes the double save-path prompt on Process All
    Frames
    (see §4).
  • Import & Export Config both at the top in the "Config Load/Export" group
    (see §5).
  • Generate CLI (Calibration) reuses the loaded CSV instead of re-prompting.

8. Image Preprocessing CLI — camera-ID + output-name fix

openlpt preprocess --input-root is now 0-based (cam0..cam3, was off-by-one
cam1..cam4) and writes cam<N>ImageNames.txt (the name the Tracking page
actually reads). Output folders, image-list filenames and camera IDs now line up
across Preprocessing → Tracking → Calibration with no rename step. pytest for
the preprocessing CLI/IO/core suites passes (21).

(CLI change — no GUI.)


9. cli_tracking_settings.py — headless "Save Configuration"

New script writes config.txt + bubbleConfig.txt/tracerConfig.txt (the
Settings page's Save Configuration output) without the GUI, for SLURM/cluster
runs. It headlessly drives the real TrackingSettingsView (auto-deriving cameras,
frame end, view volume, voxel-to-mm, IPR tolerances) with per-field overrides.
Defaults --fps 3000 --object-type bubble. Output byte-identical to the GUI's.

(CLI change — no GUI.)


10. "Generate CLI" — Settings page

Green "Generate CLI" in the Actions panel (below Save Configuration) shows
the cli_tracking_settings.py command reproducing Save Configuration with the
current field values. Output byte-identical to _save_configuration().

image

11. "Validate Settings" — block search for a valid reference frame

Validate Settings no longer validates frames one-by-one from Frame Start. It
runs a complete coarse-to-fine block search
(modules/image_preprocessing/reference_frame.py): cheap-probes the 1st frame of
each fps/5 block with a count_3d proxy (single StereoMatch at the validator's
loosest tolerances), runs the unchanged _run_validation_on_frame only on
frames that triangulate enough, and — if coarse heads find nothing — shrinks the
block and probes finer until all frames are checked
before reporting "no valid
frame". The per-frame validator (calBubbleRefImg) is not modified.

(Behavioral — no static screenshot; the status line now jumps between block
frames instead of 0,1,2,3…)


12. Reference-frame search module + tests

New modules/image_preprocessing/reference_frame.py (the engine behind §11):
find_reference_frame / find_reference_frame_blocks (multi-resolution, complete,
min_block knob) + make_stereomatch_count3d_proxy (cheap count_3d probe;
validator injected, never modified). Unit-tested (tests/test_reference_frame_search.py,
11 cases incl. the "scan all then fail" and "find interior frame by shrinking"
guarantees).

(Module + tests — no GUI.)


13. "Error Matrix" popup — Calibration page

New "Error Matrix" button in the Error Analysis header opens a window with
per-camera error stats (Mean, Median, user-set Tail %, Max + an "All cams"
row and a wand-length summary) over the top, and the full frame × camera error
matrix below. The Tail % input recomputes the percentile live. Reads the
existing per-frame errors only — nothing recalculated.

04_error_matrix

  • modules/camera_calibration/view.py — all Wand-Calibration UI (§§1–7, 13)
  • modules/camera_calibration/widgets.py — Sensitivity input (§3)
  • modules/camera_calibration/wand_calibration/point_detection_cli.py (new) — §4
  • modules/camera_calibration/wand_calibration/wand_calibration_cli.py (new) — §6
  • modules/image_preprocessing/{cli,runner,view}.py — §8
  • modules/image_preprocessing/reference_frame.py (new) — §§11–12
  • gui/views/tracking_settings_view.py — §§10–11
  • cli_tracking_settings.py (new) — §9
  • tests/test_reference_frame_search.py (new), preprocessing test updates

- Implemented `point_detection_cli.py` to provide a command-line interface for the Wand Calibration "Process All Frames" functionality, allowing headless execution of point detection across camera folders.
- Created `wand_calibration_cli.py` to enable command-line execution of the Wand Calibration "Run Calibration" feature, supporting both Pinhole and Pinhole+Refraction models with appropriate parameters.
- Enhanced the `SimpleSlider` widget in `widgets.py` to include a QDoubleSpinBox for precise numeric input, allowing users to type values directly while maintaining synchronization with the slider.
…ionality

- Updated CLI argument descriptions and examples to reflect zero-based camera indexing.
- Introduced a new module for block-based coarse-to-fine search for valid reference frames.
- Modified task building functions to support zero-based camera indexing.
- Changed output file naming conventions for image lists to use "ImageNames" instead of "image_list".
- Added comprehensive tests for CLI functionality, including input handling and output verification.
- Enhanced error handling for input validation in CLI commands.

@Shiyong-Tan Shiyong-Tan left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the implementation. I have a few suggestions before merging:

  1. For "Auto-load Cameras from root", please avoid assuming that users store camera images in a T0 folder. It would be better to support a more flexible directory structure.

  2. The newly added GUI buttons increase the learning curve and overall usage complexity for new users. Please consider simplifying the button layout to make the interface more user-friendly. For example, config-related controls could be grouped into the Settings box.

  3. For "Generate CLI", it would be helpful to provide a dedicated box or text area so users can easily copy the generated command.

@AlphabetWolf

Copy link
Copy Markdown
Author

Hi Shiyong, thanks for the review and suggestions.

I’ve addressed the issues you mentioned. Below are the fix details and screenshots:

  1. Auto-load Cameras from root
    • Removed the assumption that camera images must be stored under a T0 folder.
    • Updated the logic to support a more flexible directory structure.
    • Users can now select the folder that directly contains cam0, cam1, …, cam<N> folders, or load each camera folder individually.
image
  1. GUI button layout
    • Simplified the button layout to reduce usage complexity.
    • Moved config-related controls into the Settings box to make the interface cleaner and easier to understand.
image
  1. Generate CLI
    • Added a dedicated text area for the generated CLI command.
    • Users can now easily review and copy the command.
Screenshot 2026-06-16 at 14 28 51

@enkiduovo

Copy link
Copy Markdown

Hi Shiyong,
Above changes also includes the view volume fix we discussed yesterday:
This patch changes the fine-scan stage of _estimate_volume_from_cameras().

The logic is not to hard-enlarge the final volume. Instead:

  1. Check whether the coarse View Volume estimate looks collapsed.
  2. If any axis span is below 20 mm, treat the coarse result as suspicious.
  3. Rescan the common FOV from a larger padded search box using a finer requested grid.
  4. If the fine result is still suspiciously thin, run one emergency common-FOV rescan around the coarse-box center.
  5. Accept the emergency result only if it actually finds a larger visible common-FOV volume.
  6. Continue using the existing outward rounding to 5 mm and existing UI/config writing logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants