machinevision-toolbox-python 2.0.1__py3-none-any.whl → 2.2.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.
- {machinevision_toolbox_python-2.0.1.dist-info → machinevision_toolbox_python-2.2.0.dist-info}/METADATA +13 -5
- {machinevision_toolbox_python-2.0.1.dist-info → machinevision_toolbox_python-2.2.0.dist-info}/RECORD +23 -33
- {machinevision_toolbox_python-2.0.1.dist-info → machinevision_toolbox_python-2.2.0.dist-info}/WHEEL +1 -1
- machinevisiontoolbox/BundleAdjust.py +1 -1
- machinevisiontoolbox/Camera.py +95 -80
- machinevisiontoolbox/ImageBlobs.py +10 -4
- machinevisiontoolbox/ImageCore.py +105 -97
- machinevisiontoolbox/ImageFiducials.py +62 -10
- machinevisiontoolbox/ImageIO.py +5 -1
- machinevisiontoolbox/ImageLineFeatures.py +9 -1
- machinevisiontoolbox/ImagePointFeatures.py +29 -8
- machinevisiontoolbox/ImageProcessing.py +1 -1
- machinevisiontoolbox/ImageRegionFeatures.py +25 -6
- machinevisiontoolbox/ImageWholeFeatures.py +113 -72
- machinevisiontoolbox/Sources.py +1 -1
- machinevisiontoolbox/__init__.py +1 -1
- machinevisiontoolbox/base/imageio.py +68 -33
- machinevisiontoolbox/bin/_iminteractive.py +461 -0
- machinevisiontoolbox/bin/bagtool.py +120 -6
- machinevisiontoolbox/bin/imtool.py +34 -5
- machinevisiontoolbox/bin/mvtbtool.py +93 -18
- machinevisiontoolbox/ImageCore.docstring +0 -2877
- machinevisiontoolbox/aruco0.pdf +0 -0
- machinevisiontoolbox/aruco50.pdf +0 -0
- machinevisiontoolbox/bin/labeltool.py +0 -147
- machinevisiontoolbox/blocks/Icons/icons.sh +0 -4
- machinevisiontoolbox/cvfuncs.py +0 -40
- machinevisiontoolbox/docbugs.py +0 -47
- machinevisiontoolbox/newcameras.py +0 -55
- machinevisiontoolbox/test_skimage.py +0 -12
- machinevisiontoolbox/testblobplots.py +0 -17
- machinevisiontoolbox/x.json +0 -296
- {machinevision_toolbox_python-2.0.1.dist-info → machinevision_toolbox_python-2.2.0.dist-info}/entry_points.txt +0 -0
- {machinevision_toolbox_python-2.0.1.dist-info → machinevision_toolbox_python-2.2.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
|
|
3
|
+
Version: 2.2.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-
|
|
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
|
|
{machinevision_toolbox_python-2.0.1.dist-info → machinevision_toolbox_python-2.2.0.dist-info}/RECORD
RENAMED
|
@@ -1,56 +1,47 @@
|
|
|
1
1
|
machinevisiontoolbox/BagOfWords.py,sha256=CYNvYkVhE_aDijV7v3gIxXHkN60QD3MNu9-Xh97q5Y4,19036
|
|
2
|
-
machinevisiontoolbox/BundleAdjust.py,sha256=
|
|
3
|
-
machinevisiontoolbox/Camera.py,sha256=
|
|
4
|
-
machinevisiontoolbox/ImageBlobs.py,sha256=
|
|
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.
|
|
8
|
-
machinevisiontoolbox/
|
|
9
|
-
machinevisiontoolbox/
|
|
10
|
-
machinevisiontoolbox/
|
|
11
|
-
machinevisiontoolbox/ImageLineFeatures.py,sha256=5D4MfbNTaRSErdD-HIVlxG9RrtfPAO7WpG4FhESJb4w,10338
|
|
7
|
+
machinevisiontoolbox/ImageCore.py,sha256=ufDI7ynOGRwM8TSSDEdM4LMQxBhclc0ve976tsprBW8,140594
|
|
8
|
+
machinevisiontoolbox/ImageFiducials.py,sha256=wrCevhrkgdHzBMMRoDqADZE9OOD7L6nQCd3UDA_e3rU,26903
|
|
9
|
+
machinevisiontoolbox/ImageIO.py,sha256=MFUwjxdQ8oGttGMgzon9xOom-IGsVUFkiEWDrVEEgMs,27019
|
|
10
|
+
machinevisiontoolbox/ImageLineFeatures.py,sha256=Kq0rCzPER2eB9MhEBNn6hAHpGY-G_WPZd657RmuRryA,10855
|
|
12
11
|
machinevisiontoolbox/ImageMorph.py,sha256=WioUD2Jr9Ejnk7Let4Vf3iTFz5DhMkZ7l_ZBCbvgl4U,30237
|
|
13
12
|
machinevisiontoolbox/ImageMultiview.py,sha256=swzNsxX39dijPdPa-a4LFOl7T7liTcQeP7NJf5ODGQU,15605
|
|
14
|
-
machinevisiontoolbox/ImagePointFeatures.py,sha256=
|
|
15
|
-
machinevisiontoolbox/ImageProcessing.py,sha256=
|
|
16
|
-
machinevisiontoolbox/ImageRegionFeatures.py,sha256
|
|
13
|
+
machinevisiontoolbox/ImagePointFeatures.py,sha256=HYgBUs931OOYsM9kx4p_zFU5vAc9dOJsNPuUyTKxoY4,78209
|
|
14
|
+
machinevisiontoolbox/ImageProcessing.py,sha256=HBR6cbTlgfAdOiqXU8DPSFKZQXWTBIVufCyRaifky7g,51669
|
|
15
|
+
machinevisiontoolbox/ImageRegionFeatures.py,sha256=nZAdKFSpxmMZKwlbF13MOxBIUwXvPvDtIxNJUyp7pvg,16092
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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/
|
|
51
|
-
machinevisiontoolbox/bin/
|
|
52
|
-
machinevisiontoolbox/bin/
|
|
53
|
-
machinevisiontoolbox/bin/mvtbtool.py,sha256=
|
|
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=NuVm2lLCJSUT4_RvlSplqeuUb0duDxAoupL1UIrjjuQ,13785
|
|
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.
|
|
65
|
-
machinevision_toolbox_python-2.0.
|
|
66
|
-
machinevision_toolbox_python-2.0.
|
|
67
|
-
machinevision_toolbox_python-2.0.
|
|
68
|
-
machinevision_toolbox_python-2.0.
|
|
54
|
+
machinevision_toolbox_python-2.2.0.dist-info/METADATA,sha256=djNu7vAO1sHkOR2lI9mGurJqY7889oMByoOCDl8M-no,21453
|
|
55
|
+
machinevision_toolbox_python-2.2.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
56
|
+
machinevision_toolbox_python-2.2.0.dist-info/entry_points.txt,sha256=R0sRa7JufKCG1VPkgo5KcL7j7pW4-E0Ch2Og4AqmXg4,310
|
|
57
|
+
machinevision_toolbox_python-2.2.0.dist-info/licenses/LICENSE,sha256=niCzY_CzbIMKuUZlUkGimjrKp0vkLAtcwFmoSuSKrdw,1068
|
|
58
|
+
machinevision_toolbox_python-2.2.0.dist-info/RECORD,,
|
machinevisiontoolbox/Camera.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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:
|
|
@@ -11,7 +11,7 @@ import tempfile
|
|
|
11
11
|
import webbrowser
|
|
12
12
|
from collections import UserList, namedtuple
|
|
13
13
|
from dataclasses import dataclass
|
|
14
|
-
from typing import Any, cast
|
|
14
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
15
15
|
|
|
16
16
|
import cv2
|
|
17
17
|
import matplotlib.pyplot as plt
|
|
@@ -24,6 +24,9 @@ import spatialmath.base as smb
|
|
|
24
24
|
from machinevisiontoolbox.base import plot_labelbox, mpl_styling
|
|
25
25
|
from machinevisiontoolbox.decorators import array_result, scalar_result
|
|
26
26
|
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from machinevisiontoolbox._image_typing import _ImageBase
|
|
29
|
+
|
|
27
30
|
"""
|
|
28
31
|
NOTES
|
|
29
32
|
|
|
@@ -458,7 +461,10 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
458
461
|
|
|
459
462
|
## Equivalent ellipse
|
|
460
463
|
J = np.array([[M["mu20"], M["mu11"]], [M["mu11"], M["mu02"]]])
|
|
461
|
-
|
|
464
|
+
# J is real-symmetric, so use eigh (not eig): eig can return
|
|
465
|
+
# complex128 for a symmetric matrix due to floating-point
|
|
466
|
+
# noise even though the eigenvalues are mathematically real.
|
|
467
|
+
e, X = np.linalg.eigh(J)
|
|
462
468
|
blob_params["a"] = 2.0 * np.sqrt(e.max() / M["m00"])
|
|
463
469
|
blob_params["b"] = 2.0 * np.sqrt(e.min() / M["m00"])
|
|
464
470
|
|
|
@@ -631,7 +637,7 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
631
637
|
return self[:]
|
|
632
638
|
m: np.ndarray = np.array(mask).all(axis=0) # type: ignore[assignment]
|
|
633
639
|
|
|
634
|
-
return self[m]
|
|
640
|
+
return self[m.flatten()]
|
|
635
641
|
|
|
636
642
|
def sort(self, by: str = "area", reverse: bool = False) -> "Blobs": # type: ignore[override]
|
|
637
643
|
"""
|
|
@@ -2620,7 +2626,7 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
2620
2626
|
dot_stream.close()
|
|
2621
2627
|
|
|
2622
2628
|
|
|
2623
|
-
class ImageBlobsMixin:
|
|
2629
|
+
class ImageBlobsMixin(_ImageBase if TYPE_CHECKING else object):
|
|
2624
2630
|
def blobs(self, **kwargs) -> Blobs:
|
|
2625
2631
|
"""
|
|
2626
2632
|
Find and describe blobs in image
|