ProjectiveGeometry23 0.1.0__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- projectivegeometry23-1.1.0/.github/workflows/publish.yml +87 -0
- projectivegeometry23-1.1.0/.github/workflows/test.yml +24 -0
- projectivegeometry23-1.1.0/.gitignore +129 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/MANIFEST.in +1 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/PKG-INFO +11 -15
- projectivegeometry23-1.1.0/ProjectiveGeometry23/_version.py +24 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/svg_utils.py +65 -62
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23.egg-info/PKG-INFO +11 -15
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23.egg-info/SOURCES.txt +7 -0
- projectivegeometry23-1.1.0/ProjectiveGeometry23.egg-info/requires.txt +2 -0
- projectivegeometry23-1.1.0/pyproject.toml +48 -0
- projectivegeometry23-1.1.0/requirements.txt +4 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/setup.py +1 -2
- projectivegeometry23-1.1.0/source_detector_geometry.png +0 -0
- projectivegeometry23-1.1.0/v1.1.0 +0 -0
- projectivegeometry23-0.1.0/ProjectiveGeometry23.egg-info/requires.txt +0 -5
- projectivegeometry23-0.1.0/pyproject.toml +0 -6
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/LICENSE +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/__init__.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/central_projection.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/estimation.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/homography.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/pluecker.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/source_detector_geometry.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/utils.py +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23.egg-info/dependency_links.txt +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23.egg-info/top_level.txt +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/README.md +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/setup.cfg +0 -0
- {projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/tests/test_basic.py +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: Build and Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
release:
|
|
9
|
+
types: [published]
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.10", "3.12"]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v5
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 0 # Fetch full history for setuptools-scm
|
|
25
|
+
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: |
|
|
33
|
+
python -m pip install --upgrade pip
|
|
34
|
+
pip install build pytest
|
|
35
|
+
pip install -e .
|
|
36
|
+
|
|
37
|
+
- name: Test package installation
|
|
38
|
+
run: |
|
|
39
|
+
python -c "import ProjectiveGeometry23; print('Package imported successfully')"
|
|
40
|
+
python -c "from ProjectiveGeometry23 import utils; print('Package module imported successfully')"
|
|
41
|
+
|
|
42
|
+
- name: Run tests
|
|
43
|
+
run: pytest
|
|
44
|
+
|
|
45
|
+
- name: Build package
|
|
46
|
+
run: python -m build
|
|
47
|
+
|
|
48
|
+
- name: Check distribution
|
|
49
|
+
run: |
|
|
50
|
+
python -m pip install --upgrade pip
|
|
51
|
+
pip install twine
|
|
52
|
+
twine check dist/*
|
|
53
|
+
|
|
54
|
+
publish:
|
|
55
|
+
needs: test
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
if: github.event_name == 'release' && github.event.action == 'published'
|
|
58
|
+
environment:
|
|
59
|
+
name: pypi
|
|
60
|
+
url: https://pypi.org/project/ProjectiveGeometry23
|
|
61
|
+
permissions:
|
|
62
|
+
contents: read
|
|
63
|
+
id-token: write
|
|
64
|
+
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v5
|
|
67
|
+
with:
|
|
68
|
+
fetch-depth: 0 # Fetch full history for setuptools-scm
|
|
69
|
+
|
|
70
|
+
- name: Set up Python
|
|
71
|
+
uses: actions/setup-python@v5
|
|
72
|
+
with:
|
|
73
|
+
python-version: "3.12"
|
|
74
|
+
|
|
75
|
+
- name: Install build dependencies
|
|
76
|
+
run: |
|
|
77
|
+
python -m pip install --upgrade pip
|
|
78
|
+
pip install build
|
|
79
|
+
|
|
80
|
+
- name: Build package
|
|
81
|
+
run: python -m build
|
|
82
|
+
|
|
83
|
+
- name: Publish package distributions to PyPI
|
|
84
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
85
|
+
with:
|
|
86
|
+
user: __token__
|
|
87
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v5
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.10'
|
|
18
|
+
- name: Install dependencies
|
|
19
|
+
run: |
|
|
20
|
+
python -m pip install --upgrade pip
|
|
21
|
+
pip install .
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: |
|
|
24
|
+
python -m unittest discover tests
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
target/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# pipenv
|
|
88
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
89
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
90
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
91
|
+
# install all needed dependencies.
|
|
92
|
+
#Pipfile.lock
|
|
93
|
+
|
|
94
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.venv
|
|
107
|
+
env/
|
|
108
|
+
venv/
|
|
109
|
+
ENV/
|
|
110
|
+
env.bak/
|
|
111
|
+
venv.bak/
|
|
112
|
+
|
|
113
|
+
# Spyder project settings
|
|
114
|
+
.spyderproject
|
|
115
|
+
.spyproject
|
|
116
|
+
|
|
117
|
+
# Rope project settings
|
|
118
|
+
.ropeproject
|
|
119
|
+
|
|
120
|
+
# mkdocs documentation
|
|
121
|
+
/site
|
|
122
|
+
|
|
123
|
+
# mypy
|
|
124
|
+
.mypy_cache/
|
|
125
|
+
.dmypy.json
|
|
126
|
+
dmypy.json
|
|
127
|
+
|
|
128
|
+
# Pyre type checker
|
|
129
|
+
.pyre/
|
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ProjectiveGeometry23
|
|
3
|
-
Version:
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: A 2D and 3D projective geometry library with Plücker coordinates and projection matrix, including (X-ray) source-detector geometry model.
|
|
5
5
|
Home-page: https://github.com/aaichert/ProjectiveGeometry23
|
|
6
6
|
Author: Andre Aichert
|
|
7
|
-
Author-email: aaichert@gmail.com
|
|
8
|
-
License:
|
|
7
|
+
Author-email: Andre Aichert <aaichert@gmail.com>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Keywords: projective-geometry,homogeneous-coordinates,plucker-coordinates,pinhole-camera,projection-matrix,computer-vision,xray-geometry,computed-tomography,camera-calibration,multiple-view-geometry,epipolar-geometry
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
12
18
|
Requires-Python: >=3.7
|
|
13
19
|
Description-Content-Type: text/markdown
|
|
14
20
|
License-File: LICENSE
|
|
15
21
|
Requires-Dist: numpy
|
|
16
22
|
Requires-Dist: scipy
|
|
17
|
-
Provides-Extra: svg
|
|
18
|
-
Requires-Dist: svg_snip; extra == "svg"
|
|
19
23
|
Dynamic: author
|
|
20
|
-
Dynamic: author-email
|
|
21
|
-
Dynamic: classifier
|
|
22
|
-
Dynamic: description
|
|
23
|
-
Dynamic: description-content-type
|
|
24
24
|
Dynamic: home-page
|
|
25
|
-
Dynamic: license
|
|
26
25
|
Dynamic: license-file
|
|
27
|
-
Dynamic: provides-extra
|
|
28
|
-
Dynamic: requires-dist
|
|
29
26
|
Dynamic: requires-python
|
|
30
|
-
Dynamic: summary
|
|
31
27
|
|
|
32
28
|
# ProjectiveGeometry23
|
|
33
29
|
## Projective Geometry of Two- and Three-space
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '1.1.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 1, 0)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = 'g25c3f32d1'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Interactive drawing of points, lines in 2d and 3D, as well as
|
|
2
|
+
Interactive drawing of points, lines in 2d and 3D, as well as visualizing X-ray source-detector geometries.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
5
|
!pip install svg_vis
|
|
@@ -9,13 +9,13 @@ Usage:
|
|
|
9
9
|
from svg.Renderer import RenderSVG
|
|
10
10
|
|
|
11
11
|
target = ProjectionMatrix([...], detector_size_px, spacing)
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
vis = CanvasWithOverlay(target.image_size[0], target.image_size[1])
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
# World transformation
|
|
16
16
|
ax, az = 0.5, 0.5
|
|
17
17
|
s = 0.2
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def handle_draw(vis):
|
|
20
20
|
global ax
|
|
21
21
|
global az
|
|
@@ -25,26 +25,26 @@ Usage:
|
|
|
25
25
|
ax += vis.mouse_state.dy * 0.01
|
|
26
26
|
|
|
27
27
|
svg = RenderSVG((vis.w, vis.h))
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
svg.add(svg_world_geometry)
|
|
30
30
|
svg.add(svg_source_detector, projection=target,
|
|
31
31
|
draw_on_detector=svg_world_geometry,
|
|
32
32
|
label_source='C0', label_detector='I0(u,v)')
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
T = scale(s) @ rotation_x(ax) @ rotation_z(az)
|
|
35
35
|
raw_svg_code = svg.render(P=target.P@T)
|
|
36
36
|
vis.html_overlay.value = raw_svg_code
|
|
37
37
|
|
|
38
38
|
vis.handle_draw = handle_draw
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
vis.display()
|
|
41
41
|
|
|
42
42
|
Author: André Aichert
|
|
43
43
|
Date: Dec 11th, 2023
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
|
-
|
|
47
46
|
from svg_snip.Composer import Composer
|
|
47
|
+
from svg_snip.Composer import Group
|
|
48
48
|
import svg_snip.Elements as e2d
|
|
49
49
|
import svg_snip.Elements3D as e3d
|
|
50
50
|
|
|
@@ -55,35 +55,34 @@ from ProjectiveGeometry23.central_projection import ProjectionMatrix
|
|
|
55
55
|
from ProjectiveGeometry23.source_detector_geometry import SourceDetectorGeometry
|
|
56
56
|
|
|
57
57
|
|
|
58
|
-
def svg_coordinate_frame(P, size=100, **kwargs):
|
|
58
|
+
def svg_coordinate_frame(P, size=100, composer=None, **kwargs):
|
|
59
59
|
"""Draw a coordinate system of default size 100."""
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return '\n '.join(el) + '\n</g>\n'
|
|
60
|
+
group = Group("Coordinate Frame")
|
|
61
|
+
|
|
62
|
+
# Coordinate frame axes
|
|
63
|
+
group.add(e3d.arrow, P=P, X1=[0,0,0,1], X2=[size,0,0,1], stroke='red')
|
|
64
|
+
group.add(e3d.arrow, P=P, X1=[0,0,0,1], X2=[0,size,0,1], stroke='green')
|
|
65
|
+
group.add(e3d.arrow, P=P, X1=[0,0,0,1], X2=[0,0,size,1], stroke='blue')
|
|
66
|
+
return group
|
|
68
67
|
|
|
69
68
|
|
|
70
|
-
def svg_world_geometry(P, **kwargs):
|
|
69
|
+
def svg_world_geometry(P, composer=None, **kwargs):
|
|
71
70
|
"""Draw a coordinate system of size 100 and a wire cube
|
|
72
71
|
of the same size centered in the origin."""
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
]
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def svg_source_detector(P, projection: ProjectionMatrix, draw_on_detector=None, **kwargs):
|
|
86
|
-
"""Draw X-ray source-detector geometry.
|
|
72
|
+
group = Group("World Geometry")
|
|
73
|
+
|
|
74
|
+
# Coordinate frame axes
|
|
75
|
+
group.add(e3d.arrow, P=P, X1=[0,0,0,1], X2=[100,0,0,1], stroke='red')
|
|
76
|
+
group.add(e3d.arrow, P=P, X1=[0,0,0,1], X2=[0,100,0,1], stroke='green')
|
|
77
|
+
group.add(e3d.arrow, P=P, X1=[0,0,0,1], X2=[0,0,100,1], stroke='blue')
|
|
78
|
+
|
|
79
|
+
# A wireframe cube with size 100
|
|
80
|
+
group.add(e3d.wire_cube, P=P, min=[-50,-50,-50], max=[50,50,50], stroke='black')
|
|
81
|
+
return group
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def svg_source_detector(P, projection: ProjectionMatrix, draw_on_detector=None, composer=None, **kwargs):
|
|
85
|
+
"""Draw X-ray source-detector geometry.
|
|
87
86
|
Define draw_on_detector as any SVG drawing function to project
|
|
88
87
|
additional 3D geometry to the detector plane."""
|
|
89
88
|
sdg = SourceDetectorGeometry(projection)
|
|
@@ -92,50 +91,54 @@ def svg_source_detector(P, projection: ProjectionMatrix, draw_on_detector=None,
|
|
|
92
91
|
U = pgu.cvec(sdg.axis_direction_Upx) * projection.image_size[0]
|
|
93
92
|
V = pgu.cvec(sdg.axis_direction_Vpx) * projection.image_size[1]
|
|
94
93
|
|
|
95
|
-
|
|
96
|
-
'<g>\n',
|
|
97
|
-
# Source position
|
|
98
|
-
e3d.point(P=P, X=C, r=1, fill="black", **kwargs),
|
|
99
|
-
# Detector frame
|
|
100
|
-
e3d.polygon(P=P, Xs=[O, O+U, O+V+U ,O+V],
|
|
101
|
-
fill="#00000020", stroke="#00000040", **kwargs),
|
|
102
|
-
e3d.line(P=P, X1=O, X2=O + U, stroke="magenta", **kwargs),
|
|
103
|
-
e3d.line(P=P, X1=O, X2=O + V, stroke="cyan", **kwargs),
|
|
104
|
-
# Frustum
|
|
105
|
-
e3d.line(P=P, X1=C, X2=O, stroke="#00000020", **kwargs),
|
|
106
|
-
e3d.line(P=P, X1=C, X2=O+V, stroke="#00000020", **kwargs),
|
|
107
|
-
e3d.line(P=P, X1=C, X2=O+U, stroke="#00000020", **kwargs),
|
|
108
|
-
e3d.line(P=P, X1=C, X2=O+V+U, stroke="#00000020", **kwargs)
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
if 'label_source' in kwargs:
|
|
112
|
-
el += [e3d.text(P=P, X=C, content=kwargs['label_source'], **kwargs)]
|
|
113
|
-
if 'label_detector' in kwargs:
|
|
114
|
-
el += [e3d.text(P=P, X=O, content=kwargs['label_detector'], **kwargs)]
|
|
94
|
+
group = Group("Source Detector Geometry")
|
|
115
95
|
|
|
96
|
+
# Handle projection tracking on detector if geometry function is passed
|
|
116
97
|
if draw_on_detector is not None:
|
|
117
98
|
T_detector = sdg.central_projection_3d
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
99
|
+
group.add(draw_on_detector, P=P@T_detector, **kwargs)
|
|
100
|
+
|
|
101
|
+
# Source position
|
|
102
|
+
group.add(e3d.point, P=P, X=C, r=1, fill="black")
|
|
103
|
+
|
|
104
|
+
# Detector frame plane and directional axes
|
|
105
|
+
group.add(e3d.polygon, P=P, Xs=[O, O+U, O+V+U, O+V], fill="#00000020", stroke="#00000040")
|
|
106
|
+
group.add(e3d.arrow, P=P, X1=O, X2=O + U, stroke="magenta")
|
|
107
|
+
group.add(e3d.arrow, P=P, X1=O, X2=O + V, stroke="cyan")
|
|
108
|
+
|
|
109
|
+
# Projection Frustum boundary lines
|
|
110
|
+
group.add(e3d.line, P=P, X1=C, X2=O, stroke="#00000020")
|
|
111
|
+
group.add(e3d.line, P=P, X1=C, X2=O+V, stroke="#00000020")
|
|
112
|
+
group.add(e3d.line, P=P, X1=C, X2=O+U, stroke="#00000020")
|
|
113
|
+
group.add(e3d.line, P=P, X1=C, X2=O+V+U, stroke="#00000020")
|
|
114
|
+
|
|
115
|
+
# Optional descriptive annotations
|
|
116
|
+
if 'label_source' in kwargs:
|
|
117
|
+
group.add(e3d.text, P=P, X=C, content=kwargs['label_source'])
|
|
118
|
+
if 'label_detector' in kwargs:
|
|
119
|
+
group.add(e3d.text, P=P, X=O, content=kwargs['label_detector'])
|
|
120
|
+
return group
|
|
123
121
|
|
|
124
122
|
|
|
125
123
|
def svg_homogeneous_line(l, composer: Composer, stroke="yellow", **kwargs):
|
|
126
124
|
"""Draw a 2D line given in homogeneous coordinates.
|
|
127
|
-
|
|
125
|
+
Note: composer is passed in automatically via svg.Renderer.
|
|
128
126
|
"""
|
|
127
|
+
if composer is None:
|
|
128
|
+
return ""
|
|
129
|
+
group = Group("Homogeneous Line")
|
|
129
130
|
w, h = composer.image_size
|
|
130
131
|
l = pgu.cvec(l)
|
|
131
132
|
x1, y1, x2, y2 = pgu.intersectLineWithRect(l, w, h)
|
|
132
133
|
if not all(isinstance(v, float) for v in [x1, y1, x2, y2]):
|
|
133
134
|
return ""
|
|
134
|
-
|
|
135
|
+
group.add(e2d.line, x1=x1, y1=y1, x2=x2, y2=y2, stroke=stroke, **kwargs)
|
|
136
|
+
return group
|
|
135
137
|
|
|
136
138
|
|
|
137
|
-
def svg_pluecker_line(P, L, **kwargs):
|
|
139
|
+
def svg_pluecker_line(P, L, composer=None, **kwargs):
|
|
138
140
|
"""Draw a 3D line given in plucker coordinates."""
|
|
139
141
|
l = pluecker.project(L, P)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
group = Group("Plücker Line")
|
|
143
|
+
group.add(svg_homogeneous_line, l, **kwargs)
|
|
144
|
+
return group
|
{projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23.egg-info/PKG-INFO
RENAMED
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ProjectiveGeometry23
|
|
3
|
-
Version:
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: A 2D and 3D projective geometry library with Plücker coordinates and projection matrix, including (X-ray) source-detector geometry model.
|
|
5
5
|
Home-page: https://github.com/aaichert/ProjectiveGeometry23
|
|
6
6
|
Author: Andre Aichert
|
|
7
|
-
Author-email: aaichert@gmail.com
|
|
8
|
-
License:
|
|
7
|
+
Author-email: Andre Aichert <aaichert@gmail.com>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Keywords: projective-geometry,homogeneous-coordinates,plucker-coordinates,pinhole-camera,projection-matrix,computer-vision,xray-geometry,computed-tomography,camera-calibration,multiple-view-geometry,epipolar-geometry
|
|
9
10
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
12
18
|
Requires-Python: >=3.7
|
|
13
19
|
Description-Content-Type: text/markdown
|
|
14
20
|
License-File: LICENSE
|
|
15
21
|
Requires-Dist: numpy
|
|
16
22
|
Requires-Dist: scipy
|
|
17
|
-
Provides-Extra: svg
|
|
18
|
-
Requires-Dist: svg_snip; extra == "svg"
|
|
19
23
|
Dynamic: author
|
|
20
|
-
Dynamic: author-email
|
|
21
|
-
Dynamic: classifier
|
|
22
|
-
Dynamic: description
|
|
23
|
-
Dynamic: description-content-type
|
|
24
24
|
Dynamic: home-page
|
|
25
|
-
Dynamic: license
|
|
26
25
|
Dynamic: license-file
|
|
27
|
-
Dynamic: provides-extra
|
|
28
|
-
Dynamic: requires-dist
|
|
29
26
|
Dynamic: requires-python
|
|
30
|
-
Dynamic: summary
|
|
31
27
|
|
|
32
28
|
# ProjectiveGeometry23
|
|
33
29
|
## Projective Geometry of Two- and Three-space
|
{projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23.egg-info/SOURCES.txt
RENAMED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
.gitignore
|
|
1
2
|
LICENSE
|
|
2
3
|
MANIFEST.in
|
|
3
4
|
README.md
|
|
4
5
|
pyproject.toml
|
|
6
|
+
requirements.txt
|
|
5
7
|
setup.py
|
|
8
|
+
source_detector_geometry.png
|
|
9
|
+
v1.1.0
|
|
10
|
+
.github/workflows/publish.yml
|
|
11
|
+
.github/workflows/test.yml
|
|
6
12
|
ProjectiveGeometry23/__init__.py
|
|
13
|
+
ProjectiveGeometry23/_version.py
|
|
7
14
|
ProjectiveGeometry23/central_projection.py
|
|
8
15
|
ProjectiveGeometry23/estimation.py
|
|
9
16
|
ProjectiveGeometry23/homography.py
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"setuptools>=64",
|
|
4
|
+
"setuptools-scm[toml]>=8.0"
|
|
5
|
+
]
|
|
6
|
+
build-backend = "setuptools.build_meta"
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
name = "ProjectiveGeometry23"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
dynamic = ["version"]
|
|
12
|
+
description = "A 2D and 3D projective geometry library with Plücker coordinates and projection matrix, including (X-ray) source-detector geometry model."
|
|
13
|
+
requires-python = ">=3.6"
|
|
14
|
+
license = "Apache-2.0"
|
|
15
|
+
authors = [
|
|
16
|
+
{name = "Andre Aichert", email = "aaichert@gmail.com"},
|
|
17
|
+
]
|
|
18
|
+
keywords = [
|
|
19
|
+
"projective-geometry",
|
|
20
|
+
"homogeneous-coordinates",
|
|
21
|
+
"plucker-coordinates",
|
|
22
|
+
"pinhole-camera",
|
|
23
|
+
"projection-matrix",
|
|
24
|
+
"computer-vision",
|
|
25
|
+
"xray-geometry",
|
|
26
|
+
"computed-tomography",
|
|
27
|
+
"camera-calibration",
|
|
28
|
+
"multiple-view-geometry",
|
|
29
|
+
"epipolar-geometry"
|
|
30
|
+
]
|
|
31
|
+
classifiers = [
|
|
32
|
+
"Programming Language :: Python :: 3",
|
|
33
|
+
"Operating System :: OS Independent",
|
|
34
|
+
"Development Status :: 4 - Beta",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"Intended Audience :: Science/Research",
|
|
37
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
38
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
39
|
+
"Topic :: Scientific/Engineering :: Medical Science Apps.",
|
|
40
|
+
]
|
|
41
|
+
dependencies = [
|
|
42
|
+
"numpy",
|
|
43
|
+
"scipy",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.setuptools_scm]
|
|
47
|
+
write_to = "ProjectiveGeometry23/_version.py"
|
|
48
|
+
fallback_version = "0.0.1-local"
|
|
@@ -2,7 +2,6 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='ProjectiveGeometry23',
|
|
5
|
-
version='0.1.0',
|
|
6
5
|
description='Projective geometry in 2D and 3D with homogeneous and Plücker coordinates, projection matrices, and visualization.',
|
|
7
6
|
author='Andre Aichert',
|
|
8
7
|
author_email='aaichert@gmail.com',
|
|
@@ -25,4 +24,4 @@ setup(
|
|
|
25
24
|
license='MIT',
|
|
26
25
|
long_description=open('README.md').read(),
|
|
27
26
|
long_description_content_type='text/markdown',
|
|
28
|
-
)
|
|
27
|
+
)
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/central_projection.py
RENAMED
|
File without changes
|
{projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/estimation.py
RENAMED
|
File without changes
|
{projectivegeometry23-0.1.0 → projectivegeometry23-1.1.0}/ProjectiveGeometry23/homography.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|