machinevision-toolbox-python 1.0.3__tar.gz → 2.0.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-1.0.3 → machinevision_toolbox_python-2.0.0}/.gitignore +22 -0
- machinevision_toolbox_python-2.0.0/CHANGELOG.md +241 -0
- machinevision_toolbox_python-2.0.0/CODEAUTOLINK_FORK_PLAN.md +186 -0
- machinevision_toolbox_python-2.0.0/MIGRATION.md +91 -0
- machinevision_toolbox_python-2.0.0/Makefile +77 -0
- machinevision_toolbox_python-2.0.0/NOTES +57 -0
- machinevision_toolbox_python-2.0.0/OPENCV_FUNCTIONS-original.md +107 -0
- machinevision_toolbox_python-2.0.0/OPENCV_FUNCTIONS.md +184 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/PKG-INFO +103 -73
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/README.md +72 -64
- machinevision_toolbox_python-2.0.0/audit_typing.py +108 -0
- machinevision_toolbox_python-2.0.0/bags/RenderOption_2026-03-29-12-09-23.json +41 -0
- machinevision_toolbox_python-2.0.0/deprecation_warnings.csv +22 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/bunny.py +1 -0
- machinevision_toolbox_python-2.0.0/examples/bus.jpg +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/color.py +1 -2
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/matching.py +3 -5
- machinevision_toolbox_python-2.0.0/examples/morphdemo.py +151 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/randomdots.py +1 -1
- machinevision_toolbox_python-2.0.0/examples/ros_stream.py +24 -0
- machinevision_toolbox_python-2.0.0/examples/showzip.py +11 -0
- machinevision_toolbox_python-2.0.0/examples/street_scene.jpg +11 -0
- machinevision_toolbox_python-2.0.0/examples/torch-yolo.py +37 -0
- machinevision_toolbox_python-2.0.0/examples/torch_seg.py +54 -0
- machinevision_toolbox_python-2.0.0/examples/yolo26n.pt +0 -0
- machinevision_toolbox_python-2.0.0/flowers.jpg +0 -0
- machinevision_toolbox_python-2.0.0/fmtparser.py +78 -0
- machinevision_toolbox_python-2.0.0/inspect_bag.py +9 -0
- machinevision_toolbox_python-2.0.0/machinevision-toolbox-python.pdf +0 -0
- machinevision_toolbox_python-2.0.0/machinevision-toolbox-python.svg +13 -0
- machinevision_toolbox_python-2.0.0/machinevisiontoolbox.pdf +0 -0
- machinevision_toolbox_python-2.0.0/plot_call_inventory.md +29 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/pyproject.toml +61 -17
- machinevision_toolbox_python-2.0.0/readbag.py +347 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/BagOfWords.py +74 -121
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/BundleAdjust.py +95 -77
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/Camera.py +642 -580
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageBlobs.py +674 -481
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageColor.py +105 -81
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageConstants.py +1106 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageCore.docstring +2877 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageCore.py +1644 -460
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageFiducials.py +170 -98
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageIO.py +330 -191
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageLineFeatures.py +71 -37
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageMorph.py +296 -117
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageMultiview.py +129 -82
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImagePointFeatures.py +363 -419
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageProcessing.py +1435 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageRegionFeatures.py +79 -88
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageReshape.py +308 -214
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageSpatial.py +398 -936
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageTensor.py +242 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageWholeFeatures.py +1763 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/Kernel.py +753 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/PointCloud.py +122 -81
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/Sources.py +4227 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/VisualServo.py +140 -99
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/__init__.py +192 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/_image_typing.py +207 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/__init__.py +11 -6
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/color.py +257 -156
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/data.py +25 -24
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/findpeaks.py +35 -10
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/graphics.py +378 -164
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/imageio.py +507 -216
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/meshgrid.py +13 -3
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/shapes.py +121 -62
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/types.py +28 -16
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/version.py +12 -5
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/_bintools.py +61 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/bagtool.py +286 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/imtool.py +234 -0
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/bin/imtool.py → machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/labeltool.py +14 -28
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/mvtbtool.py +372 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/ocrtool.py +155 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/tagtool.py +290 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/camera.py +14 -56
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/test_blocks.py +6 -5
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/camera_derivatives.py +1098 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/cvfuncs.py +40 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/decorators.py +17 -9
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/docbugs.py +47 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/mvtb_types.py +23 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/newcameras.py +4 -2
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/test_skimage.py +12 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/testblobplots.py +17 -0
- machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/x.json +296 -0
- machinevision_toolbox_python-2.0.0/ss +1 -0
- machinevision_toolbox_python-2.0.0/sunday.py +71 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/symbolic/bundle-adjust.py +29 -9
- machinevision_toolbox_python-2.0.0/x.json +254 -0
- machinevision_toolbox_python-2.0.0/xx.mp4 +0 -0
- machinevision_toolbox_python-1.0.3/CHANGELOG.md +0 -103
- machinevision_toolbox_python-1.0.3/Makefile +0 -43
- machinevision_toolbox_python-1.0.3/NOTES +0 -19
- machinevision_toolbox_python-1.0.3/bun.png +0 -0
- machinevision_toolbox_python-1.0.3/camtest.py +0 -76
- machinevision_toolbox_python-1.0.3/dependencies.pdf +0 -0
- machinevision_toolbox_python-1.0.3/examples/morphdemo.py +0 -38
- machinevision_toolbox_python-1.0.3/examples/mwe.py +0 -15
- machinevision_toolbox_python-1.0.3/examples/readme.py +0 -79
- machinevision_toolbox_python-1.0.3/examples/showzip.py +0 -9
- machinevision_toolbox_python-1.0.3/notebooks/IBVS.ipynb +0 -472
- machinevision_toolbox_python-1.0.3/notebooks/ImageMotion.ipynb +0 -694
- machinevision_toolbox_python-1.0.3/notebooks/Untitled.ipynb +0 -497
- machinevision_toolbox_python-1.0.3/notebooks/Untitled1.ipynb +0 -4182
- machinevision_toolbox_python-1.0.3/notebooks/blob.ipynb +0 -378
- machinevision_toolbox_python-1.0.3/notebooks/calibration-fixture.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/calibration.ipynb +0 -2862
- machinevision_toolbox_python-1.0.3/notebooks/camera.ipynb +0 -1494
- machinevision_toolbox_python-1.0.3/notebooks/chap10.ipynb +0 -969
- machinevision_toolbox_python-1.0.3/notebooks/color-images.ipynb +0 -2191
- machinevision_toolbox_python-1.0.3/notebooks/cones.ipynb +0 -1188
- machinevision_toolbox_python-1.0.3/notebooks/fiducuals.ipynb +0 -2344
- machinevision_toolbox_python-1.0.3/notebooks/finding-blobs.ipynb +0 -4307
- machinevision_toolbox_python-1.0.3/notebooks/gamma.ipynb +0 -2054
- machinevision_toolbox_python-1.0.3/notebooks/greyscale-images.ipynb +0 -8116
- machinevision_toolbox_python-1.0.3/notebooks/homogeneous-coords.ipynb +0 -696
- machinevision_toolbox_python-1.0.3/notebooks/homography.ipynb +0 -385
- machinevision_toolbox_python-1.0.3/notebooks/image-features.ipynb +0 -836
- machinevision_toolbox_python-1.0.3/notebooks/image.ipynb +0 -723
- machinevision_toolbox_python-1.0.3/notebooks/imageprocessing.ipynb +0 -591
- machinevision_toolbox_python-1.0.3/notebooks/images/apriltags.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/images/aruco.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/images/butterfly.jpg +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/images/calib-image.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/images/calibration-fixture.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/images/coordinate-frames.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/images/output_9.png +0 -0
- machinevision_toolbox_python-1.0.3/notebooks/point-features.ipynb +0 -11637
- machinevision_toolbox_python-1.0.3/notebooks/sift.ipynb +0 -213
- machinevision_toolbox_python-1.0.3/notebooks/unknown_camera.py +0 -40
- machinevision_toolbox_python-1.0.3/setup.cfg +0 -2
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/ImageConstants.py +0 -645
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/ImageProcessing.py +0 -1053
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/ImageWholeFeatures.py +0 -1101
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/Sources.py +0 -840
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/__init__.py +0 -45
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/base/esttheta.py +0 -97
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/bin/ce.py +0 -27
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/bin/mvtbtool.py +0 -192
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/bin/tagtool.py +0 -250
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/camera_derivatives.py +0 -7
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/machinevision-toolbox-python.code-workspace +0 -7
- machinevision_toolbox_python-1.0.3/src/machinevisiontoolbox/mvtb_types.py +0 -15
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/LICENSE +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/README.md +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/blobs1.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/blobs2.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/corners.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/monalisa.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/examples/ransac_line.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/findimages.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/ilabel.c +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/ilabel.py-unopt +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/phone.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/aruco0.pdf +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/aruco50.pdf +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/camera.png +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/estpose_p.png +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/icons.sh +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/imageplane.png +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/visjac_p.png +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/__init__.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/fiducial.py +0 -0
- {machinevision_toolbox_python-1.0.3 → machinevision_toolbox_python-2.0.0}/symbolic/README.md +0 -0
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
|
|
2
|
+
### MacOS ###
|
|
3
|
+
.DS_Store
|
|
4
|
+
|
|
5
|
+
dependencies*
|
|
6
|
+
*.log
|
|
7
|
+
|
|
8
|
+
# ROS bag files
|
|
9
|
+
*.bag
|
|
10
|
+
# but keep test fixtures
|
|
11
|
+
!mvtb-data/mvtbdata/data/*.bag
|
|
12
|
+
|
|
13
|
+
# old notebooks
|
|
14
|
+
notebooks/old/*
|
|
15
|
+
|
|
2
16
|
### Python ###
|
|
3
17
|
# Byte-compiled / optimized / DLL files
|
|
4
18
|
__pycache__/
|
|
@@ -64,6 +78,11 @@ target/
|
|
|
64
78
|
.ipynb_checkpoints/
|
|
65
79
|
|
|
66
80
|
### Figures generated by Python notebooks ###
|
|
81
|
+
|
|
82
|
+
# old notebooks
|
|
83
|
+
notebooks/old/*
|
|
84
|
+
|
|
85
|
+
*.inc
|
|
67
86
|
*.eps
|
|
68
87
|
|
|
69
88
|
*.zip
|
|
@@ -72,3 +91,6 @@ docs/source/stubs/*
|
|
|
72
91
|
# latex products
|
|
73
92
|
.log
|
|
74
93
|
.aux
|
|
94
|
+
|
|
95
|
+
# LLVM profiling data
|
|
96
|
+
*.profraw
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
2.0.0 May 2026
|
|
2
|
+
|
|
3
|
+
* Added
|
|
4
|
+
- image sources
|
|
5
|
+
- `ROSBag` reads images and point clouds from ROS 1/2 bag files
|
|
6
|
+
- `ROSTopic` reads images and point clouds from live ROS 1/2 systems via `rosbridge`
|
|
7
|
+
- `ImageSequence`: a sequence of image objects
|
|
8
|
+
- `PointCloudSequence`: a sequence of point cloud objects
|
|
9
|
+
- `TensorStack`: reads images from a batch tensor
|
|
10
|
+
- `LabelMeReader`: returns image and shape data from a LabelMe JSON file
|
|
11
|
+
- CLI tools
|
|
12
|
+
- `bagtool`: animate images or point clouds from a ROS 1/2 bag file
|
|
13
|
+
- `ocrtool`: write OCR text to stdout or JSON
|
|
14
|
+
- documentation
|
|
15
|
+
- ecosystem diagram
|
|
16
|
+
- new Sphinx sections for ROS, PyTorch, NumPy integration, and Jupyter
|
|
17
|
+
- code copy button for examples (strips `>>>` prompts)
|
|
18
|
+
- top-level of reST documentation now uses sphinx-design and a card-based TOC
|
|
19
|
+
|
|
20
|
+
* Changed
|
|
21
|
+
- CI and packaging
|
|
22
|
+
- changed `master` branch to `main`
|
|
23
|
+
- reworked and renamed CI files
|
|
24
|
+
- replaced `flake8` with `ruff`
|
|
25
|
+
- added extras: `jupyter`, `pytorch`, `ros`, `ocr`
|
|
26
|
+
- added `all` extra to install all optional extras
|
|
27
|
+
- consolidated documentation and notebooks into `docs`
|
|
28
|
+
- code quality
|
|
29
|
+
- tested with Python 3.13
|
|
30
|
+
- improved behaviour when Open3D is unavailable
|
|
31
|
+
- many more unit tests, with average coverage now > 50%
|
|
32
|
+
- consistent and PEP-conformant `repr()` and `str()` formatting
|
|
33
|
+
- more consistent handling of lazy imports
|
|
34
|
+
- systematic use of `import cv2`
|
|
35
|
+
- consistent naming of test files
|
|
36
|
+
- PEP 8/257-compliant import grouping and module docstrings
|
|
37
|
+
- revisited suppression comment tags for validity and currency
|
|
38
|
+
- normalized deprecation/warning/docstring language with explicit version tagging
|
|
39
|
+
- image I/O and display
|
|
40
|
+
- `iread` now uses `cv2.imdecode` instead of PIL, with internal refactor for corner cases
|
|
41
|
+
- `iread_iter` is an efficient lazy wildcard iterator
|
|
42
|
+
- `idisp` now includes keyboard display and animation controls when `fps` or `animate` is specified
|
|
43
|
+
- fixed `idisp` issues with Jupyter Matplotlib backend selection (for example `%matplotlib widget`)
|
|
44
|
+
- `idisp` can now put text labels on colorbar ticks
|
|
45
|
+
- `Image` class and core API
|
|
46
|
+
- image NumPy array for pixel data
|
|
47
|
+
- deprecate `.A` property, setting `.A` now raises an exception
|
|
48
|
+
- systematic internal use of `._A` for array access
|
|
49
|
+
- `.array` for user use, provide a read-only view of the pixel data
|
|
50
|
+
- uses `_image_typing.py` protocol to resolve `Image` type across mixins
|
|
51
|
+
- improved color order and type logic
|
|
52
|
+
- `Image(..., dtype=True)` forces image dtype to match the ndarray; otherwise the smallest fitting dtype is selected
|
|
53
|
+
- `size` option supports turning pixel row/column data into 2D or 3D images
|
|
54
|
+
- `Image.Tensor()` and `img.tensor()` for PyTorch import/export
|
|
55
|
+
- statistics improvements:
|
|
56
|
+
- `sum`, `min`, `max`, `mean`, `std`, `median` forward arguments to NumPy (for example `axis`)
|
|
57
|
+
- `img.stats` is now a property returning per-plane statistics
|
|
58
|
+
- `img.printstats()` prints formatted per-plane statistics
|
|
59
|
+
- all are computed lazily
|
|
60
|
+
- thresholding improvements:
|
|
61
|
+
- native NumPy implementations for `otsu` and `triangle` threshold estimators
|
|
62
|
+
- `threshold_interactive` reworked for Jupyter support
|
|
63
|
+
- NaN/Inf handling:
|
|
64
|
+
- `img.numnan` and `img.numinf` properties
|
|
65
|
+
- `fixbad()` for remediation
|
|
66
|
+
- reporting in `repr()` and `str()`
|
|
67
|
+
- NumPy ufunc integration (for example `np.ceil(img)` returns an `Image`)
|
|
68
|
+
- `%` operator stacks images plane-wise (for example `img1 % img2`, `img1 % 0`)
|
|
69
|
+
- `Image.Random()`
|
|
70
|
+
- supports multi-channel images
|
|
71
|
+
- now has a `pdf` arugment to create an image with arbitary pixel-value distribution.
|
|
72
|
+
- `img1.sameas(img2)` performs scalar equality checks across datatype/planes/pixels (`img1 == img2` remains element-wise)
|
|
73
|
+
- image histogram properties `h`, `pdf`, `cf`, `cdf` are now computed lazily, and each returns a 2-tuple of ndarays (statistic, x). These property names match those of the `Histogram` class. They were formally called `h`, `cdf`, and `ncdf` and return just a single ndarray.
|
|
74
|
+
- `__str__` now includes image statistics like mean, std, median.
|
|
75
|
+
- all "constant constructors" like `Zeros`, `Constant`, `Random` etc. now have a consistent API with
|
|
76
|
+
keyword arguments `size`, `dtype`, `colororder`, `like`.
|
|
77
|
+
- `Kernel.Gauss` and `smooth` with a half-width but `sigma=0` will use a rule-of-thumb to estimate a good `sigma` value
|
|
78
|
+
- `showpixels` has a major improvement in visual appearance, some parameters now gone. The animation window has been refactored into `showwindow`. `examples/morphdemo` shows this in action.
|
|
79
|
+
- `rprint` is a variant of `print` that returns the image object, so `img = Image.Random(size=5).rprint()` does an assignment to `img` and displays the pixel values to stdout in one line.
|
|
80
|
+
- `Histogram` class
|
|
81
|
+
- now has a `pdf` property for an estimated/empirical probability density function
|
|
82
|
+
- cumulative frequency is renamed from `cdf` to `cf`; `ncdf` renamed to `cdf`
|
|
83
|
+
- now implemented using NumPy rather than OpenCV for wider dtype support
|
|
84
|
+
- works properly in Jupyter
|
|
85
|
+
- histogram computation moved to constructor
|
|
86
|
+
- `clip` controls bin range behaviour
|
|
87
|
+
- plotting options for `span`, `log`, `cursor`, and `stats` markers
|
|
88
|
+
- `Blobs` class
|
|
89
|
+
- major internal refactor; `Blob` is now a dataclass
|
|
90
|
+
- improved handling of runt (single-pixel) blobs
|
|
91
|
+
- added `id` method
|
|
92
|
+
- new attributes/methods: `MER()`/`plot_MER()`, `MEC()`/`plot_MEC()`
|
|
93
|
+
- added default color and linestyle to all plot functions. These all accept Matplotlib format string or keyword arguments for line styling
|
|
94
|
+
- Image sources
|
|
95
|
+
- all sources are iterators and context managers, reworked the common abstract base class
|
|
96
|
+
- all sources inherit display/animation (`.disp()`) and batch tensor (`.tensor()`) methods
|
|
97
|
+
- all sources accept keyword arguments forwarded to `convert`
|
|
98
|
+
- `VideoCamera` has a new `list` method showing camera name/id mapping
|
|
99
|
+
- `VideoFile`, `WebCam`, and `EarthView` are unchanged
|
|
100
|
+
- CLI
|
|
101
|
+
- improved `--help` strings and option ordering
|
|
102
|
+
- `mvtbtool` supports image preloading into the IPython namespace, autoreload, optional PyTorch import, and `MVTB_OPTIONS` environment variable
|
|
103
|
+
- `tagtool` reports ArUco/April tags to stdout or JSON
|
|
104
|
+
- notebook support
|
|
105
|
+
- notebooks revamped and extended
|
|
106
|
+
- `threshold_interactive` works in Jupyter
|
|
107
|
+
- notebook workflows are unit-testable
|
|
108
|
+
- distributed as a ZIP built by GitHub Actions
|
|
109
|
+
- distributed in a zero-install JupyterLite environment (WASM + Emscripten)
|
|
110
|
+
|
|
111
|
+
* Deprecated
|
|
112
|
+
- `iread(..., grey=...)` and `iread(..., gray=...)`; use `mono=` instead
|
|
113
|
+
- `img.image` and `img.A`; use `img.array`
|
|
114
|
+
- `img.to_int()` and `img.to_float()`; use `img.array_as()`
|
|
115
|
+
- `column`; use `view1d`
|
|
116
|
+
- `thresh()`; use `threshold()`
|
|
117
|
+
- threshold keyword `t`; use `threshold`
|
|
118
|
+
- threshold keyword `opt`; use `method`
|
|
119
|
+
- `ithresh`; use `threshold_interactive`
|
|
120
|
+
- `adaptive_threshold`; use `threshold_adaptive`
|
|
121
|
+
- legacy `Image.Constant` positional size form (for example migrate from `Image.Constant(10, 20, 30)` to `Image.Constant(30, size=(10, 20))`)
|
|
122
|
+
- `ImageCollection`; use `FileCollection`
|
|
123
|
+
- `ZipArchive`; use `FileArchive`
|
|
124
|
+
- `rank`; use `rankfilter`
|
|
125
|
+
- `Image.Zeros(10)` is now `Image.Zeros(size=10)`
|
|
126
|
+
- `Image.Constant(3,4,5)` is now `Image.Constant(5, size=(3,4))`
|
|
127
|
+
- `Image.Random(10)` is now `Image.Random(size=10)`
|
|
128
|
+
|
|
129
|
+
* Fixed
|
|
130
|
+
- resolved many Sphinx warnings
|
|
131
|
+
- resolved issues in plot/runblock examples
|
|
132
|
+
- improved OpenCV documentation link consistency where intersphinx is not effective
|
|
133
|
+
- fixed issues in `idisp` that confused Jupyter Matplotlib backend selection
|
|
134
|
+
|
|
135
|
+
* Miscellaneous
|
|
136
|
+
- generated OpenCV guard functions from OpenCV documentation for input validation
|
|
137
|
+
- `Kernel` class refactored to its own file
|
|
138
|
+
- ROS synchronization support via `SyncROSStreams`
|
|
139
|
+
|
|
140
|
+
1.0.2 January 2026
|
|
141
|
+
|
|
142
|
+
* `Image` class
|
|
143
|
+
|
|
144
|
+
- `warp_affine` can now warp an image into a given output image
|
|
145
|
+
- graphic primitives
|
|
146
|
+
- create an ArUco marker
|
|
147
|
+
- save as PDF
|
|
148
|
+
|
|
149
|
+
- all the draw_xxx() functions in base now have wrappers as methods of `Image`
|
|
150
|
+
- draw_xxx() now handle floating point arguments, rounding them to the neares int
|
|
151
|
+
- improvements in name2color to handle image datatypes and colororder
|
|
152
|
+
|
|
153
|
+
* FiducialCollection class, represent a generalized calibration board with AR tags
|
|
154
|
+
|
|
155
|
+
* ArUcoBoard class, represent a generalized ArUco calibration board
|
|
156
|
+
|
|
157
|
+
* changed to src folder layout, code is in src/machinevisiontoolbox
|
|
158
|
+
* changed from setuptools to hatch
|
|
159
|
+
* works if Open3D is not installed, it's always well behind in Python version support
|
|
160
|
+
* removed numpy < 2.0 constraint, OpenCV now suppports numpy 2.x
|
|
161
|
+
* working with Python 3.12 (except for Open3D)
|
|
162
|
+
* added command line tools:
|
|
163
|
+
- `imtool` for displaying images, exploring pixels, picking points, showing metadata etc. Works with your own images or those provided with MVTB
|
|
164
|
+
- `tagtool` for highlighting AR tags in images
|
|
165
|
+
|
|
166
|
+
1.0.1 March 2025
|
|
167
|
+
|
|
168
|
+
* `Image` class
|
|
169
|
+
- `.dice` method, chops an image up into tiles, can be overlapping
|
|
170
|
+
- `.Tile(columns=0)` will arrange the tiles into a roughly square layout
|
|
171
|
+
- Constant images, previously many of these could only generate square images, this is now generalized
|
|
172
|
+
- `.Chequerboard` creates a chequerboard pattern
|
|
173
|
+
- set background color for image warp undefined pixels
|
|
174
|
+
- single plane images can have a colorplane name
|
|
175
|
+
- deprecate `colordict()`, use `colororder2dict()` instead
|
|
176
|
+
- `String` now supports two string formats, can create color images
|
|
177
|
+
- fixed bug with gamma="sRGB" which always returned a float image, type is now the same as passed
|
|
178
|
+
|
|
179
|
+
* Blobs
|
|
180
|
+
|
|
181
|
+
- new methods for blob aligned box, plot_aligned_box,
|
|
182
|
+
- `plot_perimeter` options
|
|
183
|
+
- `perimeter_hull` convex hull
|
|
184
|
+
- fixed bug with runt blobs
|
|
185
|
+
|
|
186
|
+
* Kernels
|
|
187
|
+
|
|
188
|
+
- added `Kernel.HGauss` for Hessian of Gaussian
|
|
189
|
+
- added `Kernel` repr method, `disp` method
|
|
190
|
+
ArUcoBoard class
|
|
191
|
+
|
|
192
|
+
* Camera models
|
|
193
|
+
- Fixed errors in some camera projection models
|
|
194
|
+
|
|
195
|
+
* Point clouds
|
|
196
|
+
|
|
197
|
+
- `PointCloud` now has a "constructor" for depth images, `PointCloud.DepthImage()`
|
|
198
|
+
|
|
199
|
+
* Miscellaneous
|
|
200
|
+
|
|
201
|
+
- Lots more code examples and plots
|
|
202
|
+
- Move decoratores scalar_result and array_result to machinevisiontoolbox.decorators.py
|
|
203
|
+
- improved unit testing
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
1.0.0 January 2025
|
|
208
|
+
|
|
209
|
+
* `Kernel` methods now return `Kernel` instances rather than NumPy arrays. Methods that
|
|
210
|
+
accept a kernel can accept a `Kernel` instance or a NumPy array. Methods exist to
|
|
211
|
+
stringify or print a kernel.
|
|
212
|
+
|
|
213
|
+
* The indexing order of an `Image` object (using square bracket `__getitem__` access) has
|
|
214
|
+
changed and is now `img[u,v]` where `u` is the column coordinate and `v` is the row
|
|
215
|
+
coordinate. This is consistent with the column-first convention used across the
|
|
216
|
+
Toolbox and is consistent with the $(u,v)$ coordinate system for images. But, this
|
|
217
|
+
is the __opposite__ order to that used for NumPy index on the underlying array, and
|
|
218
|
+
to earlier versions of the Toolbox.
|
|
219
|
+
|
|
220
|
+
- a 2-tuple of integers, select this pixel. If the image has multiple planes, the
|
|
221
|
+
result is a vector over planes.
|
|
222
|
+
- a 3-tuple of integers, for a multiplane image select this pixel from the specified
|
|
223
|
+
plane.
|
|
224
|
+
- a 2-tuple of slice objects, select this region. If the image has multiple planes,
|
|
225
|
+
the result is a 3D array.
|
|
226
|
+
- a 3-tuple of slice objects, select this region of uv and planes
|
|
227
|
+
- an int, select this plane
|
|
228
|
+
- a string, select this named plane or planes
|
|
229
|
+
|
|
230
|
+
* added `pixel(u,v)` method for faster access to a single pixel value, scalar or vector.
|
|
231
|
+
|
|
232
|
+
* the children of a `Blob` is now given as a list of `Blob` objects, not their indices
|
|
233
|
+
within the overall list of blobs. This simplies traversing the blob hierarchy tree.
|
|
234
|
+
Similarly, the parent is a reference to the parent `Blob` object rather than an index,
|
|
235
|
+
and is `None` if the blob has no parent (its parent is the background).
|
|
236
|
+
|
|
237
|
+
* Documentation overhaul, both in-code docstrings, and the organization of the overall Sphinx document.
|
|
238
|
+
|
|
239
|
+
* Additional unit tests
|
|
240
|
+
|
|
241
|
+
* Myriad minor bug fixes, see commit history.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# sphinx-codeautolink: current assessment and fork plan
|
|
2
|
+
|
|
3
|
+
## Current state
|
|
4
|
+
|
|
5
|
+
The repository is currently building Sphinx successfully, but the docs still emit a substantial number of `sphinx-codeautolink` warnings, mostly of these forms:
|
|
6
|
+
|
|
7
|
+
- `codeautolink.match_name`
|
|
8
|
+
- `codeautolink.match_block`
|
|
9
|
+
|
|
10
|
+
Recent local improvements already made in MVTB:
|
|
11
|
+
|
|
12
|
+
- repaired several malformed code examples in `Sources.py` so they parse cleanly
|
|
13
|
+
- configured custom cleaners for `pycon`, `ipython`, and `ipython3` blocks in `docs/source/conf.py`
|
|
14
|
+
- confirmed that the remaining warnings are now mostly extension limitations or source-to-HTML matching issues, not obvious broken examples
|
|
15
|
+
|
|
16
|
+
## What the extension is actually doing
|
|
17
|
+
|
|
18
|
+
`sphinx-codeautolink` does use Python AST-based static analysis.
|
|
19
|
+
|
|
20
|
+
What it appears to do upstream:
|
|
21
|
+
|
|
22
|
+
- parses code blocks with `ast.parse(...)`
|
|
23
|
+
- walks the tree with an `ast.NodeVisitor`-style tracker
|
|
24
|
+
- records imports, names, attribute chains, some assignments, and scope information
|
|
25
|
+
- resolves names against imports, type hints, and the Sphinx inventory/intersphinx objects
|
|
26
|
+
- does not execute code
|
|
27
|
+
|
|
28
|
+
Important limitation:
|
|
29
|
+
|
|
30
|
+
It is not a full static type checker. Its own documentation indicates that parsing and type-hint resolution are incomplete, which matches the warning patterns seen in this repository.
|
|
31
|
+
|
|
32
|
+
## Updated direction
|
|
33
|
+
|
|
34
|
+
There is now a stronger implementation direction based on local fork work:
|
|
35
|
+
|
|
36
|
+
- the `runblock` path has already been forked and made substantially faster
|
|
37
|
+
- that execution-based path provides real runtime objects and types, which is often a better source of truth than AST inference for documentation examples
|
|
38
|
+
|
|
39
|
+
This changes the most useful fork strategy.
|
|
40
|
+
|
|
41
|
+
The goal should probably not be two mostly separate systems, one static and one executed. Instead, the better design is a shared pipeline with two analysis modes.
|
|
42
|
+
|
|
43
|
+
The shared front end should:
|
|
44
|
+
|
|
45
|
+
1. normalise the source block once
|
|
46
|
+
2. clean prompts and console syntax once
|
|
47
|
+
3. produce one internal representation of the block
|
|
48
|
+
|
|
49
|
+
From there, resolution can happen in two ways:
|
|
50
|
+
|
|
51
|
+
1. runtime-assisted resolution when execution is enabled and succeeds
|
|
52
|
+
2. static fallback resolution when execution is disabled, unsafe, slow, or incomplete
|
|
53
|
+
|
|
54
|
+
That means the two functions are "smooshed together" architecturally, but not collapsed into one unconditional execution path.
|
|
55
|
+
|
|
56
|
+
## Why the merged architecture is better
|
|
57
|
+
|
|
58
|
+
For MVTB-style docs examples, execution often gives better answers for names such as `im`, `f`, `camera`, `bag`, and similar local variables, because the resolver can inspect the actual runtime object rather than infer it from assignments.
|
|
59
|
+
|
|
60
|
+
The likely priority order for name resolution should be:
|
|
61
|
+
|
|
62
|
+
1. runtime object identity and type, when available
|
|
63
|
+
2. static AST/import/type-hint inference
|
|
64
|
+
3. existing inventory/name heuristics
|
|
65
|
+
|
|
66
|
+
This preserves the advantages of static analysis:
|
|
67
|
+
|
|
68
|
+
- works for non-runnable snippets
|
|
69
|
+
- works for deliberately partial snippets
|
|
70
|
+
- avoids executing unsafe or expensive blocks
|
|
71
|
+
|
|
72
|
+
while using execution where it gives a clear accuracy improvement.
|
|
73
|
+
|
|
74
|
+
## Fork feasibility
|
|
75
|
+
|
|
76
|
+
Yes, this looks forkable.
|
|
77
|
+
|
|
78
|
+
The likely intervention areas are:
|
|
79
|
+
|
|
80
|
+
1. parser logic
|
|
81
|
+
2. name/type resolution logic
|
|
82
|
+
3. block-to-generated-HTML matching logic
|
|
83
|
+
|
|
84
|
+
The practical goal should be:
|
|
85
|
+
|
|
86
|
+
Make it materially better for real documentation examples.
|
|
87
|
+
|
|
88
|
+
The practical goal should not be:
|
|
89
|
+
|
|
90
|
+
Turn it into a full general-purpose Python semantic analyser.
|
|
91
|
+
|
|
92
|
+
## Problems worth targeting first
|
|
93
|
+
|
|
94
|
+
These are the highest-value issues for MVTB-style documentation examples:
|
|
95
|
+
|
|
96
|
+
1. False warnings on multiline interactive examples.
|
|
97
|
+
2. Weak handling of simple value flow such as `im = ...` followed by attribute/method access.
|
|
98
|
+
3. Weak handling of documented objects referenced through short local names.
|
|
99
|
+
4. HTML/block matching failures where the code is reasonable but the generated page structure does not line up with the extension's expectations.
|
|
100
|
+
5. Noisy warnings on autosummary-generated stub pages where the signal is low.
|
|
101
|
+
|
|
102
|
+
## Concrete plan
|
|
103
|
+
|
|
104
|
+
### Phase 0: define the merged architecture
|
|
105
|
+
|
|
106
|
+
1. Identify the current overlap between block cleaning, parsing, and name extraction in the static and runblock paths.
|
|
107
|
+
2. Extract a shared block-normalisation layer.
|
|
108
|
+
3. Define one common intermediate result structure consumed by both runtime-assisted and static resolvers.
|
|
109
|
+
|
|
110
|
+
Success criterion:
|
|
111
|
+
|
|
112
|
+
There is one canonical representation of a documentation block, not two competing preprocessors.
|
|
113
|
+
|
|
114
|
+
### Phase 1: build a reproducible warning corpus
|
|
115
|
+
|
|
116
|
+
1. Save a representative Sphinx warning log from this repository.
|
|
117
|
+
2. Group warnings by pattern and by source file.
|
|
118
|
+
3. Select a small set of stable regression cases from MVTB docs, especially:
|
|
119
|
+
- `docs/source/intro.rst`
|
|
120
|
+
- `docs/source/sources.rst`
|
|
121
|
+
- camera/property stub pages
|
|
122
|
+
- autosummary pages that currently trigger `match_block`
|
|
123
|
+
|
|
124
|
+
Success criterion:
|
|
125
|
+
|
|
126
|
+
We have 5-10 concrete examples that fail consistently and represent the real pain points.
|
|
127
|
+
|
|
128
|
+
### Phase 2: inspect upstream code paths against those cases
|
|
129
|
+
|
|
130
|
+
1. Trace each chosen failure through the upstream parser and resolver.
|
|
131
|
+
2. Trace the same cases through the forked runblock execution path.
|
|
132
|
+
2. Determine whether each warning comes from:
|
|
133
|
+
- AST parsing limitations
|
|
134
|
+
- missing runtime-to-symbol mapping
|
|
135
|
+
- incomplete assignment/type propagation
|
|
136
|
+
- inventory resolution gaps
|
|
137
|
+
- HTML matching logic
|
|
138
|
+
3. Separate true unsupported constructs from fixable bugs.
|
|
139
|
+
|
|
140
|
+
Success criterion:
|
|
141
|
+
|
|
142
|
+
Each regression case is mapped to a specific upstream subsystem and failure mode.
|
|
143
|
+
|
|
144
|
+
### Phase 3: implement narrow fixes
|
|
145
|
+
|
|
146
|
+
Prefer small, doc-example-oriented fixes first:
|
|
147
|
+
|
|
148
|
+
1. Add runtime-assisted resolution for executed examples, using real objects/types from the fast runblock path.
|
|
149
|
+
2. Improve handling of simple assignment chains in the static fallback.
|
|
150
|
+
3. Improve propagation for obvious constructor-returned objects used in subsequent lines.
|
|
151
|
+
4. Relax or improve block/HTML matching where structurally valid examples are being missed.
|
|
152
|
+
5. Suppress or downgrade warnings in known low-value contexts such as some autosummary stubs if linking cannot be made reliable.
|
|
153
|
+
|
|
154
|
+
Success criterion:
|
|
155
|
+
|
|
156
|
+
The selected regression cases produce fewer warnings without introducing obvious bad links.
|
|
157
|
+
|
|
158
|
+
### Phase 4: validate against MVTB docs
|
|
159
|
+
|
|
160
|
+
1. Run the docs build before and after the fork changes.
|
|
161
|
+
2. Compare warning counts by category, not just total count.
|
|
162
|
+
3. Manually inspect a sample of generated links in HTML.
|
|
163
|
+
|
|
164
|
+
Success criterion:
|
|
165
|
+
|
|
166
|
+
Fewer warnings and acceptable link quality on real MVTB pages.
|
|
167
|
+
|
|
168
|
+
### Phase 5: decide maintenance strategy
|
|
169
|
+
|
|
170
|
+
Options:
|
|
171
|
+
|
|
172
|
+
1. Keep a private fork and pin to it.
|
|
173
|
+
2. Upstream small fixes and keep only local patches if needed.
|
|
174
|
+
3. If only warning noise improves, keep local config/workarounds and do not maintain a long-lived fork.
|
|
175
|
+
|
|
176
|
+
## Recommended first move
|
|
177
|
+
|
|
178
|
+
If this is resumed later, the most efficient next step is:
|
|
179
|
+
|
|
180
|
+
Create a small regression set from the current MVTB warning log, then map each case to whether it should be solved by runtime-assisted resolution or by static fallback.
|
|
181
|
+
|
|
182
|
+
Without that, the fork risks becoming speculative rather than driven by concrete documentation failures.
|
|
183
|
+
|
|
184
|
+
## Why this is worth doing
|
|
185
|
+
|
|
186
|
+
If upstream continues improving, MVTB can inherit those improvements. A fork only makes sense if we can identify a small number of high-value fixes that materially improve real documentation pages with manageable maintenance cost.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Migration to MVTB 2
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Image object
|
|
5
|
+
|
|
6
|
+
### Access to encapsulated pixel data
|
|
7
|
+
|
|
8
|
+
The `Image` object keeps a private reference to the numpy array that holds the pixel data. This array should not be
|
|
9
|
+
changed directly since it may invalidate the metadata in the object itself.
|
|
10
|
+
|
|
11
|
+
The private reference was previously either `.A` or `.image`. The former is too cryptic and the latter
|
|
12
|
+
confusing since it returns an ndarray not an `Image`.
|
|
13
|
+
|
|
14
|
+
For v2 this is now `.array`. It's a read-only property. You can use the referenced array but do not mutate it.
|
|
15
|
+
|
|
16
|
+
To get an ndarray of a particular type use `.array_as(dtype)` where `dtype` is a string or a np datatype.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Dtype change
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Reprs
|
|
23
|
+
|
|
24
|
+
In v1 the __str__ methods were often quite verbose, nicely formatted multiline displays. Some even
|
|
25
|
+
displayed tables using `ansitable`. Most __repr__ methods just called __str__ which is poor practice,
|
|
26
|
+
a __repr__ should be concise and single line and ideally be sufficient to recreate the object.
|
|
27
|
+
|
|
28
|
+
In v2, __repr__s now conform to that model. This means that the old workflow
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
>>> mvtb_method(...)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
would display a verbose response. Now you just get the cryptic version.
|
|
35
|
+
|
|
36
|
+
## Image.threshold()
|
|
37
|
+
|
|
38
|
+
`Image.threshold(t, opt)` where `t` is the threshold that could be a numeric threshold or a string specifying
|
|
39
|
+
an algorithm for choosing the threshold. This is modeled on cv.threshold which returns an image the same
|
|
40
|
+
type as the source. A bug meant that for floating point images the result would comprise 0 and inf values.
|
|
41
|
+
The algorithms for choosing a threshold, otsu and triangle, are limited to uint8/16 and uint8 pixels respectively.
|
|
42
|
+
|
|
43
|
+
A binary threshold of a floating image should be a boolean image not a float. However boolean images are
|
|
44
|
+
not well received by OpenCV, so the decision was made to return uint8 image with pixels as 0 (false) and
|
|
45
|
+
255 (true) for the binary threshold case.
|
|
46
|
+
|
|
47
|
+
Changes:
|
|
48
|
+
|
|
49
|
+
* for binary and binary_inv case the return value will always be uint8
|
|
50
|
+
* the as_bool option will return a bool image
|
|
51
|
+
* Otsu and triangle have been implemented from scratch using numpy and handle int or float images
|
|
52
|
+
* a new 'percentile' option has been added
|
|
53
|
+
|
|
54
|
+
>>> img.threshold(5).print()
|
|
55
|
+
>>> img.threshold('otsu')
|
|
56
|
+
>>> img.threshold('percentile', p=90)
|
|
57
|
+
|
|
58
|
+
## Image constants
|
|
59
|
+
|
|
60
|
+
`Image.Constant(10, 10, 3)` would create a 10x10 image containing pixel values of 3. It is not particularly
|
|
61
|
+
informative when read. It could also be written as `Image.Constant(w=10, h=10, value=3)` which is not much better.
|
|
62
|
+
Worse it could be written as `Image.Constant((10,10), 3)` or `Image.Constant(w=(10,10), value=3)`.
|
|
63
|
+
Too many options, and arguably the constant value should come first.
|
|
64
|
+
|
|
65
|
+
Shape functions like `Image.Squares(2, 10, 10)` would create...
|
|
66
|
+
|
|
67
|
+
All these functions now have the following keyword arguments, they cannot be positional.
|
|
68
|
+
|
|
69
|
+
* `size: tuple` a tuple either (W,H) or (W,H,C)
|
|
70
|
+
* `dtype: str | Dtype` a datatype specifier as either a string or an np.dtype
|
|
71
|
+
* `colororder: str` specifying the color order of a multi-channel image
|
|
72
|
+
* `like: Image` where the image sets the defaults for size, dtype and colororder, the options above will override those
|
|
73
|
+
|
|
74
|
+
The only positional arguments would the ones specific to the method.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# Other
|
|
79
|
+
|
|
80
|
+
Image.stats
|
|
81
|
+
|
|
82
|
+
`Image.stats` is now a property (dictionary-valued), not a method.
|
|
83
|
+
|
|
84
|
+
* v1: `img.stats()`
|
|
85
|
+
* v2: `img.stats`
|
|
86
|
+
* formatted console output: `img.printstats()`
|
|
87
|
+
|
|
88
|
+
Whole-image scalar statistics are now properties as well:
|
|
89
|
+
|
|
90
|
+
* v1: `img.sum()`, `img.min()`, `img.max()`, `img.mean()`, `img.std()`, `img.var()`, `img.median()`
|
|
91
|
+
* v2: `img.sum`, `img.min`, `img.max`, `img.mean`, `img.std`, `img.var`, `img.median`
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
.FORCE:
|
|
2
|
+
|
|
3
|
+
BLUE=\033[0;34m
|
|
4
|
+
BLACK=\033[0;30m
|
|
5
|
+
|
|
6
|
+
help:
|
|
7
|
+
@echo "$(BLUE) make test - run all unit tests"
|
|
8
|
+
@echo " make test-log - run all unit tests and write log to pytest.log"
|
|
9
|
+
@echo " make test-nb - run nbmake tests on RVC3 vision chapter notebooks"
|
|
10
|
+
@echo " make coverage - run unit tests and coverage report"
|
|
11
|
+
@echo " make typehints - run mypy type-hint coverage report and open HTML"
|
|
12
|
+
@echo " make docs - build Sphinx documentation"
|
|
13
|
+
@echo " make docs-nitpicky - build Sphinx docs with nitpicky cross-reference checks"
|
|
14
|
+
@echo " make docs-strict - nitpicky Sphinx build with warnings treated as errors"
|
|
15
|
+
@echo " make view - open Sphinx doco build (uses open for MacOS)"
|
|
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
|
+
@echo " make clean - remove dist and docs build files"
|
|
19
|
+
@echo " make help - this message$(BLACK)"
|
|
20
|
+
|
|
21
|
+
test:
|
|
22
|
+
validate-pyproject pyproject.toml
|
|
23
|
+
python -m pytest
|
|
24
|
+
|
|
25
|
+
test-log:
|
|
26
|
+
python -m pytest -W all --tb=short 2>&1 | tee pytest.log
|
|
27
|
+
@echo "pytest log --> pytest.log"
|
|
28
|
+
|
|
29
|
+
test-nb:
|
|
30
|
+
python -m pytest --nbmake notebooks
|
|
31
|
+
|
|
32
|
+
test-rvc:
|
|
33
|
+
MVTB_TEST_MODE=True python -m pytest --nbmake tests/RVC
|
|
34
|
+
|
|
35
|
+
coverage:
|
|
36
|
+
coverage run --source='src/machinevisiontoolbox' -m pytest
|
|
37
|
+
coverage report
|
|
38
|
+
coverage html
|
|
39
|
+
open -a Safari htmlcov/index.html
|
|
40
|
+
|
|
41
|
+
typehints:
|
|
42
|
+
-mypy src/machinevisiontoolbox --ignore-missing-imports --html-report /tmp/mypy-typehints
|
|
43
|
+
open -a Safari /tmp/mypy-typehints/index.html
|
|
44
|
+
|
|
45
|
+
docs: .FORCE
|
|
46
|
+
(cd docs; make html O="-w warnings.txt")
|
|
47
|
+
|
|
48
|
+
docs-nitpicky: .FORCE
|
|
49
|
+
conda run --no-capture-output -n dev sphinx-build -n -b html docs/source docs/build/html
|
|
50
|
+
|
|
51
|
+
docs-strict: .FORCE
|
|
52
|
+
conda run --no-capture-output -n dev sphinx-build -n -W -b html docs/source docs/build/html
|
|
53
|
+
|
|
54
|
+
view: .FORCE
|
|
55
|
+
open -a Safari docs/build/html/index.html
|
|
56
|
+
|
|
57
|
+
dist: .FORCE
|
|
58
|
+
# $(MAKE) test
|
|
59
|
+
python -m build
|
|
60
|
+
ls -lh dist/*
|
|
61
|
+
|
|
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
|
+
clean: .FORCE
|
|
74
|
+
(cd docs; make clean)
|
|
75
|
+
-rm -r *.egg-info
|
|
76
|
+
-rm -r dist build
|
|
77
|
+
|