machinevision-toolbox-python 1.0.0__py3-none-any.whl → 1.0.2__py3-none-any.whl

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.
Files changed (43) hide show
  1. {machinevision_toolbox_python-1.0.0.dist-info → machinevision_toolbox_python-1.0.2.dist-info}/METADATA +32 -30
  2. machinevision_toolbox_python-1.0.2.dist-info/RECORD +58 -0
  3. {machinevision_toolbox_python-1.0.0.dist-info → machinevision_toolbox_python-1.0.2.dist-info}/WHEEL +1 -2
  4. machinevision_toolbox_python-1.0.2.dist-info/entry_points.txt +4 -0
  5. machinevisiontoolbox/Camera.py +54 -63
  6. machinevisiontoolbox/ImageBlobs.py +689 -112
  7. machinevisiontoolbox/ImageConstants.py +217 -70
  8. machinevisiontoolbox/ImageCore.py +328 -253
  9. machinevisiontoolbox/ImageFiducials.py +590 -0
  10. machinevisiontoolbox/ImageIO.py +5 -6
  11. machinevisiontoolbox/ImagePointFeatures.py +6 -54
  12. machinevisiontoolbox/ImageProcessing.py +2 -1
  13. machinevisiontoolbox/ImageRegionFeatures.py +3 -377
  14. machinevisiontoolbox/ImageReshape.py +251 -229
  15. machinevisiontoolbox/ImageSpatial.py +218 -119
  16. machinevisiontoolbox/ImageWholeFeatures.py +240 -34
  17. machinevisiontoolbox/PointCloud.py +201 -73
  18. machinevisiontoolbox/Sources.py +2 -2
  19. machinevisiontoolbox/__init__.py +2 -0
  20. machinevisiontoolbox/aruco0.pdf +0 -0
  21. machinevisiontoolbox/aruco50.pdf +0 -0
  22. machinevisiontoolbox/base/__init__.py +3 -0
  23. machinevisiontoolbox/base/color.py +41 -43
  24. machinevisiontoolbox/base/graphics.py +324 -243
  25. machinevisiontoolbox/base/imageio.py +99 -20
  26. machinevisiontoolbox/base/meshgrid.py +18 -4
  27. machinevisiontoolbox/base/version.py +26 -0
  28. machinevisiontoolbox/bin/ce.py +27 -0
  29. machinevisiontoolbox/bin/imtool.py +161 -0
  30. machinevisiontoolbox/bin/mvtbtool.py +192 -0
  31. machinevisiontoolbox/bin/tagtool.py +250 -0
  32. machinevisiontoolbox/blocks/Icons/camera.png +0 -0
  33. machinevisiontoolbox/blocks/Icons/estpose_p.png +0 -0
  34. machinevisiontoolbox/blocks/Icons/icons.sh +4 -0
  35. machinevisiontoolbox/blocks/Icons/imageplane.png +0 -0
  36. machinevisiontoolbox/blocks/Icons/visjac_p.png +0 -0
  37. machinevisiontoolbox/blocks/test_blocks.py +0 -0
  38. machinevisiontoolbox/decorators.py +82 -0
  39. machinevisiontoolbox/machinevision-toolbox-python.code-workspace +7 -0
  40. machinevision_toolbox_python-1.0.0.dist-info/RECORD +0 -44
  41. machinevision_toolbox_python-1.0.0.dist-info/entry_points.txt +0 -2
  42. machinevision_toolbox_python-1.0.0.dist-info/top_level.txt +0 -1
  43. {machinevision_toolbox_python-1.0.0.dist-info → machinevision_toolbox_python-1.0.2.dist-info/licenses}/LICENSE +0 -0
@@ -1,48 +1,51 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: machinevision-toolbox-python
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: Python tools for machine vision - education and research
5
- Author: Dorian Tsai
6
- Author-email: Peter Corke <rvc@petercorke.com>
7
5
  Project-URL: Homepage, https://github.com/petercorke/machinevision-toolbox-python
8
6
  Project-URL: Bug Tracker, https://github.com/pypa/sampleproject/issues
9
7
  Project-URL: Documentation, https://petercorke.github.io/machinevision-toolbox-python
10
8
  Project-URL: GitHub Source, https://github.com/petercorke/machinevision-toolbox-python
11
9
  Project-URL: Changelog, https://github.com/petercorke/machinevision-toolbox-python/blob/master/CHANGELOG.md
12
- Keywords: machine vision,computer vision,multiview geometry,stereo vision,bundle adjustment,visual servoing,image features,color,blobs,morphology,image segmentation,opencv,open3d
10
+ Author: Dorian Tsai
11
+ Author-email: Peter Corke <rvc@petercorke.com>
12
+ License-File: LICENSE
13
+ Keywords: blobs,bundle adjustment,color,computer vision,image features,image segmentation,machine vision,morphology,multiview geometry,open3d,opencv,stereo vision,visual servoing
13
14
  Classifier: Development Status :: 5 - Production/Stable
14
15
  Classifier: Intended Audience :: Developers
15
- Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
16
18
  Classifier: Programming Language :: Python :: 3.10
17
19
  Classifier: Programming Language :: Python :: 3.11
18
20
  Classifier: Programming Language :: Python :: 3.12
19
- Classifier: License :: OSI Approved :: MIT License
20
- Classifier: Operating System :: OS Independent
21
- Requires-Python: >=3.7
22
- Description-Content-Type: text/markdown
23
- License-File: LICENSE
24
- Requires-Dist: numpy<2.0.0,>=1.17.4
25
- Requires-Dist: scipy
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: ansitable
26
23
  Requires-Dist: matplotlib
27
- Requires-Dist: opencv-python
28
- Requires-Dist: open3d
24
+ Requires-Dist: mvtb-data
25
+ Requires-Dist: numpy
29
26
  Requires-Dist: opencv-contrib-python
30
- Requires-Dist: spatialmath-python
27
+ Requires-Dist: opencv-python
31
28
  Requires-Dist: pgraph-python
32
- Requires-Dist: ansitable
33
- Requires-Dist: mvtb-data
29
+ Requires-Dist: scipy
30
+ Requires-Dist: spatialmath-python
34
31
  Provides-Extra: dev
35
- Requires-Dist: pytest; extra == "dev"
36
- Requires-Dist: coverage; extra == "dev"
37
- Requires-Dist: flake8; extra == "dev"
32
+ Requires-Dist: coverage; extra == 'dev'
33
+ Requires-Dist: flake8; extra == 'dev'
34
+ Requires-Dist: pytest; extra == 'dev'
38
35
  Provides-Extra: docs
39
- Requires-Dist: sphinx; extra == "docs"
40
- Requires-Dist: recommonmark; extra == "docs"
41
- Requires-Dist: sphinx-rtd-theme; extra == "docs"
42
- Requires-Dist: sphinx-autorun; extra == "docs"
43
- Requires-Dist: sphinxcontrib-jsmath; extra == "docs"
44
- Requires-Dist: sphinx-markdown-tables; extra == "docs"
45
- Requires-Dist: sphinx-favicon; extra == "docs"
36
+ Requires-Dist: recommonmark; extra == 'docs'
37
+ Requires-Dist: sphinx; extra == 'docs'
38
+ Requires-Dist: sphinx-autorun; extra == 'docs'
39
+ Requires-Dist: sphinx-favicon; extra == 'docs'
40
+ Requires-Dist: sphinx-markdown-tables; extra == 'docs'
41
+ Requires-Dist: sphinx-rtd-theme; extra == 'docs'
42
+ Requires-Dist: sphinxcontrib-jsmath; extra == 'docs'
43
+ Provides-Extra: jupyter
44
+ Requires-Dist: ipympl; extra == 'jupyter'
45
+ Requires-Dist: ipywidgets; extra == 'jupyter'
46
+ Provides-Extra: open3d
47
+ Requires-Dist: open3d-python; extra == 'open3d'
48
+ Description-Content-Type: text/markdown
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">Examples and details</a></li>
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>
@@ -0,0 +1,58 @@
1
+ machinevisiontoolbox/BagOfWords.py,sha256=kHAt6P5Tz5iWpP9N-fcdL3KTwimBqxu9QQ1WRs04Lzc,19680
2
+ machinevisiontoolbox/BundleAdjust.py,sha256=syBFkXwJcRWpNr0k6gu-J3shzH0ozbgOgwaZp844fqk,36081
3
+ machinevisiontoolbox/Camera.py,sha256=Sz6MLiVpLEKX_EtBNcd3AhTjI3Qe_4E9JuB9ERgiugA,136424
4
+ machinevisiontoolbox/ImageBlobs.py,sha256=p9LL28SKUUVuRVb8wrxDPyXygmKqni9ReQFntrEv3ZY,73599
5
+ machinevisiontoolbox/ImageColor.py,sha256=V4T_fs0EvFJegAQrNr-3pR7rg7Dye00g2V3JVEK4oOA,17111
6
+ machinevisiontoolbox/ImageConstants.py,sha256=a9eCbfUFUiQj0HsEH291MjYYmXGJjYSIl6Lg7idDppw,20629
7
+ machinevisiontoolbox/ImageCore.py,sha256=rTGHVYw9ayXmDKAXDaLAMuEKVk65aFQqeSUBxt_4qJ8,98404
8
+ machinevisiontoolbox/ImageFiducials.py,sha256=8QwHUrMclP3rLMr2swO44nORo6AJVuIZT777-1QSB44,22341
9
+ machinevisiontoolbox/ImageIO.py,sha256=9MOUSrM1xnkoHYk2W77G0IVPcVjX_YTCLfNg2ZbEFZ4,21935
10
+ machinevisiontoolbox/ImageLineFeatures.py,sha256=IlWSZOrvLnzvLx1vf4GuXb4Icpj214jz9FCDleguV9s,9104
11
+ machinevisiontoolbox/ImageMorph.py,sha256=1xn29MyEkrYRbw-Dg8X6qFKTf4_MDTQ5ddi7y8D-arw,23759
12
+ machinevisiontoolbox/ImageMultiview.py,sha256=wQWcq2Er-EzNNQ7_0mZRuID9VFh4rCjXPxZ-yMiQ-W4,14703
13
+ machinevisiontoolbox/ImagePointFeatures.py,sha256=Ran5vzBC3-_brg_X3b-qdXjpX0boEnzznhnkKD8J-wg,75269
14
+ machinevisiontoolbox/ImageProcessing.py,sha256=pZuaVRlpskO2L3JCDh6BOVEfpTUhqKXwPh4usfcTKBM,38123
15
+ machinevisiontoolbox/ImageRegionFeatures.py,sha256=MpqavHwkpevg_dD3zia0wMZMuOmatR2ndZ_TBQ_AbqE,14455
16
+ machinevisiontoolbox/ImageReshape.py,sha256=3DAlTBpUdljzJwxyCswRoNiTbGBBP8nTWNpsHoPn03I,47470
17
+ machinevisiontoolbox/ImageSpatial.py,sha256=dxTiml3DLp3UXV5x4auo3IuQQJVXRKrjduOpogIeklE,71856
18
+ machinevisiontoolbox/ImageWholeFeatures.py,sha256=OBGZ_elQ6LlOxN1Hgr4dGf4AOUdgxfAD2qkgAaA7uuU,34874
19
+ machinevisiontoolbox/PointCloud.py,sha256=AMQSXsgVneoEtecUVsvcup009Ja13NcsMZ2kMddyN-E,23455
20
+ machinevisiontoolbox/Sources.py,sha256=mcBYA9ccvqXjPK9npwt9zAnuP18sw-q2zhwem4xW_to,28572
21
+ machinevisiontoolbox/VisualServo.py,sha256=PlHCz_jbvV1JFfDrePQQ7cP94Wr5nliulHtYEMGwJtw,59294
22
+ machinevisiontoolbox/__init__.py,sha256=UcoSG7Cr9Qot3mg2q748jBbo3TUB2lch4VWzOydKe8U,1363
23
+ machinevisiontoolbox/aruco0.pdf,sha256=a_JZT-TfVv7tQNOvlHSZPf9QCNiOScm_q30jMF8T2ME,75233
24
+ machinevisiontoolbox/aruco50.pdf,sha256=wUwqNaDmZ5EFNl1GNF_O3YRztWOZBhTq7DdMdMTskQw,77285
25
+ machinevisiontoolbox/camera_derivatives.py,sha256=uChdvsXC-25Cg7-xH7tIbxe3tcxxJGQ_nslSiCvnL88,17557
26
+ machinevisiontoolbox/decorators.py,sha256=hBZzLFQDhVOS3mj5Rs4GHbIIf30g_C2LO5m2xyLzH7s,2281
27
+ machinevisiontoolbox/fiducial.py,sha256=syC7iIz95nYBTr_njo4ZzLXOyAdAIqoAZq_wRVhyUHQ,1374
28
+ machinevisiontoolbox/machinevision-toolbox-python.code-workspace,sha256=pQBvdNW9qEbMp3qYKhvOgd3NYoO7vqnnbPMh4H8op_Y,44
29
+ machinevisiontoolbox/mvtb_types.py,sha256=66Oa8-J0UyBTtZQ0hH1B9qPqqw7i7dTCYe3CvgnGpXg,434
30
+ machinevisiontoolbox/newcameras.py,sha256=iQ8Fduiub4Clh1JIEVvQTXZVqXrmgzf0Y5iMPGTOW-w,1225
31
+ machinevisiontoolbox/base/__init__.py,sha256=nQTxEyan6bOvovQKUWjag-VZzfM6P20CwUv7sbCrJEs,1547
32
+ machinevisiontoolbox/base/color.py,sha256=GQSQIHUKrKWxuBJ4a6kfTy05RQKUhFKA4q4JyjIU358,55067
33
+ machinevisiontoolbox/base/data.py,sha256=tDwUOHzpvGnkzlUaA3p5jQr1rlv9WIr6taRBv3gnmeU,5988
34
+ machinevisiontoolbox/base/esttheta.py,sha256=pYFguhXwo9FoaH0sRAXxrcEkECYttDPnHWBi1YMfISY,2323
35
+ machinevisiontoolbox/base/findpeaks.py,sha256=e0dcG6ZqHMwpzRFQrZH9-OITzhspi6Lq1TZoS37IPQY,10377
36
+ machinevisiontoolbox/base/graphics.py,sha256=L0YuIi-HHOhogtmfwMSy9SD5tG0zdxWAYojbhCrRYCc,28956
37
+ machinevisiontoolbox/base/imageio.py,sha256=qUZL7xz-S3o9Xh8vLVQAWqsL7HQQNtSUROERWsUimSo,40393
38
+ machinevisiontoolbox/base/meshgrid.py,sha256=82u1ijws1zoXl5NLzTAMJjry9VEZuWqb_Akz6f1JJ8k,2937
39
+ machinevisiontoolbox/base/shapes.py,sha256=2FmjeuDnehNF5ZmssFDawmblDpKhuVUI3CmXCcILJxg,9926
40
+ machinevisiontoolbox/base/types.py,sha256=3znb81yTFb7sLrgjgt0P5q5wZa9_iRZGw_hWbINhCxc,4716
41
+ machinevisiontoolbox/base/version.py,sha256=Wf76g7w1Ikff-3e-hlExYVRxvV92p04K1m_PZLH9T_I,875
42
+ machinevisiontoolbox/bin/ce.py,sha256=012zsKMT58WZxIsLq8nzDO6b-YK04kduaTwZLSwTdrI,846
43
+ machinevisiontoolbox/bin/imtool.py,sha256=7nHNMuoI0-5y4EdWWPkWlwKdgKVqDDbYPw2bozICLQk,4920
44
+ machinevisiontoolbox/bin/mvtbtool.py,sha256=ehzLW6mwkNsQJVW599NFZ3k5W3ANm9UHBnAP_wLCnsg,5740
45
+ machinevisiontoolbox/bin/tagtool.py,sha256=Gfre8skzAwZystfGFv18W6rNcnIykvtBoCvik80TWzw,7224
46
+ machinevisiontoolbox/blocks/__init__.py,sha256=EsdfK2WxYLSo0SA5HSmlgsivLT1kDnoH9v-RTBDnWwc,142
47
+ machinevisiontoolbox/blocks/camera.py,sha256=qWT_LoDFcZkCAlRqQkRDzX0fr4EvkEgdtGo0QPoO_8s,9776
48
+ machinevisiontoolbox/blocks/test_blocks.py,sha256=ZKsDG_nG9g1t_OIFR6vX823yJojEAi5mtqj9PxKoDrg,1701
49
+ machinevisiontoolbox/blocks/Icons/camera.png,sha256=CGcTB_llMoucN-rfnP6ZP_7AfE_92z6JnCdam-hDLgs,1642
50
+ machinevisiontoolbox/blocks/Icons/estpose_p.png,sha256=1XrwL4OkotGWMwKmhnar3tt8cQWUdZiO7PxXD354T-E,4320
51
+ machinevisiontoolbox/blocks/Icons/icons.sh,sha256=teezrmF3es8c3-MvwG1lDCt9SKWEqA0eVHOKFeBugig,115
52
+ machinevisiontoolbox/blocks/Icons/imageplane.png,sha256=34FYQMzkq6foxvRU8pn0KkcHxpHRvsJRJSYKfNu13Eg,3902
53
+ machinevisiontoolbox/blocks/Icons/visjac_p.png,sha256=8X023l-C9Y5DfAN8wCdWYjSjq6wp1vRzuZ85sUbwxv8,3819
54
+ machinevision_toolbox_python-1.0.2.dist-info/METADATA,sha256=dLXvahd9CC0ah59W8SfIYchw7zDHjGz0AtKSLcvQiO8,19851
55
+ machinevision_toolbox_python-1.0.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
56
+ machinevision_toolbox_python-1.0.2.dist-info/entry_points.txt,sha256=ZX7Ox5l4VcwNurmTuD85Um5NpAipiKthfVe16cccWU8,162
57
+ machinevision_toolbox_python-1.0.2.dist-info/licenses/LICENSE,sha256=niCzY_CzbIMKuUZlUkGimjrKp0vkLAtcwFmoSuSKrdw,1068
58
+ machinevision_toolbox_python-1.0.2.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.7.0)
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ imtool = machinevisiontoolbox.bin.imtool:main
3
+ mvtbtool = machinevisiontoolbox.bin.mvtbtool:main
4
+ tagtool = machinevisiontoolbox.bin.tagtool:main
@@ -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
- # from collections import namedtuple
30
- from spatialmath import SE3
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 = base.getvector(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 = base.getvector(npix, dtype="int")
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 = base.getvector(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 = base.getvector(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
- base.plot_homline(l, *args, ax=self._ax, **kwargs)
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 = smbase.axes_logic(ax, 3, projection=projection)
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
- smbase.plot_cuboid(
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
- smbase.plot_cylinder(
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 = base.getvector(P, out="col")
1447
+ P = smb.getvector(P, out="col")
1453
1448
 
1454
1449
  if P.shape[0] == 3:
1455
- P = base.e2h(P) # make it homogeneous
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 = base.h2e(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 = base.vex(C @ line.skew() @ C.T)
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 smbase.ismatrix(Q, (4, 4)):
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) @ base.e2h(p)
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 @ base.e2h(p), *fmt, **kwargs)
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 base.getmatrix(points, (2, None)).T:
1737
- lines.append(Line3.PointDir(-Mi @ v, Mi @ smbase.e2h(point)))
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) * smbase.e2h(points)
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 * smbase.e2h(np.r_[ud, vd]) # convert to pixel coords
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 = base.getvector(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 = base.getvector(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 = base.homtrans(H, p1[:, mask]) - p2[:, mask]
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(smbase.trnorm(R), t).inv()
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 = base.e2h(p2[:, mask]).T @ F @ base.e2h(p1[:, mask])
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 = base.e2h(p2).T @ F # homog lines, one per row
2630
- # p1h = base.e2h(p1)
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 @ base.e2h(p1)
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 base.skew(T21.t) @ T21.R
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 base.isvector(P, 3):
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 = base.getmatrix(uv, (2, None))
2880
+ uv = smb.getmatrix(uv, (2, None))
2888
2881
  Z = depth
2889
2882
 
2890
- Z = base.getvector(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 @ base.e2h(p)
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 = smbase.getmatrix(p, (2, None))
2957
+ p = smb.getmatrix(p, (2, None))
2966
2958
  f = self.f[0]
2967
2959
 
2968
- if smbase.isscalar(Z):
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 = smbase.getmatrix(lines, (2, None))
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 = base.getvector(vel, 6)
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 = base.getmatrix(P, (3, None))
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 = base.getmatrix(P, (3, None))
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
- theta = np.arccos(P[2, :] / R)
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 = base.getmatrix(P, (3, None))
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
- theta = np.arccos(z)
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 smbase.isscalar(depth):
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
- smbase.plot_sphere(
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 = base.getvector(P, out='col')
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 = base.e2h(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 = base.h2e(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
- # smbase.plotvol3(2)
4003
+ # smb.plotvol3(2)
4013
4004
 
4014
4005
  # cam.plot_camera(scale=0.5, shape='camera', T=SE3.Ry(np.pi/2))
4015
4006