machinevision-toolbox-python 2.0.0__py3-none-any.whl → 2.1.0__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 (32) hide show
  1. {machinevision_toolbox_python-2.0.0.dist-info → machinevision_toolbox_python-2.1.0.dist-info}/METADATA +13 -5
  2. {machinevision_toolbox_python-2.0.0.dist-info → machinevision_toolbox_python-2.1.0.dist-info}/RECORD +21 -31
  3. {machinevision_toolbox_python-2.0.0.dist-info → machinevision_toolbox_python-2.1.0.dist-info}/WHEEL +1 -1
  4. machinevisiontoolbox/BundleAdjust.py +1 -1
  5. machinevisiontoolbox/Camera.py +95 -80
  6. machinevisiontoolbox/ImageBlobs.py +209 -29
  7. machinevisiontoolbox/ImageCore.py +105 -97
  8. machinevisiontoolbox/ImageIO.py +5 -1
  9. machinevisiontoolbox/ImagePointFeatures.py +8 -6
  10. machinevisiontoolbox/ImageProcessing.py +1 -1
  11. machinevisiontoolbox/ImageRegionFeatures.py +9 -6
  12. machinevisiontoolbox/ImageWholeFeatures.py +113 -72
  13. machinevisiontoolbox/Sources.py +20 -4
  14. machinevisiontoolbox/__init__.py +1 -1
  15. machinevisiontoolbox/base/imageio.py +68 -33
  16. machinevisiontoolbox/bin/_iminteractive.py +461 -0
  17. machinevisiontoolbox/bin/bagtool.py +120 -6
  18. machinevisiontoolbox/bin/imtool.py +34 -5
  19. machinevisiontoolbox/bin/mvtbtool.py +12 -5
  20. machinevisiontoolbox/ImageCore.docstring +0 -2877
  21. machinevisiontoolbox/aruco0.pdf +0 -0
  22. machinevisiontoolbox/aruco50.pdf +0 -0
  23. machinevisiontoolbox/bin/labeltool.py +0 -147
  24. machinevisiontoolbox/blocks/Icons/icons.sh +0 -4
  25. machinevisiontoolbox/cvfuncs.py +0 -40
  26. machinevisiontoolbox/docbugs.py +0 -47
  27. machinevisiontoolbox/newcameras.py +0 -55
  28. machinevisiontoolbox/test_skimage.py +0 -12
  29. machinevisiontoolbox/testblobplots.py +0 -17
  30. machinevisiontoolbox/x.json +0 -296
  31. {machinevision_toolbox_python-2.0.0.dist-info → machinevision_toolbox_python-2.1.0.dist-info}/entry_points.txt +0 -0
  32. {machinevision_toolbox_python-2.0.0.dist-info → machinevision_toolbox_python-2.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machinevision-toolbox-python
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: Object-oriented machine vision for Python.
5
5
  Project-URL: Homepage, https://github.com/petercorke/machinevision-toolbox-python
6
6
  Project-URL: Bug Tracker, https://github.com/pypa/sampleproject/issues
@@ -23,8 +23,8 @@ Requires-Dist: ansitable
23
23
  Requires-Dist: matplotlib
24
24
  Requires-Dist: mvtb-data
25
25
  Requires-Dist: numpy
26
- Requires-Dist: opencv-contrib-python
27
- Requires-Dist: opencv-python
26
+ Requires-Dist: opencv-contrib-python<5.0.0
27
+ Requires-Dist: opencv-python<5.0.0
28
28
  Requires-Dist: pgraph-python
29
29
  Requires-Dist: pillow
30
30
  Requires-Dist: requests
@@ -33,8 +33,10 @@ Requires-Dist: spatialmath-python
33
33
  Requires-Dist: tqdm
34
34
  Provides-Extra: all
35
35
  Requires-Dist: ipympl; extra == 'all'
36
+ Requires-Dist: ipython; extra == 'all'
36
37
  Requires-Dist: ipywidgets; extra == 'all'
37
38
  Requires-Dist: open3d-python; extra == 'all'
39
+ Requires-Dist: pygments; extra == 'all'
38
40
  Requires-Dist: pytesseract; extra == 'all'
39
41
  Requires-Dist: rosbags; extra == 'all'
40
42
  Requires-Dist: roslibpy; extra == 'all'
@@ -44,15 +46,17 @@ Provides-Extra: dev
44
46
  Requires-Dist: coverage; extra == 'dev'
45
47
  Requires-Dist: nbmake; extra == 'dev'
46
48
  Requires-Dist: pytest; extra == 'dev'
49
+ Requires-Dist: pytest-timeout; extra == 'dev'
50
+ Requires-Dist: pytest-xvfb; extra == 'dev'
47
51
  Requires-Dist: ruff; extra == 'dev'
48
52
  Provides-Extra: docs
49
53
  Requires-Dist: pydata-sphinx-theme; extra == 'docs'
50
54
  Requires-Dist: sphinx; extra == 'docs'
51
- Requires-Dist: sphinx-autorun; extra == 'docs'
52
- Requires-Dist: sphinx-codeautolink; extra == 'docs'
55
+ Requires-Dist: sphinx-codeautolink>=0.19.0; extra == 'docs'
53
56
  Requires-Dist: sphinx-copybutton; extra == 'docs'
54
57
  Requires-Dist: sphinx-design; extra == 'docs'
55
58
  Requires-Dist: sphinx-favicon; extra == 'docs'
59
+ Requires-Dist: sphinx-pyrunblock; extra == 'docs'
56
60
  Requires-Dist: sphinxcontrib-programoutput; extra == 'docs'
57
61
  Provides-Extra: jupyter
58
62
  Requires-Dist: ipympl; extra == 'jupyter'
@@ -65,6 +69,9 @@ Provides-Extra: ros
65
69
  Requires-Dist: rosbags; extra == 'ros'
66
70
  Requires-Dist: roslibpy; extra == 'ros'
67
71
  Requires-Dist: websockets; extra == 'ros'
72
+ Provides-Extra: tool
73
+ Requires-Dist: ipython; extra == 'tool'
74
+ Requires-Dist: pygments; extra == 'tool'
68
75
  Provides-Extra: torch
69
76
  Requires-Dist: torch; extra == 'torch'
70
77
  Description-Content-Type: text/markdown
@@ -74,6 +81,7 @@ Description-Content-Type: text/markdown
74
81
  <div align="center">
75
82
  <img src="https://github.com/petercorke/machinevision-toolbox-python/raw/main/docs/figs/VisionToolboxLogo_NoBackgnd@2x.png" width="350">
76
83
  <br>
84
+ <em>OpenCV for humans</em><br>
77
85
  <strong>A high-productivity framework for computer vision research and education.</strong>
78
86
  <br><br>
79
87
 
@@ -1,56 +1,47 @@
1
1
  machinevisiontoolbox/BagOfWords.py,sha256=CYNvYkVhE_aDijV7v3gIxXHkN60QD3MNu9-Xh97q5Y4,19036
2
- machinevisiontoolbox/BundleAdjust.py,sha256=RsrVRlTxlS4ycgs810pnXnP7ZbOf89O8H4MKGB_Ua3o,37064
3
- machinevisiontoolbox/Camera.py,sha256=PPsm0f1jEsnJsblaXQHgEBrIzsN8i63vdPXoh-Sdm_w,139131
4
- machinevisiontoolbox/ImageBlobs.py,sha256=ssyuX1vuaWBZLJyAC0DyxbmpyImh4DUf9QU_3tNOsYI,82702
2
+ machinevisiontoolbox/BundleAdjust.py,sha256=Fjp1eWe78DwZfvu9tuiuMYlCGmv8fqwF2kMFT1_GW4w,37076
3
+ machinevisiontoolbox/Camera.py,sha256=YRG5s6rvlI9vJX2C3X2mawcTBofknjU8MiRc7atJv3o,139142
4
+ machinevisiontoolbox/ImageBlobs.py,sha256=TsXaJpqUN1WrPg0zHRmLQvP3wUBxcHHUBt9qDggjVnE,89447
5
5
  machinevisiontoolbox/ImageColor.py,sha256=fueFYDNlvqSJPgcKsG5v2wBxaW7mYNa6OA-_rK-UJK0,17577
6
6
  machinevisiontoolbox/ImageConstants.py,sha256=R0sc9z8sbraruI6qkixLso6fTgxUAC5cQMSw4ms9m2k,38774
7
- machinevisiontoolbox/ImageCore.docstring,sha256=o--QfvUsp1_tRlD31jvX01rsPZ7qp8fvLogtF9IcmHc,88029
8
- machinevisiontoolbox/ImageCore.py,sha256=Als1G5Cd2Z6e1xIThff1yqyDaX6KcLQY1MUYZpP7UJk,140497
7
+ machinevisiontoolbox/ImageCore.py,sha256=ufDI7ynOGRwM8TSSDEdM4LMQxBhclc0ve976tsprBW8,140594
9
8
  machinevisiontoolbox/ImageFiducials.py,sha256=0CXDgRVY8cA8sIsqd9liPLDRBFRXkolxZwu8rj8TxsM,24124
10
- machinevisiontoolbox/ImageIO.py,sha256=cHdezZyoXzWRRM_1w-1K19cS6TLB9dJ_sd61x57E_PQ,26889
9
+ machinevisiontoolbox/ImageIO.py,sha256=MFUwjxdQ8oGttGMgzon9xOom-IGsVUFkiEWDrVEEgMs,27019
11
10
  machinevisiontoolbox/ImageLineFeatures.py,sha256=5D4MfbNTaRSErdD-HIVlxG9RrtfPAO7WpG4FhESJb4w,10338
12
11
  machinevisiontoolbox/ImageMorph.py,sha256=WioUD2Jr9Ejnk7Let4Vf3iTFz5DhMkZ7l_ZBCbvgl4U,30237
13
12
  machinevisiontoolbox/ImageMultiview.py,sha256=swzNsxX39dijPdPa-a4LFOl7T7liTcQeP7NJf5ODGQU,15605
14
- machinevisiontoolbox/ImagePointFeatures.py,sha256=hc3DrIzvy7cRDW6zmOpdMUb8Ut-mWJoPH4oBOvFsxSg,77109
15
- machinevisiontoolbox/ImageProcessing.py,sha256=70yql1K_wYOSymIINaYgAhd9QBt5y_NIomq2mb6S3Bg,51659
16
- machinevisiontoolbox/ImageRegionFeatures.py,sha256=-UOYYv0p2EkNcsF8BK4ZYnh41gUlTSdR-I2v-sH4wT4,14908
13
+ machinevisiontoolbox/ImagePointFeatures.py,sha256=ZvgXAnyOM-0Lx6yGCYlkfBkRTN-RycNbpu9JzLLritI,77224
14
+ machinevisiontoolbox/ImageProcessing.py,sha256=HBR6cbTlgfAdOiqXU8DPSFKZQXWTBIVufCyRaifky7g,51669
15
+ machinevisiontoolbox/ImageRegionFeatures.py,sha256=qh0NcTLmSVsLe_sKfnY2Jt3d2w1k1Cno-P8K5H9cLV4,15073
17
16
  machinevisiontoolbox/ImageReshape.py,sha256=F8eNrJ1to6d5jrIJeT1D2RqX-7EnARrQ03UGUCvljXg,50204
18
17
  machinevisiontoolbox/ImageSpatial.py,sha256=nzgScDprv7UQXhKcOps80gKjx4Ve6y498lCRm21sEtw,55622
19
18
  machinevisiontoolbox/ImageTensor.py,sha256=ohNbThdsQid2AQbDIHaCoxj00tpRggFWv0TTpIHAJQk,9006
20
- machinevisiontoolbox/ImageWholeFeatures.py,sha256=Fsv92YImQM4mmxtHC-0zdS4w8FjQ0L4ERuhXH96z6D4,61161
19
+ machinevisiontoolbox/ImageWholeFeatures.py,sha256=wpD03wsGu314Ff-nkDqrbCVGgPGobuQItnCZ04Xkwfo,62901
21
20
  machinevisiontoolbox/Kernel.py,sha256=VWobkVDlgMvQDo1eoC0fSLxAn2SGu2pQG13QaUIrRNE,21501
22
21
  machinevisiontoolbox/PointCloud.py,sha256=FJP-gFmd16ePFfBQ2Y-Tdu6SSw_HyEhtDjNeLyknJFY,25239
23
- machinevisiontoolbox/Sources.py,sha256=Ryc93AHfzAACREQU3XmhOJnpnTqNMF6ImITSz6ecLXE,152187
22
+ machinevisiontoolbox/Sources.py,sha256=ZWH4o4ffT-qaJuRJOYT7YFLQV4WmzwzuH5J7ZWwzHvQ,152710
24
23
  machinevisiontoolbox/VisualServo.py,sha256=2q_szKZo51McduLUMnN8-O6foLyLAR-o0h10-UDWKPY,60947
25
- machinevisiontoolbox/__init__.py,sha256=V-oUeFjcanyZxbLF5F-HbEOjnd2kJyyrtgDIR9lPgiw,3831
24
+ machinevisiontoolbox/__init__.py,sha256=ocn82vw6o7pvUKSfebBwPKyKTiK-jMR8FK3SEtpDFVM,3871
26
25
  machinevisiontoolbox/_image_typing.py,sha256=FjdzZpuxEH9nBrj8gb-tkwUZDjpCNH92sQS3meemCVE,7286
27
- machinevisiontoolbox/aruco0.pdf,sha256=a_JZT-TfVv7tQNOvlHSZPf9QCNiOScm_q30jMF8T2ME,75233
28
- machinevisiontoolbox/aruco50.pdf,sha256=wUwqNaDmZ5EFNl1GNF_O3YRztWOZBhTq7DdMdMTskQw,77285
29
26
  machinevisiontoolbox/camera_derivatives.py,sha256=ysaP8PvgeBpFf8e37AmYQTW28SiFBK4fCl9LGONgVQg,39513
30
- machinevisiontoolbox/cvfuncs.py,sha256=Pf4sxB0VvxHT2UqfpY2G9cs75aaqHp0UQZEzSJs94FI,1307
31
27
  machinevisiontoolbox/decorators.py,sha256=6wEoLFozK2RFcGb9QrLy2bAw4sjkbm_2q3PpnIS9Rtk,2623
32
- machinevisiontoolbox/docbugs.py,sha256=HEJvRPOlXgyY5_UyxQXHCVVmJ7UO7SgMV0tpoUSFQbE,1344
33
28
  machinevisiontoolbox/fiducial.py,sha256=syC7iIz95nYBTr_njo4ZzLXOyAdAIqoAZq_wRVhyUHQ,1374
34
29
  machinevisiontoolbox/mvtb_types.py,sha256=YD2P9mDXhz75GgC7Cyeer8luBpSHckkrLZ0GDVvGOnE,728
35
- machinevisiontoolbox/newcameras.py,sha256=WQ3w8NawL7vcRexJwjRkBouHQpvdisXf1LgCL3zD3cM,1243
36
- machinevisiontoolbox/test_skimage.py,sha256=2nIdV5MK3gnz-BA33d2H0vAt-aK3wwb-C35jAYaz5Z8,320
37
- machinevisiontoolbox/testblobplots.py,sha256=DwX2hc5PEeG7l9oUhC8or8mUdeDENX6mYlDUN3e1HRw,465
38
- machinevisiontoolbox/x.json,sha256=bEpuzzQtJYf96nvjZkjxthWVzm0PKI5ZU6uiNuxWnMs,4643
39
30
  machinevisiontoolbox/base/__init__.py,sha256=DxtRJJF6vnY2S1n33xJmXTBf504RCkctmoyKwBW4pc4,1645
40
31
  machinevisiontoolbox/base/color.py,sha256=F1eBcjyQPFV1uiTkeOe6UtBf_2V4s5wkQH-0egh7Ru0,58432
41
32
  machinevisiontoolbox/base/data.py,sha256=PF1HyrYQ-EDR-0heHMG1oDxs63AtQshNWbUvN8GOKsY,6130
42
33
  machinevisiontoolbox/base/findpeaks.py,sha256=Ag0UIw2CPVioB356Pvj-_k_wjxMODGpsW7qdkt6UvEs,11251
43
34
  machinevisiontoolbox/base/graphics.py,sha256=R8hbf_jK3mvq_dEoATxkjcbxUJvoSMovNbrk3W4BQe8,36974
44
- machinevisiontoolbox/base/imageio.py,sha256=d6ytMGVPfC1D4Dpj-K4pVEdd_afs4vmjQ0j2_y0_kbg,51986
35
+ machinevisiontoolbox/base/imageio.py,sha256=QwiYa0XS2E1ZyOIPqGU72RFaPZQZAzKO47w_FBouKV8,54053
45
36
  machinevisiontoolbox/base/meshgrid.py,sha256=Bo2GIlk0tRT2CV5sP5I9i-mZy-6c3BPozLOuOiEVHT0,3162
46
37
  machinevisiontoolbox/base/shapes.py,sha256=d-DmB_9iEsHyC6AT6lv2LMHvb-PMqHTXtehqMKk3aRQ,11430
47
38
  machinevisiontoolbox/base/types.py,sha256=AEiyEsmX5ljifC_PldaOcJnZRDyUSF3kwRbAihNDslQ,5055
48
39
  machinevisiontoolbox/base/version.py,sha256=uSKKfk9fOu5XF_21Kzfh3N111U-39mobNwiRyelOqcU,976
49
40
  machinevisiontoolbox/bin/_bintools.py,sha256=WwzyOqXEv4T-TB2GMBym4pGU2NACM5ACDCg7exGRl0I,1918
50
- machinevisiontoolbox/bin/bagtool.py,sha256=jY7_kQpy904JiYcVGxuvV2ves-jCeqHTDOVOB51rp6w,9039
51
- machinevisiontoolbox/bin/imtool.py,sha256=BAteBohTcM7C_kpHQ73Bpx41vPhrKphMonFvY_iXi4k,6870
52
- machinevisiontoolbox/bin/labeltool.py,sha256=npt-SzyJfUpQObmj6u7hHRymV9CZwDkHdQubQyFkMTk,4267
53
- machinevisiontoolbox/bin/mvtbtool.py,sha256=tPfEPLOZ451fOifGvFyRE2RAkjm-4-0wYvWIgWoBs9o,11089
41
+ machinevisiontoolbox/bin/_iminteractive.py,sha256=9fh2QcuO9RFfO9uGA05MePbe6cUtlh-F19z2zbG4pLA,17063
42
+ machinevisiontoolbox/bin/bagtool.py,sha256=b-Ap2AynpXe0FtcydyfkXIgHDaumAkGBJgDZ6lgdZBU,12359
43
+ machinevisiontoolbox/bin/imtool.py,sha256=la9m9LuMnthJzXxjMRWqGY_l7rJUZS5wiVgZsw84SO4,7897
44
+ machinevisiontoolbox/bin/mvtbtool.py,sha256=P2-wnZXQMf7cWE3SVvmvc4wDn5ApJbMOfl0DyNLHNkU,11348
54
45
  machinevisiontoolbox/bin/ocrtool.py,sha256=HtkbLnjij40oy83nBtZlbJSFJ2pn7lcQAmOifvCLw0I,4719
55
46
  machinevisiontoolbox/bin/tagtool.py,sha256=io-NCIMdMc5zIFYMa6U2ITTv2T-Q8Y0bwh_pB1qZ4IQ,8523
56
47
  machinevisiontoolbox/blocks/__init__.py,sha256=EsdfK2WxYLSo0SA5HSmlgsivLT1kDnoH9v-RTBDnWwc,142
@@ -58,11 +49,10 @@ machinevisiontoolbox/blocks/camera.py,sha256=v0kLMa97bTcLkNtq8c-oGFH7DWqRbp8HTtA
58
49
  machinevisiontoolbox/blocks/test_blocks.py,sha256=dsJiK3BwvNRvzK95bUbPhgbZdoWZhVWQD-yHD-YZRMw,1767
59
50
  machinevisiontoolbox/blocks/Icons/camera.png,sha256=CGcTB_llMoucN-rfnP6ZP_7AfE_92z6JnCdam-hDLgs,1642
60
51
  machinevisiontoolbox/blocks/Icons/estpose_p.png,sha256=1XrwL4OkotGWMwKmhnar3tt8cQWUdZiO7PxXD354T-E,4320
61
- machinevisiontoolbox/blocks/Icons/icons.sh,sha256=teezrmF3es8c3-MvwG1lDCt9SKWEqA0eVHOKFeBugig,115
62
52
  machinevisiontoolbox/blocks/Icons/imageplane.png,sha256=34FYQMzkq6foxvRU8pn0KkcHxpHRvsJRJSYKfNu13Eg,3902
63
53
  machinevisiontoolbox/blocks/Icons/visjac_p.png,sha256=8X023l-C9Y5DfAN8wCdWYjSjq6wp1vRzuZ85sUbwxv8,3819
64
- machinevision_toolbox_python-2.0.0.dist-info/METADATA,sha256=m__KxfUlHHR_yxdRskzXCt3AkGTGKP3T6pr9vAIYKLU,21125
65
- machinevision_toolbox_python-2.0.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
66
- machinevision_toolbox_python-2.0.0.dist-info/entry_points.txt,sha256=R0sRa7JufKCG1VPkgo5KcL7j7pW4-E0Ch2Og4AqmXg4,310
67
- machinevision_toolbox_python-2.0.0.dist-info/licenses/LICENSE,sha256=niCzY_CzbIMKuUZlUkGimjrKp0vkLAtcwFmoSuSKrdw,1068
68
- machinevision_toolbox_python-2.0.0.dist-info/RECORD,,
54
+ machinevision_toolbox_python-2.1.0.dist-info/METADATA,sha256=Prpajt2dDvAN5u3yxRUm0-RYQGGyD-06t8avYEiOpj8,21453
55
+ machinevision_toolbox_python-2.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
56
+ machinevision_toolbox_python-2.1.0.dist-info/entry_points.txt,sha256=R0sRa7JufKCG1VPkgo5KcL7j7pW4-E0Ch2Og4AqmXg4,310
57
+ machinevision_toolbox_python-2.1.0.dist-info/licenses/LICENSE,sha256=niCzY_CzbIMKuUZlUkGimjrKp0vkLAtcwFmoSuSKrdw,1068
58
+ machinevision_toolbox_python-2.1.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.29.0
2
+ Generator: hatchling 1.31.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -12,7 +12,7 @@ try:
12
12
  import pgraph
13
13
 
14
14
  pgraph_installed = True
15
- except:
15
+ except ImportError:
16
16
  print("pgraph not installed")
17
17
  pgraph_installed = False
18
18
  import matplotlib.pyplot as plt
@@ -827,7 +827,7 @@ class CameraBase(ABC):
827
827
  for artist in self._ax.get_children():
828
828
  try:
829
829
  artist.remove()
830
- except:
830
+ except Exception:
831
831
  pass
832
832
 
833
833
  def plot_point(
@@ -1216,86 +1216,10 @@ class CameraBase(ABC):
1216
1216
  try:
1217
1217
  # draw camera-like object:
1218
1218
  if shape == "frustum":
1219
- # TODO make this kwargs or optional inputs
1220
- # side colors:
1221
- # +x red
1222
- # -y red
1223
- # +y green
1224
- # -y yellow
1225
- length = scale
1226
- widthb = scale / 10
1227
- widtht = scale
1228
- widthb /= 2
1229
- widtht /= 2
1230
- b0 = np.array([-widthb, -widthb, 0, 1])
1231
- b1 = np.array([-widthb, widthb, 0, 1])
1232
- b2 = np.array([widthb, widthb, 0, 1])
1233
- b3 = np.array([widthb, -widthb, 0, 1])
1234
- t0 = np.array([-widtht, -widtht, length, 1])
1235
- t1 = np.array([-widtht, widtht, length, 1])
1236
- t2 = np.array([widtht, widtht, length, 1])
1237
- t3 = np.array([widtht, -widtht, length, 1])
1238
-
1239
- # bottom/narrow end
1240
- T = pose.A
1241
- b0 = (T @ b0)[:-1]
1242
- b1 = (T @ b1)[:-1]
1243
- b2 = (T @ b2)[:-1]
1244
- b3 = (T @ b3)[:-1]
1245
-
1246
- # wide/top end
1247
- t0 = (T @ t0)[:-1]
1248
- t1 = (T @ t1)[:-1]
1249
- t2 = (T @ t2)[:-1]
1250
- t3 = (T @ t3)[:-1]
1251
-
1252
- points = [
1253
- np.array([b0, b1, t1, t0]), # -x face
1254
- np.array([b1, b2, t2, t1]), # +y face
1255
- np.array([b2, b3, t3, t2]), # +x face
1256
- np.array([b3, b0, t0, t3]), # -y face
1257
- ]
1258
- poly = Poly3DCollection(
1259
- points, facecolors=["r", "g", "r", "y"], alpha=alpha
1260
- )
1261
- ax.add_collection3d(poly)
1219
+ self._plot_frustum(ax, pose, scale, alpha)
1262
1220
 
1263
1221
  elif shape == "camera":
1264
- # the box is centred at the origin and its centerline parallel to the
1265
- # z-axis. Its z-extent is -bh/2 to bh/2.
1266
- W = 0.5 # width & height of the box
1267
- L = 1.2 # length of the box
1268
- cr = 0.2 # cylinder radius
1269
- ch = 0.4 # cylinder height
1270
- cn = 12 # number of facets of cylinder
1271
- a = 3 # length of axis line segments
1272
-
1273
- # draw the box part of the camera
1274
- smb.plot_cuboid(
1275
- sides=np.r_[W, W, L] * scale,
1276
- pose=pose,
1277
- filled=solid,
1278
- color=color,
1279
- alpha=0.5 * alpha if solid else alpha,
1280
- ax=ax,
1281
- )
1282
-
1283
- # draw the lens
1284
- smb.plot_cylinder(
1285
- radius=cr * scale,
1286
- height=np.r_[L / 2, L / 2 + ch] * scale,
1287
- resolution=cn,
1288
- pose=pose,
1289
- filled=solid,
1290
- color=color,
1291
- alpha=0.5 * alpha,
1292
- ax=ax,
1293
- )
1294
-
1295
- if label:
1296
- ax.set_xlabel("X")
1297
- ax.set_ylabel("Y")
1298
- ax.set_zlabel("Z")
1222
+ self._plot_camera_icon(ax, pose, scale, solid, color, alpha, label)
1299
1223
 
1300
1224
  if frame is True:
1301
1225
  self.pose.plot(
@@ -1311,6 +1235,97 @@ class CameraBase(ABC):
1311
1235
 
1312
1236
  return ax
1313
1237
 
1238
+ def _plot_frustum(self, ax: Axes, pose: SE3, scale: float, alpha: float) -> None:
1239
+ """Draw the ``shape="frustum"`` camera icon into ``ax``."""
1240
+ # TODO make this kwargs or optional inputs
1241
+ # side colors:
1242
+ # +x red
1243
+ # -y red
1244
+ # +y green
1245
+ # -y yellow
1246
+ length = scale
1247
+ widthb = scale / 10
1248
+ widtht = scale
1249
+ widthb /= 2
1250
+ widtht /= 2
1251
+ b0 = np.array([-widthb, -widthb, 0, 1])
1252
+ b1 = np.array([-widthb, widthb, 0, 1])
1253
+ b2 = np.array([widthb, widthb, 0, 1])
1254
+ b3 = np.array([widthb, -widthb, 0, 1])
1255
+ t0 = np.array([-widtht, -widtht, length, 1])
1256
+ t1 = np.array([-widtht, widtht, length, 1])
1257
+ t2 = np.array([widtht, widtht, length, 1])
1258
+ t3 = np.array([widtht, -widtht, length, 1])
1259
+
1260
+ # bottom/narrow end
1261
+ T = pose.A
1262
+ b0 = (T @ b0)[:-1]
1263
+ b1 = (T @ b1)[:-1]
1264
+ b2 = (T @ b2)[:-1]
1265
+ b3 = (T @ b3)[:-1]
1266
+
1267
+ # wide/top end
1268
+ t0 = (T @ t0)[:-1]
1269
+ t1 = (T @ t1)[:-1]
1270
+ t2 = (T @ t2)[:-1]
1271
+ t3 = (T @ t3)[:-1]
1272
+
1273
+ points = [
1274
+ np.array([b0, b1, t1, t0]), # -x face
1275
+ np.array([b1, b2, t2, t1]), # +y face
1276
+ np.array([b2, b3, t3, t2]), # +x face
1277
+ np.array([b3, b0, t0, t3]), # -y face
1278
+ ]
1279
+ poly = Poly3DCollection(points, facecolors=["r", "g", "r", "y"], alpha=alpha)
1280
+ ax.add_collection3d(poly)
1281
+
1282
+ def _plot_camera_icon(
1283
+ self,
1284
+ ax: Axes,
1285
+ pose: SE3,
1286
+ scale: float,
1287
+ solid: bool,
1288
+ color: str,
1289
+ alpha: float,
1290
+ label: bool,
1291
+ ) -> None:
1292
+ """Draw the ``shape="camera"`` box+cylinder icon into ``ax``."""
1293
+ # the box is centred at the origin and its centerline parallel to the
1294
+ # z-axis. Its z-extent is -bh/2 to bh/2.
1295
+ W = 0.5 # width & height of the box
1296
+ L = 1.2 # length of the box
1297
+ cr = 0.2 # cylinder radius
1298
+ ch = 0.4 # cylinder height
1299
+ cn = 12 # number of facets of cylinder
1300
+ a = 3 # length of axis line segments
1301
+
1302
+ # draw the box part of the camera
1303
+ smb.plot_cuboid(
1304
+ sides=np.r_[W, W, L] * scale,
1305
+ pose=pose,
1306
+ filled=solid,
1307
+ color=color,
1308
+ alpha=0.5 * alpha if solid else alpha,
1309
+ ax=ax,
1310
+ )
1311
+
1312
+ # draw the lens
1313
+ smb.plot_cylinder(
1314
+ radius=cr * scale,
1315
+ height=np.r_[L / 2, L / 2 + ch] * scale,
1316
+ resolution=cn,
1317
+ pose=pose,
1318
+ filled=solid,
1319
+ color=color,
1320
+ alpha=0.5 * alpha,
1321
+ ax=ax,
1322
+ )
1323
+
1324
+ if label:
1325
+ ax.set_xlabel("X")
1326
+ ax.set_ylabel("Y")
1327
+ ax.set_zlabel("Z")
1328
+
1314
1329
  def _add_noise_distortion(self, uv: np.ndarray) -> np.ndarray:
1315
1330
  """
1316
1331
  Add noise to pixel coordinates
@@ -1862,7 +1877,7 @@ class CentralCamera(CameraBase):
1862
1877
  """
1863
1878
  try:
1864
1879
  return 2 * np.arctan(np.r_[self.imagesize] / 2 * np.r_[self.rho] / self.f)
1865
- except:
1880
+ except (TypeError, AttributeError):
1866
1881
  raise ValueError("imagesize or rho properties not set")
1867
1882
 
1868
1883
  def distort(self, points: np.ndarray) -> np.ndarray: