Skip to content

Commit b07bb59

Browse files
committed
Issue #65: Add stereo render example, as yet untested.
1 parent 2a718ab commit b07bb59

6 files changed

Lines changed: 734 additions & 0 deletions

File tree

.kiro/steering/product.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Product Overview
2+
3+
scikit-surgeryutils is a collection of small demo applications and utility functions for surgical/medical imaging research. It is part of the SciKit-Surgery ecosystem developed at the Wellcome EPSRC Centre for Interventional and Surgical Sciences (UCL).
4+
5+
## Purpose
6+
7+
- Provide common overlay applications that combine video feeds with VTK-rendered 3D models
8+
- Offer command-line tools for camera calibration, video lag measurement, model rendering, DICOM reslicing, and text overlays
9+
- Serve as integration glue between other SciKit-Surgery libraries (scikit-surgeryimage, scikit-surgeryvtk, scikit-surgerycalibration, scikit-surgeryarucotracker)
10+
11+
## Target Users
12+
13+
Researchers and developers working in computer-assisted interventions and surgical guidance systems.
14+
15+
## License
16+
17+
BSD-3-Clause. Copyright University College London.

.kiro/steering/structure.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Project Structure
2+
3+
```
4+
scikit-surgeryutils/
5+
├── sksurgeryutils/ # Main package
6+
│ ├── __init__.py
7+
│ ├── _version.py # Auto-generated by versioneer
8+
│ ├── common_overlay_apps.py # Base widget classes for VTK overlay on video
9+
│ ├── ui/ # CLI entry points and demo applications
10+
│ │ ├── *_command_line.py # argparse CLI wrappers
11+
│ │ ├── *_demo.py # Demo/application logic
12+
│ │ └── *_app.py # Full application classes
13+
│ └── utils/ # Shared utility functions
14+
│ ├── image_utils.py
15+
│ ├── opencv_video_capture_utils.py
16+
│ ├── screen_utils.py
17+
│ └── string_utils.py
18+
├── tests/ # pytest test suite
19+
│ ├── conftest.py # Session-scoped QApplication fixture
20+
│ ├── data/ # Test data (videos, DICOM, models)
21+
│ ├── ui/ # Tests for UI/app modules
22+
│ ├── utils/ # Tests for utility modules
23+
│ └── pylintrc # Pylint configuration
24+
├── docs/ # Sphinx documentation source
25+
├── config/ # Misc config files
26+
├── sk*.py # Standalone runnable demo scripts (project root)
27+
├── setup.py / setup.cfg # Package build configuration
28+
├── tox.ini # Tox test environments
29+
├── requirements.txt # Runtime dependencies
30+
├── requirements-dev.txt # Dev/test dependencies
31+
└── requirements-docs.txt # Docs build dependencies
32+
```
33+
34+
## Conventions
35+
36+
- Each command-line tool has a pair: `*_command_line.py` (CLI/argparse) and `*_demo.py` (logic).
37+
- Console entry points are registered in `setup.py` under `entry_points`.
38+
- Test files mirror the source structure (`tests/ui/`, `tests/utils/`).
39+
- The `# coding=utf-8` header is used in all source files.
40+
- Classes inherit from `QWidget` and use `QTimer` for frame-loop patterns.
41+
- Logging uses Python's standard `logging` module.
42+
- Type validation raises `TypeError`/`ValueError` explicitly rather than using assertions.

.kiro/steering/tech.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Tech Stack
2+
3+
## Language
4+
5+
- Python (targets 3.9–3.13, CI runs on 3.13)
6+
7+
## Key Dependencies
8+
9+
| Library | Purpose |
10+
|---------|---------|
11+
| PySide6 (>=6.5.1.1) | Qt bindings for GUI widgets |
12+
| opencv-contrib-python-headless (>=4.10) | Computer vision, video capture |
13+
| numpy (>=2.0.0) | Array/matrix operations |
14+
| scikit-surgerycore | Core utilities (transforms, config) |
15+
| scikit-surgeryimage | Image acquisition, processing |
16+
| scikit-surgeryvtk | VTK overlay rendering |
17+
| scikit-surgeryarucotracker | ArUco/ChArUco marker tracking |
18+
| scikit-surgerycalibration | Camera calibration |
19+
20+
## Build & Packaging
21+
22+
- setuptools with `setup.py` / `setup.cfg`
23+
- Versioning via **versioneer** (PEP 440 style from git tags prefixed `v`)
24+
- No pyproject.toml yet — uses traditional setup.py
25+
26+
## Dev Dependencies
27+
28+
- pytest, pytest-qt — testing
29+
- coverage, coveralls — coverage reporting
30+
- pylint — linting (config in `tests/pylintrc`)
31+
- tox — test environment orchestration
32+
- pyfakefs, mock, parameterized — test helpers
33+
- sphinx — documentation
34+
35+
## Common Commands
36+
37+
All Python commands should be run using the tox-managed virtualenv at `.tox/test/bin/python`. Tox installs all requirements from the top-level requirements files.
38+
39+
```bash
40+
# Run tests with coverage (creates/uses .tox/test venv)
41+
tox -e test
42+
43+
# Run linter
44+
tox -e lint
45+
46+
# Build docs
47+
tox -e docs
48+
49+
# Run a Python command using the tox venv directly
50+
.tox/test/bin/python -m pytest -v -s
51+
52+
# Run a script with the tox venv
53+
.tox/test/bin/python sksurgerystereorenderer.py --help
54+
```
55+
56+
## CI/CD
57+
58+
- GitHub Actions (`.github/workflows/ci.yml`)
59+
- Coverage reported to Coveralls
60+
- Docs hosted on Read the Docs

sksurgerystereorenderer.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
import sys
4+
5+
from sksurgeryutils.ui.sksurgerystereorenderer_command_line import main
6+
7+
if __name__ == "__main__":
8+
sys.exit(main(sys.argv[1:]))
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# coding=utf-8
2+
3+
"""
4+
Command line entry point for sksurgerystereorenderer application.
5+
"""
6+
7+
import argparse
8+
from sksurgeryutils import __version__
9+
from sksurgeryutils.ui.sksurgerystereorenderer_demo import run_demo
10+
11+
12+
def main(args=None):
13+
"""
14+
Entry point for sksurgerystereorenderer application.
15+
"""
16+
parser = argparse.ArgumentParser(
17+
description='sksurgerystereorenderer - Stereo augmented reality '
18+
'renderer with interactive model manipulation.')
19+
20+
parser.add_argument("-li", "--left_intrinsics",
21+
required=True,
22+
type=str,
23+
help="File path to left camera 3x3 intrinsics matrix.")
24+
25+
parser.add_argument("-ri", "--right_intrinsics",
26+
required=True,
27+
type=str,
28+
help="File path to right camera 3x3 intrinsics matrix.")
29+
30+
parser.add_argument("-l2r", "--left_to_right",
31+
required=True,
32+
type=str,
33+
help="File path to 4x4 stereo left-to-right "
34+
"extrinsic matrix.")
35+
36+
parser.add_argument("-m", "--models",
37+
required=True,
38+
type=str,
39+
help="Path to models .json configuration file.")
40+
41+
parser.add_argument("-r", "--clipping_range",
42+
required=True,
43+
type=str,
44+
help="Near,far clipping range (e.g. '1,1000').")
45+
46+
parser.add_argument("-lv", "--left_video",
47+
required=True,
48+
type=str,
49+
help="Left video source: integer device index, "
50+
"video file path, or static image (.png/.jpg).")
51+
52+
parser.add_argument("-rv", "--right_video",
53+
required=True,
54+
type=str,
55+
help="Right video source: integer device index, "
56+
"video file path, or static image (.png/.jpg).")
57+
58+
parser.add_argument("-m2w", "--model_to_world",
59+
required=False,
60+
default=None,
61+
type=str,
62+
help="File path to a 4x4 model-to-world matrix "
63+
"applied to all models on startup.")
64+
65+
parser.add_argument("-c2w", "--camera_to_world",
66+
required=False,
67+
default=None,
68+
type=str,
69+
help="File path to a 4x4 camera-to-world matrix "
70+
"for the initial camera pose.")
71+
72+
parser.add_argument("-s", "--stereo_mode",
73+
required=False,
74+
default="stacked",
75+
type=str,
76+
choices=["stacked", "interlaced"],
77+
help="Stereo display mode: 'stacked' (left=top, "
78+
"right=bottom) or 'interlaced'. "
79+
"Default: stacked.")
80+
81+
version_string = __version__
82+
friendly_version_string = version_string if version_string else 'unknown'
83+
parser.add_argument(
84+
"-v", "--version",
85+
action='version',
86+
version='sksurgerystereorenderer version '
87+
+ friendly_version_string)
88+
89+
args = parser.parse_args(args)
90+
91+
run_demo(args.left_intrinsics,
92+
args.right_intrinsics,
93+
args.left_to_right,
94+
args.models,
95+
args.clipping_range,
96+
args.left_video,
97+
args.right_video,
98+
args.model_to_world,
99+
args.camera_to_world,
100+
args.stereo_mode)

0 commit comments

Comments
 (0)