Wand Calibration / Tracking GUI QoL + headless CLIs#3
Conversation
- 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.
…ation and enhance cheap proxy mechanism
Shiyong-Tan
left a comment
There was a problem hiding this comment.
Thanks for the implementation. I have a few suggestions before merging:
-
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.
-
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.
-
For "Generate CLI", it would be helpful to provide a dedicated box or text area so users can easily copy the generated command.
…r feedback and error handling
|
Hi Shiyong, The logic is not to hard-enlarge the final volume. Instead:
|



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/lptconda envs);screenshots below are rendered from the actual widgets.
Summary of Changes
cam<N>folders, for Point Detection.Table of Contents
cli_tracking_settings.py— headless "Save Configuration"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 everycam<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.
2. "Cams" grid + expand/collapse — visualization area
The old per-camera tab bar (
Cam 1 … Cam N+3D View) is replaced by twotabs: "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.
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.85field next to theslider 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, samewand_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).
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.
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 thealready-loaded points CSV when present. (See Calibration panel above.)
7. Bug fixes / workflow tweaks (Wand Calibration page)
instead of aborting (only a total absence of images aborts).
Frames (see §4).
(see §5).
8. Image Preprocessing CLI — camera-ID + output-name fix
openlpt preprocess --input-rootis now 0-based (cam0..cam3, was off-by-onecam1..cam4) and writescam<N>ImageNames.txt(the name the Tracking pageactually reads). Output folders, image-list filenames and camera IDs now line up
across Preprocessing → Tracking → Calibration with no rename step.
pytestforthe 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(theSettings 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.pycommand reproducing Save Configuration with thecurrent field values. Output byte-identical to
_save_configuration().11. "Validate Settings" — block search for a valid reference frame
Validate Settingsno longer validates frames one-by-one from Frame Start. Itruns a complete coarse-to-fine block search
(
modules/image_preprocessing/reference_frame.py): cheap-probes the 1st frame ofeach
fps/5block with acount_3dproxy (single StereoMatch at the validator'sloosest tolerances), runs the unchanged
_run_validation_on_frameonly onframes 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_blockknob) +make_stereomatch_count3d_proxy(cheapcount_3dprobe;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.
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) — §4modules/camera_calibration/wand_calibration/wand_calibration_cli.py(new) — §6modules/image_preprocessing/{cli,runner,view}.py— §8modules/image_preprocessing/reference_frame.py(new) — §§11–12gui/views/tracking_settings_view.py— §§10–11cli_tracking_settings.py(new) — §9tests/test_reference_frame_search.py(new), preprocessing test updates