machinevision-toolbox-python 1.0.0__tar.gz → 1.0.1__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.
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/PKG-INFO +6 -4
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/README.md +1 -2
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevision_toolbox_python.egg-info/PKG-INFO +6 -4
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevision_toolbox_python.egg-info/SOURCES.txt +7 -1
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevision_toolbox_python.egg-info/entry_points.txt +1 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevision_toolbox_python.egg-info/requires.txt +4 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/Camera.py +54 -63
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageBlobs.py +552 -105
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageConstants.py +217 -70
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageCore.py +173 -244
- machinevision_toolbox_python-1.0.1/machinevisiontoolbox/ImageFiducials.py +433 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageIO.py +2 -1
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImagePointFeatures.py +4 -52
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageProcessing.py +2 -1
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageRegionFeatures.py +3 -377
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageReshape.py +209 -226
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageSpatial.py +218 -119
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageWholeFeatures.py +240 -34
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/PointCloud.py +201 -72
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/Sources.py +2 -1
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/__init__.py +2 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/__init__.py +3 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/color.py +16 -25
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/meshgrid.py +18 -4
- machinevision_toolbox_python-1.0.1/machinevisiontoolbox/base/version.py +26 -0
- machinevision_toolbox_python-1.0.1/machinevisiontoolbox/decorators.py +82 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/pyproject.toml +4 -1
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_constants.py +44 -4
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_core.py +63 -16
- machinevision_toolbox_python-1.0.1/tests/test_pointcloud.py +37 -0
- machinevision_toolbox_python-1.0.1/tests/test_reshape.py +741 -0
- machinevision_toolbox_python-1.0.1/tests/test_wholefeature.py +203 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/LICENSE +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevision_toolbox_python.egg-info/dependency_links.txt +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevision_toolbox_python.egg-info/top_level.txt +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/BagOfWords.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/BundleAdjust.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageColor.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageLineFeatures.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageMorph.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/ImageMultiview.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/VisualServo.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/data.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/esttheta.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/findpeaks.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/graphics.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/imageio.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/shapes.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/base/types.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/blocks/__init__.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/blocks/camera.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/blocks/test_blocks.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/camera_derivatives.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/fiducial.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/mvtb_types.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/machinevisiontoolbox/newcameras.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/setup.cfg +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_base_color.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_blobs.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_camera.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_color.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_image_io.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_imageprocessing_kernel.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_imageprocessing_morph.py +0 -0
- {machinevision_toolbox_python-1.0.0 → machinevision_toolbox_python-1.0.1}/tests/test_processing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: machinevision-toolbox-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: Python tools for machine vision - education and research
|
|
5
5
|
Author: Dorian Tsai
|
|
6
6
|
Author-email: Peter Corke <rvc@petercorke.com>
|
|
@@ -43,6 +43,9 @@ Requires-Dist: sphinx-autorun; extra == "docs"
|
|
|
43
43
|
Requires-Dist: sphinxcontrib-jsmath; extra == "docs"
|
|
44
44
|
Requires-Dist: sphinx-markdown-tables; extra == "docs"
|
|
45
45
|
Requires-Dist: sphinx-favicon; extra == "docs"
|
|
46
|
+
Provides-Extra: jupyter
|
|
47
|
+
Requires-Dist: ipywidgets; extra == "jupyter"
|
|
48
|
+
Requires-Dist: ipympl; extra == "jupyter"
|
|
46
49
|
|
|
47
50
|
# Machine Vision Toolbox for Python
|
|
48
51
|
|
|
@@ -70,9 +73,8 @@ Requires-Dist: sphinx-favicon; extra == "docs"
|
|
|
70
73
|
|
|
71
74
|
<li><a href="https://github.com/petercorke/machinevision-toolbox-python">GitHub repository </a></li>
|
|
72
75
|
<li><a href="https://petercorke.github.io/machinevision-toolbox-python/">Documentation</a></li>
|
|
73
|
-
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">
|
|
76
|
+
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">Wiki (examples and details)</a></li>
|
|
74
77
|
<li><a href="installation#">Installation</a></li>
|
|
75
|
-
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">Examples and details</a></li>
|
|
76
78
|
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/blob/master/CHANGELOG.md">Changelog</a></li>
|
|
77
79
|
</ul>
|
|
78
80
|
</td>
|
|
@@ -24,9 +24,8 @@
|
|
|
24
24
|
|
|
25
25
|
<li><a href="https://github.com/petercorke/machinevision-toolbox-python">GitHub repository </a></li>
|
|
26
26
|
<li><a href="https://petercorke.github.io/machinevision-toolbox-python/">Documentation</a></li>
|
|
27
|
-
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">
|
|
27
|
+
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">Wiki (examples and details)</a></li>
|
|
28
28
|
<li><a href="installation#">Installation</a></li>
|
|
29
|
-
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">Examples and details</a></li>
|
|
30
29
|
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/blob/master/CHANGELOG.md">Changelog</a></li>
|
|
31
30
|
</ul>
|
|
32
31
|
</td>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: machinevision-toolbox-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: Python tools for machine vision - education and research
|
|
5
5
|
Author: Dorian Tsai
|
|
6
6
|
Author-email: Peter Corke <rvc@petercorke.com>
|
|
@@ -43,6 +43,9 @@ Requires-Dist: sphinx-autorun; extra == "docs"
|
|
|
43
43
|
Requires-Dist: sphinxcontrib-jsmath; extra == "docs"
|
|
44
44
|
Requires-Dist: sphinx-markdown-tables; extra == "docs"
|
|
45
45
|
Requires-Dist: sphinx-favicon; extra == "docs"
|
|
46
|
+
Provides-Extra: jupyter
|
|
47
|
+
Requires-Dist: ipywidgets; extra == "jupyter"
|
|
48
|
+
Requires-Dist: ipympl; extra == "jupyter"
|
|
46
49
|
|
|
47
50
|
# Machine Vision Toolbox for Python
|
|
48
51
|
|
|
@@ -70,9 +73,8 @@ Requires-Dist: sphinx-favicon; extra == "docs"
|
|
|
70
73
|
|
|
71
74
|
<li><a href="https://github.com/petercorke/machinevision-toolbox-python">GitHub repository </a></li>
|
|
72
75
|
<li><a href="https://petercorke.github.io/machinevision-toolbox-python/">Documentation</a></li>
|
|
73
|
-
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">
|
|
76
|
+
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">Wiki (examples and details)</a></li>
|
|
74
77
|
<li><a href="installation#">Installation</a></li>
|
|
75
|
-
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/wiki">Examples and details</a></li>
|
|
76
78
|
<li><a href="https://github.com/petercorke/machinevision-toolbox-python/blob/master/CHANGELOG.md">Changelog</a></li>
|
|
77
79
|
</ul>
|
|
78
80
|
</td>
|
|
@@ -15,6 +15,7 @@ machinevisiontoolbox/ImageBlobs.py
|
|
|
15
15
|
machinevisiontoolbox/ImageColor.py
|
|
16
16
|
machinevisiontoolbox/ImageConstants.py
|
|
17
17
|
machinevisiontoolbox/ImageCore.py
|
|
18
|
+
machinevisiontoolbox/ImageFiducials.py
|
|
18
19
|
machinevisiontoolbox/ImageIO.py
|
|
19
20
|
machinevisiontoolbox/ImageLineFeatures.py
|
|
20
21
|
machinevisiontoolbox/ImageMorph.py
|
|
@@ -30,6 +31,7 @@ machinevisiontoolbox/Sources.py
|
|
|
30
31
|
machinevisiontoolbox/VisualServo.py
|
|
31
32
|
machinevisiontoolbox/__init__.py
|
|
32
33
|
machinevisiontoolbox/camera_derivatives.py
|
|
34
|
+
machinevisiontoolbox/decorators.py
|
|
33
35
|
machinevisiontoolbox/fiducial.py
|
|
34
36
|
machinevisiontoolbox/mvtb_types.py
|
|
35
37
|
machinevisiontoolbox/newcameras.py
|
|
@@ -43,6 +45,7 @@ machinevisiontoolbox/base/imageio.py
|
|
|
43
45
|
machinevisiontoolbox/base/meshgrid.py
|
|
44
46
|
machinevisiontoolbox/base/shapes.py
|
|
45
47
|
machinevisiontoolbox/base/types.py
|
|
48
|
+
machinevisiontoolbox/base/version.py
|
|
46
49
|
machinevisiontoolbox/blocks/__init__.py
|
|
47
50
|
machinevisiontoolbox/blocks/camera.py
|
|
48
51
|
machinevisiontoolbox/blocks/test_blocks.py
|
|
@@ -55,4 +58,7 @@ tests/test_core.py
|
|
|
55
58
|
tests/test_image_io.py
|
|
56
59
|
tests/test_imageprocessing_kernel.py
|
|
57
60
|
tests/test_imageprocessing_morph.py
|
|
58
|
-
tests/
|
|
61
|
+
tests/test_pointcloud.py
|
|
62
|
+
tests/test_processing.py
|
|
63
|
+
tests/test_reshape.py
|
|
64
|
+
tests/test_wholefeature.py
|
|
@@ -14,7 +14,6 @@ import matplotlib.pyplot as plt
|
|
|
14
14
|
import scipy
|
|
15
15
|
|
|
16
16
|
import cv2 as cv
|
|
17
|
-
from spatialmath import base, Line3, SO3
|
|
18
17
|
from machinevisiontoolbox.ImagePointFeatures import FeatureMatch
|
|
19
18
|
from machinevisiontoolbox.base import idisp
|
|
20
19
|
from machinevisiontoolbox.base.imageio import _isnotebook
|
|
@@ -26,15 +25,13 @@ from machinevisiontoolbox.base.imageio import _isnotebook
|
|
|
26
25
|
# from mpl_toolkits.mplot3d import Axes3D, art3d
|
|
27
26
|
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
import spatialmath.base as smbase
|
|
28
|
+
from spatialmath import Line3, SE3
|
|
29
|
+
import spatialmath.base as smb
|
|
32
30
|
|
|
33
31
|
from machinevisiontoolbox import Image
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
class CameraBase(ABC):
|
|
37
|
-
|
|
38
35
|
# list of attributes
|
|
39
36
|
_name = None # camera name (string)
|
|
40
37
|
_camtype = None # camera type (string)
|
|
@@ -121,7 +118,7 @@ class CameraBase(ABC):
|
|
|
121
118
|
self._rhou = sensorsize[0] / self.imagesize[0]
|
|
122
119
|
self._rhov = sensorsize[1] / self.imagesize[1]
|
|
123
120
|
else:
|
|
124
|
-
rho =
|
|
121
|
+
rho = smb.getvector(rho)
|
|
125
122
|
if len(rho) == 1:
|
|
126
123
|
self._rhou = rho[0]
|
|
127
124
|
self._rhov = rho[0]
|
|
@@ -313,7 +310,7 @@ class CameraBase(ABC):
|
|
|
313
310
|
|
|
314
311
|
:seealso: :meth:`width` :meth:`height` :meth:`nu` :meth:`nv`
|
|
315
312
|
"""
|
|
316
|
-
npix =
|
|
313
|
+
npix = smb.getvector(npix, dtype="int")
|
|
317
314
|
if len(npix) == 1:
|
|
318
315
|
self._imagesize = np.r_[npix[0], npix[0]]
|
|
319
316
|
elif len(npix) in (2, 3):
|
|
@@ -444,7 +441,7 @@ class CameraBase(ABC):
|
|
|
444
441
|
|
|
445
442
|
:seealso: :meth:`pp` :meth:`u0` :meth:`v0`
|
|
446
443
|
"""
|
|
447
|
-
pp =
|
|
444
|
+
pp = smb.getvector(pp)
|
|
448
445
|
if len(pp) == 1:
|
|
449
446
|
self._pp = np.r_[pp[0], pp[0]]
|
|
450
447
|
elif len(pp) == 2:
|
|
@@ -869,7 +866,7 @@ class CameraBase(ABC):
|
|
|
869
866
|
self._init_imageplane(ax)
|
|
870
867
|
|
|
871
868
|
if not isinstance(P, np.ndarray):
|
|
872
|
-
P =
|
|
869
|
+
P = smb.getvector(P)
|
|
873
870
|
|
|
874
871
|
if P.shape[0] == 3:
|
|
875
872
|
# plot world points
|
|
@@ -927,7 +924,7 @@ class CameraBase(ABC):
|
|
|
927
924
|
self._init_imageplane()
|
|
928
925
|
plt.autoscale(False)
|
|
929
926
|
|
|
930
|
-
|
|
927
|
+
smb.plot_homline(l, *args, ax=self._ax, **kwargs)
|
|
931
928
|
|
|
932
929
|
# def plot_line3(self, L, nsteps=21, **kwargs):
|
|
933
930
|
# """
|
|
@@ -1155,7 +1152,7 @@ class CameraBase(ABC):
|
|
|
1155
1152
|
face order -x, +y, +x, -y
|
|
1156
1153
|
"""
|
|
1157
1154
|
# get axes to draw in
|
|
1158
|
-
ax =
|
|
1155
|
+
ax = smb.axes_logic(ax, 3, projection=projection)
|
|
1159
1156
|
|
|
1160
1157
|
if pose is None:
|
|
1161
1158
|
pose = self.pose
|
|
@@ -1210,7 +1207,6 @@ class CameraBase(ABC):
|
|
|
1210
1207
|
ax.add_collection3d(poly)
|
|
1211
1208
|
|
|
1212
1209
|
elif shape == "camera":
|
|
1213
|
-
|
|
1214
1210
|
# the box is centred at the origin and its centerline parallel to the
|
|
1215
1211
|
# z-axis. Its z-extent is -bh/2 to bh/2.
|
|
1216
1212
|
W = 0.5 # width & height of the box
|
|
@@ -1221,7 +1217,7 @@ class CameraBase(ABC):
|
|
|
1221
1217
|
a = 3 # length of axis line segments
|
|
1222
1218
|
|
|
1223
1219
|
# draw the box part of the camera
|
|
1224
|
-
|
|
1220
|
+
smb.plot_cuboid(
|
|
1225
1221
|
sides=np.r_[W, W, L] * scale,
|
|
1226
1222
|
pose=pose,
|
|
1227
1223
|
filled=solid,
|
|
@@ -1231,7 +1227,7 @@ class CameraBase(ABC):
|
|
|
1231
1227
|
)
|
|
1232
1228
|
|
|
1233
1229
|
# draw the lens
|
|
1234
|
-
|
|
1230
|
+
smb.plot_cylinder(
|
|
1235
1231
|
radius=cr * scale,
|
|
1236
1232
|
height=np.r_[L / 2, L / 2 + ch] * scale,
|
|
1237
1233
|
resolution=cn,
|
|
@@ -1305,7 +1301,6 @@ class CentralCamera(CameraBase):
|
|
|
1305
1301
|
"""
|
|
1306
1302
|
|
|
1307
1303
|
def __init__(self, f=1, distortion=None, **kwargs):
|
|
1308
|
-
|
|
1309
1304
|
super().__init__(camtype="perspective", **kwargs)
|
|
1310
1305
|
# TODO some of this logic to f and pp setters
|
|
1311
1306
|
self.f = f
|
|
@@ -1449,10 +1444,10 @@ class CentralCamera(CameraBase):
|
|
|
1449
1444
|
if P.ndim == 1:
|
|
1450
1445
|
P = P.reshape((-1, 1)) # make it a column
|
|
1451
1446
|
else:
|
|
1452
|
-
P =
|
|
1447
|
+
P = smb.getvector(P, out="col")
|
|
1453
1448
|
|
|
1454
1449
|
if P.shape[0] == 3:
|
|
1455
|
-
P =
|
|
1450
|
+
P = smb.e2h(P) # make it homogeneous
|
|
1456
1451
|
euclidean = True
|
|
1457
1452
|
else:
|
|
1458
1453
|
euclidean = False
|
|
@@ -1469,7 +1464,7 @@ class CentralCamera(CameraBase):
|
|
|
1469
1464
|
|
|
1470
1465
|
if euclidean:
|
|
1471
1466
|
# Euclidean points given, return Euclidean points
|
|
1472
|
-
x =
|
|
1467
|
+
x = smb.h2e(x)
|
|
1473
1468
|
|
|
1474
1469
|
# add Gaussian noise and distortion
|
|
1475
1470
|
if self._distortion:
|
|
@@ -1538,7 +1533,7 @@ class CentralCamera(CameraBase):
|
|
|
1538
1533
|
lines2d = []
|
|
1539
1534
|
C = self.C()
|
|
1540
1535
|
for line in lines:
|
|
1541
|
-
l =
|
|
1536
|
+
l = smb.vex(C @ line.skew() @ C.T)
|
|
1542
1537
|
x = l / np.max(np.abs(l)) # normalize by largest element
|
|
1543
1538
|
lines2d.append(x)
|
|
1544
1539
|
return np.column_stack(lines2d)
|
|
@@ -1587,7 +1582,7 @@ class CentralCamera(CameraBase):
|
|
|
1587
1582
|
|
|
1588
1583
|
:seealso: :meth:`C` :meth:`project_point` :meth:`project_line`
|
|
1589
1584
|
"""
|
|
1590
|
-
if not
|
|
1585
|
+
if not smb.ismatrix(Q, (4, 4)):
|
|
1591
1586
|
raise ValueError("expecting 4x4 conic matrix")
|
|
1592
1587
|
|
|
1593
1588
|
return self.C() @ Q @ self.C().T
|
|
@@ -1631,7 +1626,7 @@ class CentralCamera(CameraBase):
|
|
|
1631
1626
|
:seealso: :meth:`plot_epiline` :meth:`CentralCamera.F`
|
|
1632
1627
|
"""
|
|
1633
1628
|
# p is 3 x N, result is 3 x N
|
|
1634
|
-
return self.F(camera2) @
|
|
1629
|
+
return self.F(camera2) @ smb.e2h(p)
|
|
1635
1630
|
|
|
1636
1631
|
def plot_epiline(self, F, p, *fmt, **kwargs):
|
|
1637
1632
|
r"""
|
|
@@ -1673,7 +1668,7 @@ class CentralCamera(CameraBase):
|
|
|
1673
1668
|
:seealso: :meth:`plot_point` :meth:`epiline` :meth:`CentralCamera.F`
|
|
1674
1669
|
"""
|
|
1675
1670
|
# p is 3 x N, result is 3 x N
|
|
1676
|
-
self.plot_line2(F @
|
|
1671
|
+
self.plot_line2(F @ smb.e2h(p), *fmt, **kwargs)
|
|
1677
1672
|
|
|
1678
1673
|
def plot_line3(self, L, **kwargs):
|
|
1679
1674
|
"""
|
|
@@ -1733,8 +1728,8 @@ class CentralCamera(CameraBase):
|
|
|
1733
1728
|
Mi = np.linalg.inv(C[:3, :3])
|
|
1734
1729
|
v = C[:, 3]
|
|
1735
1730
|
lines = []
|
|
1736
|
-
for point in
|
|
1737
|
-
lines.append(Line3.PointDir(-Mi @ v, Mi @
|
|
1731
|
+
for point in smb.getmatrix(points, (2, None)).T:
|
|
1732
|
+
lines.append(Line3.PointDir(-Mi @ v, Mi @ smb.e2h(point)))
|
|
1738
1733
|
return Line3(lines)
|
|
1739
1734
|
|
|
1740
1735
|
@property
|
|
@@ -1820,7 +1815,7 @@ class CentralCamera(CameraBase):
|
|
|
1820
1815
|
return points
|
|
1821
1816
|
|
|
1822
1817
|
# convert to normalized image coordinates
|
|
1823
|
-
X = np.linalg.inv(self.K) *
|
|
1818
|
+
X = np.linalg.inv(self.K) * smb.e2h(points)
|
|
1824
1819
|
|
|
1825
1820
|
# unpack coordinates
|
|
1826
1821
|
u = X[0, :]
|
|
@@ -1848,7 +1843,7 @@ class CentralCamera(CameraBase):
|
|
|
1848
1843
|
ud = u + delta_u
|
|
1849
1844
|
vd = v + delta_v
|
|
1850
1845
|
|
|
1851
|
-
return self.K *
|
|
1846
|
+
return self.K * smb.e2h(np.r_[ud, vd]) # convert to pixel coords
|
|
1852
1847
|
|
|
1853
1848
|
@property
|
|
1854
1849
|
def fu(self):
|
|
@@ -1928,7 +1923,7 @@ class CentralCamera(CameraBase):
|
|
|
1928
1923
|
:type f: scalar or array_like(2)
|
|
1929
1924
|
:raises ValueError: incorrect length of ``f``
|
|
1930
1925
|
"""
|
|
1931
|
-
f =
|
|
1926
|
+
f = smb.getvector(f)
|
|
1932
1927
|
|
|
1933
1928
|
if len(f) == 1:
|
|
1934
1929
|
self._fu = f[0]
|
|
@@ -2156,7 +2151,6 @@ class CentralCamera(CameraBase):
|
|
|
2156
2151
|
valid = []
|
|
2157
2152
|
|
|
2158
2153
|
for i, image in enumerate(images):
|
|
2159
|
-
|
|
2160
2154
|
gray = image.mono().A
|
|
2161
2155
|
# Find the chess board corners
|
|
2162
2156
|
ret, corners = cv.findChessboardCorners(gray, gridshape, None)
|
|
@@ -2334,7 +2328,7 @@ class CentralCamera(CameraBase):
|
|
|
2334
2328
|
if d < 0:
|
|
2335
2329
|
raise ValueError(d, "plane distance d must be > 0")
|
|
2336
2330
|
|
|
2337
|
-
n =
|
|
2331
|
+
n = smb.getvector(n)
|
|
2338
2332
|
if n[2] < 0:
|
|
2339
2333
|
raise ValueError(n, "normal must be away from camera (n[2] >= 0)")
|
|
2340
2334
|
|
|
@@ -2409,7 +2403,7 @@ class CentralCamera(CameraBase):
|
|
|
2409
2403
|
)
|
|
2410
2404
|
|
|
2411
2405
|
mask = mask.ravel().astype(bool)
|
|
2412
|
-
e =
|
|
2406
|
+
e = smb.homtrans(H, p1[:, mask]) - p2[:, mask]
|
|
2413
2407
|
resid = np.linalg.norm(e)
|
|
2414
2408
|
|
|
2415
2409
|
if method in ("ransac", "lmeds"):
|
|
@@ -2464,7 +2458,7 @@ class CentralCamera(CameraBase):
|
|
|
2464
2458
|
for R, t in zip(rotations, translations):
|
|
2465
2459
|
# we normalize the rotation matrix, those returned by openCV can
|
|
2466
2460
|
# not quite proper SO(3) values
|
|
2467
|
-
pose = SE3.Rt(
|
|
2461
|
+
pose = SE3.Rt(smb.trnorm(R), t).inv()
|
|
2468
2462
|
T.append(pose)
|
|
2469
2463
|
return T, normals
|
|
2470
2464
|
|
|
@@ -2619,15 +2613,15 @@ class CentralCamera(CameraBase):
|
|
|
2619
2613
|
# add various return values
|
|
2620
2614
|
retval = [F]
|
|
2621
2615
|
if residual:
|
|
2622
|
-
e =
|
|
2616
|
+
e = smb.e2h(p2[:, mask]).T @ F @ smb.e2h(p1[:, mask])
|
|
2623
2617
|
resid = np.linalg.norm(np.diagonal(e))
|
|
2624
2618
|
retval.append(resid)
|
|
2625
2619
|
if method in ("ransac", "lmeds"):
|
|
2626
2620
|
retval.append(mask)
|
|
2627
2621
|
|
|
2628
2622
|
return retval
|
|
2629
|
-
# elines =
|
|
2630
|
-
# p1h =
|
|
2623
|
+
# elines = smb.e2h(p2).T @ F # homog lines, one per row
|
|
2624
|
+
# p1h = smb.e2h(p1)
|
|
2631
2625
|
# residuals = []
|
|
2632
2626
|
# for i, line in enumerate(elines):
|
|
2633
2627
|
# d = line @ p1h[:, i] / np.sqrt(line[0] ** 2 + line[1] ** 2)
|
|
@@ -2661,7 +2655,7 @@ class CentralCamera(CameraBase):
|
|
|
2661
2655
|
D = np.empty((p1.shape[1], p2.shape[1]))
|
|
2662
2656
|
|
|
2663
2657
|
# compute epipolar lines corresponding to p1
|
|
2664
|
-
l = F @
|
|
2658
|
+
l = F @ smb.e2h(p1)
|
|
2665
2659
|
for i in range(p1.shape[1]):
|
|
2666
2660
|
for j in range(p2.shape[1]):
|
|
2667
2661
|
D[i, j] = np.abs(
|
|
@@ -2710,7 +2704,7 @@ class CentralCamera(CameraBase):
|
|
|
2710
2704
|
else:
|
|
2711
2705
|
raise ValueError("bad type")
|
|
2712
2706
|
|
|
2713
|
-
return
|
|
2707
|
+
return smb.skew(T21.t) @ T21.R
|
|
2714
2708
|
|
|
2715
2709
|
def points2E(self, p1, p2, method=None, K=None, **kwargs):
|
|
2716
2710
|
"""
|
|
@@ -2815,14 +2809,13 @@ class CentralCamera(CameraBase):
|
|
|
2815
2809
|
return SE3.Rt(R, t).inv()
|
|
2816
2810
|
|
|
2817
2811
|
else:
|
|
2818
|
-
|
|
2819
2812
|
R1, R2, t = cv.decomposeEssentialMat(E=E)
|
|
2820
2813
|
# not explicitly stated, but seems that this returns (R, t) from
|
|
2821
2814
|
# camera to world
|
|
2822
2815
|
|
|
2823
2816
|
possibles = [(R1, t), (R1, -t), (R2, t), (R2, -t)]
|
|
2824
2817
|
|
|
2825
|
-
if
|
|
2818
|
+
if smb.isvector(P, 3):
|
|
2826
2819
|
for Rt in possibles:
|
|
2827
2820
|
pose = SE3.Rt(Rt[0], Rt[1]).inv()
|
|
2828
2821
|
p = self.project_point(P, pose=pose, behind=True)
|
|
@@ -2884,10 +2877,10 @@ class CentralCamera(CameraBase):
|
|
|
2884
2877
|
:seealso: :meth:`flowfield` :meth:`visjac_p_polar` :meth:`visjac_l` :meth:`visjac_e`
|
|
2885
2878
|
"""
|
|
2886
2879
|
|
|
2887
|
-
uv =
|
|
2880
|
+
uv = smb.getmatrix(uv, (2, None))
|
|
2888
2881
|
Z = depth
|
|
2889
2882
|
|
|
2890
|
-
Z =
|
|
2883
|
+
Z = smb.getvector(Z)
|
|
2891
2884
|
if len(Z) == 1:
|
|
2892
2885
|
Z = np.repeat(Z, uv.shape[1])
|
|
2893
2886
|
elif len(Z) != uv.shape[1]:
|
|
@@ -2899,9 +2892,8 @@ class CentralCamera(CameraBase):
|
|
|
2899
2892
|
Kinv = np.linalg.inv(K)
|
|
2900
2893
|
|
|
2901
2894
|
for z, p in zip(Z, uv.T): # iterate over each column (point)
|
|
2902
|
-
|
|
2903
2895
|
# convert to normalized image-plane coordinates
|
|
2904
|
-
xy = Kinv @
|
|
2896
|
+
xy = Kinv @ smb.e2h(p)
|
|
2905
2897
|
x = xy[0, 0]
|
|
2906
2898
|
y = xy[1, 0]
|
|
2907
2899
|
|
|
@@ -2962,14 +2954,13 @@ class CentralCamera(CameraBase):
|
|
|
2962
2954
|
"""
|
|
2963
2955
|
|
|
2964
2956
|
J = []
|
|
2965
|
-
p =
|
|
2957
|
+
p = smb.getmatrix(p, (2, None))
|
|
2966
2958
|
f = self.f[0]
|
|
2967
2959
|
|
|
2968
|
-
if
|
|
2960
|
+
if smb.isscalar(Z):
|
|
2969
2961
|
Z = [Z] * p.shape[1]
|
|
2970
2962
|
|
|
2971
2963
|
for (phi, r), Zk in zip(p.T, Z):
|
|
2972
|
-
|
|
2973
2964
|
# k = (f**2 + r**2) / f
|
|
2974
2965
|
# k2 = f / (r * Zk)
|
|
2975
2966
|
|
|
@@ -3071,7 +3062,7 @@ class CentralCamera(CameraBase):
|
|
|
3071
3062
|
|
|
3072
3063
|
a, b, c, d = plane
|
|
3073
3064
|
|
|
3074
|
-
lines =
|
|
3065
|
+
lines = smb.getmatrix(lines, (2, None))
|
|
3075
3066
|
jac = []
|
|
3076
3067
|
for theta, rho in lines.T:
|
|
3077
3068
|
sth = np.sin(theta)
|
|
@@ -3232,7 +3223,7 @@ class CentralCamera(CameraBase):
|
|
|
3232
3223
|
|
|
3233
3224
|
:seealso: :meth:`visjac_p`
|
|
3234
3225
|
"""
|
|
3235
|
-
vel =
|
|
3226
|
+
vel = smb.getvector(vel, 6)
|
|
3236
3227
|
|
|
3237
3228
|
u = np.arange(0, self.nu, 50)
|
|
3238
3229
|
v = np.arange(0, self.nv, 50)
|
|
@@ -3387,7 +3378,6 @@ class FishEyeCamera(CameraBase):
|
|
|
3387
3378
|
"""
|
|
3388
3379
|
|
|
3389
3380
|
def __init__(self, k=None, projection="equiangular", **kwargs):
|
|
3390
|
-
|
|
3391
3381
|
super().__init__(camtype="fisheye", **kwargs)
|
|
3392
3382
|
|
|
3393
3383
|
self.projection = projection
|
|
@@ -3469,7 +3459,7 @@ class FishEyeCamera(CameraBase):
|
|
|
3469
3459
|
:seealso: :meth:`plot_point`
|
|
3470
3460
|
"""
|
|
3471
3461
|
|
|
3472
|
-
P =
|
|
3462
|
+
P = smb.getmatrix(P, (3, None))
|
|
3473
3463
|
|
|
3474
3464
|
if pose is not None:
|
|
3475
3465
|
T = self.pose.inv()
|
|
@@ -3479,7 +3469,7 @@ class FishEyeCamera(CameraBase):
|
|
|
3479
3469
|
T *= objpose
|
|
3480
3470
|
|
|
3481
3471
|
R = np.sqrt(np.sum(P**2, axis=0))
|
|
3482
|
-
phi = np.arctan2(P[1, :], P[0, :])
|
|
3472
|
+
phi = np.arctan2(-P[1, :], P[0, :])
|
|
3483
3473
|
theta = np.arccos(P[2, :] / R)
|
|
3484
3474
|
|
|
3485
3475
|
r = self.rfunc(theta)
|
|
@@ -3538,7 +3528,6 @@ class CatadioptricCamera(CameraBase):
|
|
|
3538
3528
|
"""
|
|
3539
3529
|
|
|
3540
3530
|
def __init__(self, k=None, projection="equiangular", maxangle=None, **kwargs):
|
|
3541
|
-
|
|
3542
3531
|
super().__init__(camtype="catadioptric", **kwargs)
|
|
3543
3532
|
|
|
3544
3533
|
self.projection = projection
|
|
@@ -3613,7 +3602,7 @@ class CatadioptricCamera(CameraBase):
|
|
|
3613
3602
|
|
|
3614
3603
|
:seealso: :meth:`plot_point`
|
|
3615
3604
|
"""
|
|
3616
|
-
P =
|
|
3605
|
+
P = smb.getmatrix(P, (3, None))
|
|
3617
3606
|
|
|
3618
3607
|
if pose is not None:
|
|
3619
3608
|
T = self.pose.inv()
|
|
@@ -3625,9 +3614,10 @@ class CatadioptricCamera(CameraBase):
|
|
|
3625
3614
|
P = T * P # transform points to camera frame
|
|
3626
3615
|
|
|
3627
3616
|
# project to the image plane
|
|
3628
|
-
R = np.sqrt(np.sum(P**2, axis=0))
|
|
3629
3617
|
phi = np.arctan2(P[1, :], P[0, :])
|
|
3630
|
-
|
|
3618
|
+
|
|
3619
|
+
Rxy = np.sqrt(np.sum(P[:2, :] ** 2, axis=0)) # sqrt(X^2 + Y^2)
|
|
3620
|
+
theta = np.arctan(P[2, :] / Rxy)
|
|
3631
3621
|
|
|
3632
3622
|
r = self.rfunc(theta) # depends on projection model
|
|
3633
3623
|
x = r * np.cos(phi)
|
|
@@ -3660,7 +3650,6 @@ class SphericalCamera(CameraBase):
|
|
|
3660
3650
|
"""
|
|
3661
3651
|
|
|
3662
3652
|
def __init__(self, **kwargs):
|
|
3663
|
-
|
|
3664
3653
|
# invoke the superclass constructor
|
|
3665
3654
|
super().__init__(
|
|
3666
3655
|
camtype="spherical",
|
|
@@ -3712,7 +3701,7 @@ class SphericalCamera(CameraBase):
|
|
|
3712
3701
|
|
|
3713
3702
|
:seealso: :meth:`plot_point`
|
|
3714
3703
|
"""
|
|
3715
|
-
P =
|
|
3704
|
+
P = smb.getmatrix(P, (3, None))
|
|
3716
3705
|
|
|
3717
3706
|
if pose is None:
|
|
3718
3707
|
pose = self.pose
|
|
@@ -3730,7 +3719,9 @@ class SphericalCamera(CameraBase):
|
|
|
3730
3719
|
z = P[2, :] / R
|
|
3731
3720
|
|
|
3732
3721
|
phi = np.arctan2(y, x)
|
|
3733
|
-
|
|
3722
|
+
r = np.sqrt(x**2 + y**2)
|
|
3723
|
+
theta = np.arcsin(r)
|
|
3724
|
+
|
|
3734
3725
|
return np.array([phi, theta])
|
|
3735
3726
|
|
|
3736
3727
|
def visjac_p(self, p, depth=None):
|
|
@@ -3761,7 +3752,7 @@ class SphericalCamera(CameraBase):
|
|
|
3761
3752
|
"""
|
|
3762
3753
|
|
|
3763
3754
|
J = []
|
|
3764
|
-
if
|
|
3755
|
+
if smb.isscalar(depth):
|
|
3765
3756
|
depth = [depth] * p.shape[1]
|
|
3766
3757
|
|
|
3767
3758
|
for (phi, theta), R in zip(p.T, depth):
|
|
@@ -3780,7 +3771,7 @@ class SphericalCamera(CameraBase):
|
|
|
3780
3771
|
return np.vstack(J)
|
|
3781
3772
|
|
|
3782
3773
|
def plot(self, frame=False, **kwargs):
|
|
3783
|
-
|
|
3774
|
+
smb.plot_sphere(
|
|
3784
3775
|
radius=1,
|
|
3785
3776
|
filled=True,
|
|
3786
3777
|
color="lightyellow",
|
|
@@ -3899,11 +3890,11 @@ class SphericalCamera(CameraBase):
|
|
|
3899
3890
|
# if P.ndim == 1:
|
|
3900
3891
|
# P = P.reshape((-1, 1)) # make it a column
|
|
3901
3892
|
# else:
|
|
3902
|
-
# P =
|
|
3893
|
+
# P = smb.getvector(P, out='col')
|
|
3903
3894
|
|
|
3904
3895
|
# # make it homogeneous if not already
|
|
3905
3896
|
# if P.shape[0] == 3:
|
|
3906
|
-
# P =
|
|
3897
|
+
# P = smb.e2h(P)
|
|
3907
3898
|
|
|
3908
3899
|
# # project 3D points
|
|
3909
3900
|
|
|
@@ -3915,7 +3906,7 @@ class SphericalCamera(CameraBase):
|
|
|
3915
3906
|
# if behind:
|
|
3916
3907
|
# x[2, x[2, :] < 0] = np.nan # points behind the camera are set to NaN
|
|
3917
3908
|
|
|
3918
|
-
# x =
|
|
3909
|
+
# x = smb.h2e(x)
|
|
3919
3910
|
|
|
3920
3911
|
# # add Gaussian noise and distortion
|
|
3921
3912
|
# x = self.add_noise_distortion(x)
|
|
@@ -4009,7 +4000,7 @@ if __name__ == "__main__":
|
|
|
4009
4000
|
# print(JA)
|
|
4010
4001
|
# print(JB)
|
|
4011
4002
|
|
|
4012
|
-
#
|
|
4003
|
+
# smb.plotvol3(2)
|
|
4013
4004
|
|
|
4014
4005
|
# cam.plot_camera(scale=0.5, shape='camera', T=SE3.Ry(np.pi/2))
|
|
4015
4006
|
|