machinevision-toolbox-python 2.0.1__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- machinevision_toolbox_python-2.2.0/.release-please-manifest.json +3 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/CHANGELOG.md +69 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/Makefile +0 -12
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/PKG-INFO +13 -5
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/README.md +1 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/pyproject.toml +11 -6
- machinevision_toolbox_python-2.2.0/release-please-config.json +64 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/BundleAdjust.py +1 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/Camera.py +95 -80
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageBlobs.py +10 -4
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageCore.py +105 -97
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageFiducials.py +62 -10
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageIO.py +5 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageLineFeatures.py +9 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImagePointFeatures.py +29 -8
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageProcessing.py +1 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageRegionFeatures.py +25 -6
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageWholeFeatures.py +113 -72
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/Sources.py +1 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/__init__.py +1 -1
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/imageio.py +68 -33
- machinevision_toolbox_python-2.2.0/src/machinevisiontoolbox/bin/_iminteractive.py +461 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/bin/bagtool.py +120 -6
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/bin/imtool.py +34 -5
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/bin/mvtbtool.py +93 -18
- machinevision_toolbox_python-2.0.1/CODEAUTOLINK_FORK_PLAN.md +0 -186
- machinevision_toolbox_python-2.0.1/MIGRATION.md +0 -91
- machinevision_toolbox_python-2.0.1/NOTES +0 -57
- machinevision_toolbox_python-2.0.1/OPENCV_FUNCTIONS-original.md +0 -107
- machinevision_toolbox_python-2.0.1/OPENCV_FUNCTIONS.md +0 -184
- machinevision_toolbox_python-2.0.1/audit_typing.py +0 -108
- machinevision_toolbox_python-2.0.1/bags/RenderOption_2026-03-29-12-09-23.json +0 -41
- machinevision_toolbox_python-2.0.1/deprecation_warnings.csv +0 -22
- machinevision_toolbox_python-2.0.1/examples/bus.jpg +0 -0
- machinevision_toolbox_python-2.0.1/examples/street_scene.jpg +0 -11
- machinevision_toolbox_python-2.0.1/examples/yolo26n.pt +0 -0
- machinevision_toolbox_python-2.0.1/findimages.py +0 -16
- machinevision_toolbox_python-2.0.1/flowers.jpg +0 -0
- machinevision_toolbox_python-2.0.1/fmtparser.py +0 -78
- machinevision_toolbox_python-2.0.1/ilabel.c +0 -15230
- machinevision_toolbox_python-2.0.1/ilabel.py-unopt +0 -271
- machinevision_toolbox_python-2.0.1/inspect_bag.py +0 -9
- machinevision_toolbox_python-2.0.1/machinevision-toolbox-python.pdf +0 -0
- machinevision_toolbox_python-2.0.1/machinevision-toolbox-python.svg +0 -13
- machinevision_toolbox_python-2.0.1/machinevisiontoolbox.pdf +0 -0
- machinevision_toolbox_python-2.0.1/phone.py +0 -17
- machinevision_toolbox_python-2.0.1/plot_call_inventory.md +0 -29
- machinevision_toolbox_python-2.0.1/readbag.py +0 -347
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/ImageCore.docstring +0 -2877
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/aruco0.pdf +0 -0
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/aruco50.pdf +0 -0
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/bin/labeltool.py +0 -147
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/blocks/Icons/icons.sh +0 -4
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/cvfuncs.py +0 -40
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/docbugs.py +0 -47
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/newcameras.py +0 -55
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/test_skimage.py +0 -12
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/testblobplots.py +0 -17
- machinevision_toolbox_python-2.0.1/src/machinevisiontoolbox/x.json +0 -296
- machinevision_toolbox_python-2.0.1/ss +0 -1
- machinevision_toolbox_python-2.0.1/sunday.py +0 -71
- machinevision_toolbox_python-2.0.1/x.json +0 -254
- machinevision_toolbox_python-2.0.1/xx.mp4 +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/.gitignore +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/LICENSE +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/README.md +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/blobs1.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/blobs2.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/bunny.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/color.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/corners.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/matching.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/monalisa.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/morphdemo.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/randomdots.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/ransac_line.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/ros_stream.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/showzip.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/torch-yolo.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/examples/torch_seg.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/BagOfWords.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageColor.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageConstants.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageMorph.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageMultiview.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageReshape.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageSpatial.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/ImageTensor.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/Kernel.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/PointCloud.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/VisualServo.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/_image_typing.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/__init__.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/color.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/data.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/findpeaks.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/graphics.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/meshgrid.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/shapes.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/types.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/base/version.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/bin/_bintools.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/bin/ocrtool.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/bin/tagtool.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/Icons/camera.png +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/Icons/estpose_p.png +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/Icons/imageplane.png +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/Icons/visjac_p.png +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/__init__.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/camera.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/blocks/test_blocks.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/camera_derivatives.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/decorators.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/fiducial.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/src/machinevisiontoolbox/mvtb_types.py +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/symbolic/README.md +0 -0
- {machinevision_toolbox_python-2.0.1 → machinevision_toolbox_python-2.2.0}/symbolic/bundle-adjust.py +0 -0
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2.2.0](https://github.com/petercorke/machinevision-toolbox-python/compare/v2.1.0...v2.2.0) (2026-08-10)
|
|
4
|
+
|
|
5
|
+
**Highlight: OpenCV 5 compatibility.** MVTB now works correctly under both OpenCV 4 and the
|
|
6
|
+
newly-released OpenCV 5 — aruco/fiducial pose estimation, HoughLinesP line features,
|
|
7
|
+
BRISK/AKAZE point features, and MSER region features have all been fixed for OpenCV 5's API
|
|
8
|
+
and shape changes, verified against real OpenCV 4.13.0 and 5.0.0 installs. See #44 for the
|
|
9
|
+
full compatibility audit.
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add mvtbtool --test smoke test, fix silent Open3D banner skip ([6a0bf2c](https://github.com/petercorke/machinevision-toolbox-python/commit/6a0bf2c090b8be4aa2d378495545ca71a55e89b1))
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* handle HoughLinesP's (N,4) return shape on OpenCV 5 ([b54f755](https://github.com/petercorke/machinevision-toolbox-python/commit/b54f7552a8c08530173e159d70a84fa5e8f6d486))
|
|
18
|
+
* handle MSER's empty-tuple bboxes on OpenCV 5, resolve MSER discrepancy ([aabaf88](https://github.com/petercorke/machinevision-toolbox-python/commit/aabaf885e660c59c4949a5f5706b276ad7c50202))
|
|
19
|
+
* normalize aruco ids/matchImagePoints shapes for OpenCV 5 ([6ac5ec0](https://github.com/petercorke/machinevision-toolbox-python/commit/6ac5ec0cc795ad7016f491dbb464e91c4ad34aae))
|
|
20
|
+
* replace removed cv2.aruco.estimatePoseSingleMarkers with solvePnP ([635225d](https://github.com/petercorke/machinevision-toolbox-python/commit/635225de657a1484ad526480605d9d234f202ffa))
|
|
21
|
+
* resolve BRISK/AKAZE via cv2.xfeatures2d on OpenCV 5 ([fad7247](https://github.com/petercorke/machinevision-toolbox-python/commit/fad7247cf6cfc07f7e8511ffa37ce4ccc928f451))
|
|
22
|
+
|
|
23
|
+
## [2.1.0](https://github.com/petercorke/machinevision-toolbox-python/compare/v2.0.1...v2.1.0) (2026-08-03)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
* add interactive tools to imtool and bagtool ([b16ab7d](https://github.com/petercorke/machinevision-toolbox-python/commit/b16ab7dbd1f2fe26869a7fcacc710e549735e431))
|
|
29
|
+
* **mvtbtool:** add 'tool' extra for IPython/pygments, fail with clear message when missing ([a31655b](https://github.com/petercorke/machinevision-toolbox-python/commit/a31655be13d07acb14548e79c618d62d5bf5589c))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* add missing type annotations, warn on ncdf deprecation ([7e8cabe](https://github.com/petercorke/machinevision-toolbox-python/commit/7e8cabe4ceee1f517b1a9161ab28e9d87137475e))
|
|
35
|
+
* add socket timeout to iread() URL fetches ([6ff62b1](https://github.com/petercorke/machinevision-toolbox-python/commit/6ff62b17aa1b556a1823e69ae4950f2786e0ebc1))
|
|
36
|
+
* bring 3 mixins in line with the TYPE_CHECKING _ImageBase pattern ([0d31fc5](https://github.com/petercorke/machinevision-toolbox-python/commit/0d31fc52f881df6cfda35c5ab11e4f9753e65aa0))
|
|
37
|
+
* colorplane handling in image i/o ([6882967](https://github.com/petercorke/machinevision-toolbox-python/commit/68829677c0f42d4b6e83b61b981f5027efe61ee3))
|
|
38
|
+
* gridify() IndexError from numpy float // int staying float64 ([e57597a](https://github.com/petercorke/machinevision-toolbox-python/commit/e57597aa527ab1741ff19066070ecd6968056da5))
|
|
39
|
+
* keep single-blob filter() matches ([7b0ab8d](https://github.com/petercorke/machinevision-toolbox-python/commit/7b0ab8d67c67251e12753df198447fdc9255f48a)), closes [#17](https://github.com/petercorke/machinevision-toolbox-python/issues/17)
|
|
40
|
+
* replace 6 bare except: clauses with specific exception types ([5a11306](https://github.com/petercorke/machinevision-toolbox-python/commit/5a11306eb838b2c47535389f482ab872b7a22d24))
|
|
41
|
+
* un-hide bot-comment notes from HTML comment block ([4a4e943](https://github.com/petercorke/machinevision-toolbox-python/commit/4a4e943fab8e00af404713efb1f3501d1c94f1a3))
|
|
42
|
+
* use eigh instead of eig for blob orientation/ellipse moments ([3a74fdf](https://github.com/petercorke/machinevision-toolbox-python/commit/3a74fdf6b558967ae797d19bbb4369275eaf690c))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Documentation
|
|
46
|
+
|
|
47
|
+
* add build date to footer copyright notice ([e7de5bf](https://github.com/petercorke/machinevision-toolbox-python/commit/e7de5bf8e68d6251cbc23465befdd4070d7fbc6c))
|
|
48
|
+
* add example placeholder to Alternatives considered ([879f086](https://github.com/petercorke/machinevision-toolbox-python/commit/879f086dc0bcde61496c6f227d275dd19c47e53a))
|
|
49
|
+
* add PR and issue templates ([d081f7e](https://github.com/petercorke/machinevision-toolbox-python/commit/d081f7e49ae1e1673b00c92e4bd174e3c2629efb))
|
|
50
|
+
* ask for a concrete function signature in feature requests ([b25cd12](https://github.com/petercorke/machinevision-toolbox-python/commit/b25cd12efa6eae61a9ef2a6b05a78dbffca82cda))
|
|
51
|
+
* fix docstring convention note, add Codacy heads-up ([d68f605](https://github.com/petercorke/machinevision-toolbox-python/commit/d68f605301aaa71795c5cab75acadb910ce6d398))
|
|
52
|
+
* fix Image class sidebar, cut over to sphinx-pyrunblock ([20c219d](https://github.com/petercorke/machinevision-toolbox-python/commit/20c219d65fdb68ca14d58777a08f0c29333303dd))
|
|
53
|
+
* fix stale rank() reference in card-algorithms.rst ([1e3f6bd](https://github.com/petercorke/machinevision-toolbox-python/commit/1e3f6bdf3cbaa3307985f616af2c178c3d6a5029))
|
|
54
|
+
* fix stale/broken references and add footer build date ([c51955b](https://github.com/petercorke/machinevision-toolbox-python/commit/c51955bf14b55ed8dd9a19bf6b9c9d6b97952e6d))
|
|
55
|
+
* flesh out PR template with a proper checklist ([f4db44b](https://github.com/petercorke/machinevision-toolbox-python/commit/f4db44b4b21a16514ea0f1de2bceb54d22b6d39c))
|
|
56
|
+
* forewarn contributors about Dependabot vulnerability comments ([acfedab](https://github.com/petercorke/machinevision-toolbox-python/commit/acfedabfc285e11e4a505eb06b81c3bec74c0762))
|
|
57
|
+
* log ci.yml's conda/micromamba setup as tech debt ([af09d07](https://github.com/petercorke/machinevision-toolbox-python/commit/af09d07cae1df3129df4853d3a672db333f42465))
|
|
58
|
+
* log Codacy backlog real numbers to tech-debt ([65b3c5e](https://github.com/petercorke/machinevision-toolbox-python/commit/65b3c5ed3b2a2cbd20ee41a29b9c2b8234db126e))
|
|
59
|
+
* log gridify() IndexError bug found while testing bare-except fix ([889d45c](https://github.com/petercorke/machinevision-toolbox-python/commit/889d45c4957f93ec9910ccb960f91a432d1d06a3))
|
|
60
|
+
* log Histogram.plot type= docstring/behavior mismatch ([e693eef](https://github.com/petercorke/machinevision-toolbox-python/commit/e693eefa033c5d7a7e95c2787ac3f4dbbce0d2c3))
|
|
61
|
+
* log mypy-not-in-CI as high-priority tech debt, with fresh audit ([1b74ae8](https://github.com/petercorke/machinevision-toolbox-python/commit/1b74ae8efc240e43c338dec8415f7198de2a0d3a))
|
|
62
|
+
* log pgraph-python CI gap and conda-migration decision to tech-debt ([c5b6aeb](https://github.com/petercorke/machinevision-toolbox-python/commit/c5b6aebdaa42003bc48d0428d3381599f325d1df))
|
|
63
|
+
* log PR [#32](https://github.com/petercorke/machinevision-toolbox-python/issues/32)/[#33](https://github.com/petercorke/machinevision-toolbox-python/issues/33) Codacy findings (type shadowing, F405, max param) ([e0ed8db](https://github.com/petercorke/machinevision-toolbox-python/commit/e0ed8db736f1032c2a4fdb78c308c16f1b7e300b))
|
|
64
|
+
* migrate tech-debt.md to GitHub Issues (tech-debt label) ([36aae6a](https://github.com/petercorke/machinevision-toolbox-python/commit/36aae6aa9855ac79a4de19fb49fbaf30827b423a))
|
|
65
|
+
* remove reference to nonexistent CentralCamera.decomposeF ([c7f1400](https://github.com/petercorke/machinevision-toolbox-python/commit/c7f1400700f2ff5364d2fafe19367cfa49628e8e))
|
|
66
|
+
* switch sphinx-codeautolink to released 0.19.0, drop branch pin ([594a9a1](https://github.com/petercorke/machinevision-toolbox-python/commit/594a9a13580cf58868d836adee3a5bbaebc42d12))
|
|
67
|
+
* use %pip magic in notebooks, add tagline to README ([843db36](https://github.com/petercorke/machinevision-toolbox-python/commit/843db36441d43ec74e573d9b201f93635213c7ad))
|
|
68
|
+
|
|
1
69
|
2.0.0 May 2026
|
|
2
70
|
|
|
3
71
|
* Added
|
|
@@ -238,4 +306,4 @@ and is `None` if the blob has no parent (its parent is the background).
|
|
|
238
306
|
|
|
239
307
|
* Additional unit tests
|
|
240
308
|
|
|
241
|
-
* Myriad minor bug fixes, see commit history.
|
|
309
|
+
* Myriad minor bug fixes, see commit history.
|
|
@@ -14,7 +14,6 @@ help:
|
|
|
14
14
|
@echo " make docs-strict - nitpicky Sphinx build with warnings treated as errors"
|
|
15
15
|
@echo " make view - open Sphinx doco build (uses open for MacOS)"
|
|
16
16
|
@echo " make dist - preview dist build"
|
|
17
|
-
@echo " make pypi - build the dist, upload to PyPI, tag the release and push the tag to origin"
|
|
18
17
|
@echo " make clean - remove dist and docs build files"
|
|
19
18
|
@echo " make help - this message$(BLACK)"
|
|
20
19
|
|
|
@@ -59,17 +58,6 @@ dist: .FORCE
|
|
|
59
58
|
python -m build
|
|
60
59
|
ls -lh dist/*
|
|
61
60
|
|
|
62
|
-
pypi: .FORCE
|
|
63
|
-
@if ! git diff --quiet || ! git diff --cached --quiet; then \
|
|
64
|
-
echo "Error: uncommitted changes present, aborting upload"; exit 1; \
|
|
65
|
-
fi
|
|
66
|
-
python -m build
|
|
67
|
-
$(eval VERSION := $(shell grep '^version' pyproject.toml | sed 's/version = "\(.*\)"/\1/'))
|
|
68
|
-
@echo "Uploading version $(VERSION) to PyPI"
|
|
69
|
-
twine upload dist/*
|
|
70
|
-
git tag v$(VERSION)
|
|
71
|
-
git push origin v$(VERSION)
|
|
72
|
-
|
|
73
61
|
clean: .FORCE
|
|
74
62
|
(cd docs; make clean)
|
|
75
63
|
-rm -r *.egg-info
|
|
@@ -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
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
<img src="https://github.com/petercorke/machinevision-toolbox-python/raw/main/docs/figs/VisionToolboxLogo_NoBackgnd@2x.png" width="350">
|
|
5
5
|
<br>
|
|
6
|
+
<em>OpenCV for humans</em><br>
|
|
6
7
|
<strong>A high-productivity framework for computer vision research and education.</strong>
|
|
7
8
|
<br><br>
|
|
8
9
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "machinevision-toolbox-python"
|
|
3
|
-
version = "2.0
|
|
3
|
+
version = "2.2.0"
|
|
4
4
|
authors = [{ name = "Peter Corke", email = "rvc@petercorke.com" }]
|
|
5
5
|
description = "Object-oriented machine vision for Python."
|
|
6
6
|
readme = "README.md"
|
|
@@ -39,8 +39,8 @@ dependencies = [
|
|
|
39
39
|
"scipy",
|
|
40
40
|
"matplotlib",
|
|
41
41
|
"pillow",
|
|
42
|
-
"opencv-python",
|
|
43
|
-
"opencv-contrib-python",
|
|
42
|
+
"opencv-python<5.0.0",
|
|
43
|
+
"opencv-contrib-python<5.0.0",
|
|
44
44
|
"spatialmath-python",
|
|
45
45
|
"pgraph-python",
|
|
46
46
|
"ansitable",
|
|
@@ -65,19 +65,22 @@ dependencies = [
|
|
|
65
65
|
# open3d - open3d support (open3d generally won't work with latest Python)
|
|
66
66
|
# all - all runtime optional features below
|
|
67
67
|
# ocr - OCR support via pytesseract
|
|
68
|
+
# tool - dependencies for the mvtbtool interactive shell
|
|
68
69
|
|
|
69
|
-
dev = ["pytest", "coverage", "ruff", "nbmake"]
|
|
70
|
+
dev = ["pytest", "pytest-timeout", "pytest-xvfb", "coverage", "ruff", "nbmake"]
|
|
70
71
|
|
|
71
72
|
ros = ["rosbags", "roslibpy", "websockets"]
|
|
72
73
|
|
|
74
|
+
tool = ["ipython", "pygments"]
|
|
75
|
+
|
|
73
76
|
docs = [
|
|
74
77
|
"sphinx",
|
|
75
78
|
"pydata-sphinx-theme",
|
|
76
|
-
"sphinx-codeautolink",
|
|
79
|
+
"sphinx-codeautolink>=0.19.0",
|
|
77
80
|
"sphinx-favicon",
|
|
78
81
|
"sphinx-copybutton",
|
|
79
82
|
"sphinxcontrib-programoutput",
|
|
80
|
-
"sphinx-
|
|
83
|
+
"sphinx-pyrunblock",
|
|
81
84
|
"sphinx-design",
|
|
82
85
|
]
|
|
83
86
|
|
|
@@ -98,6 +101,8 @@ all = [
|
|
|
98
101
|
"rosbags",
|
|
99
102
|
"roslibpy",
|
|
100
103
|
"websockets",
|
|
104
|
+
"ipython",
|
|
105
|
+
"pygments",
|
|
101
106
|
]
|
|
102
107
|
|
|
103
108
|
[tool.pytest.ini_options]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
3
|
+
"release-type": "python",
|
|
4
|
+
"packages": {
|
|
5
|
+
".": {
|
|
6
|
+
"release-type": "python",
|
|
7
|
+
"package-name": "machinevision-toolbox-python",
|
|
8
|
+
"version-file": "pyproject.toml",
|
|
9
|
+
"changelog-path": "CHANGELOG.md",
|
|
10
|
+
"include-component-in-tag": false
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"pull-request-title-pattern": "chore: release ${version}",
|
|
14
|
+
"changelog-sections": [
|
|
15
|
+
{
|
|
16
|
+
"type": "feat",
|
|
17
|
+
"section": "Features"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "fix",
|
|
21
|
+
"section": "Bug Fixes"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "perf",
|
|
25
|
+
"section": "Performance Improvements"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "deps",
|
|
29
|
+
"section": "Dependencies"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "revert",
|
|
33
|
+
"section": "Reverts"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": "docs",
|
|
37
|
+
"section": "Documentation"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "build",
|
|
41
|
+
"section": "Build System"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "test",
|
|
45
|
+
"section": "Tests",
|
|
46
|
+
"hidden": true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "refactor",
|
|
50
|
+
"section": "Code Refactoring",
|
|
51
|
+
"hidden": true
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "chore",
|
|
55
|
+
"section": "Miscellaneous",
|
|
56
|
+
"hidden": true
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"type": "ci",
|
|
60
|
+
"section": "CI",
|
|
61
|
+
"hidden": true
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
@@ -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
|