machinevision-toolbox-python 1.0.2__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.
Files changed (184) hide show
  1. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/.gitignore +22 -0
  2. machinevision_toolbox_python-2.0.0/CHANGELOG.md +241 -0
  3. machinevision_toolbox_python-2.0.0/CODEAUTOLINK_FORK_PLAN.md +186 -0
  4. machinevision_toolbox_python-2.0.0/MIGRATION.md +91 -0
  5. machinevision_toolbox_python-2.0.0/Makefile +77 -0
  6. machinevision_toolbox_python-2.0.0/NOTES +57 -0
  7. machinevision_toolbox_python-2.0.0/OPENCV_FUNCTIONS-original.md +107 -0
  8. machinevision_toolbox_python-2.0.0/OPENCV_FUNCTIONS.md +184 -0
  9. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/PKG-INFO +103 -73
  10. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/README.md +72 -64
  11. machinevision_toolbox_python-2.0.0/audit_typing.py +108 -0
  12. machinevision_toolbox_python-2.0.0/bags/RenderOption_2026-03-29-12-09-23.json +41 -0
  13. machinevision_toolbox_python-2.0.0/deprecation_warnings.csv +22 -0
  14. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/bunny.py +1 -0
  15. machinevision_toolbox_python-2.0.0/examples/bus.jpg +0 -0
  16. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/color.py +1 -2
  17. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/matching.py +3 -5
  18. machinevision_toolbox_python-2.0.0/examples/morphdemo.py +151 -0
  19. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/randomdots.py +1 -1
  20. machinevision_toolbox_python-2.0.0/examples/ros_stream.py +24 -0
  21. machinevision_toolbox_python-2.0.0/examples/showzip.py +11 -0
  22. machinevision_toolbox_python-2.0.0/examples/street_scene.jpg +11 -0
  23. machinevision_toolbox_python-2.0.0/examples/torch-yolo.py +37 -0
  24. machinevision_toolbox_python-2.0.0/examples/torch_seg.py +54 -0
  25. machinevision_toolbox_python-2.0.0/examples/yolo26n.pt +0 -0
  26. machinevision_toolbox_python-2.0.0/flowers.jpg +0 -0
  27. machinevision_toolbox_python-2.0.0/fmtparser.py +78 -0
  28. machinevision_toolbox_python-2.0.0/inspect_bag.py +9 -0
  29. machinevision_toolbox_python-2.0.0/machinevision-toolbox-python.pdf +0 -0
  30. machinevision_toolbox_python-2.0.0/machinevision-toolbox-python.svg +13 -0
  31. machinevision_toolbox_python-2.0.0/machinevisiontoolbox.pdf +0 -0
  32. machinevision_toolbox_python-2.0.0/plot_call_inventory.md +29 -0
  33. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/pyproject.toml +61 -23
  34. machinevision_toolbox_python-2.0.0/readbag.py +347 -0
  35. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/BagOfWords.py +74 -121
  36. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/BundleAdjust.py +95 -77
  37. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/Camera.py +642 -580
  38. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageBlobs.py +724 -571
  39. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageColor.py +105 -81
  40. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageConstants.py +1106 -0
  41. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageCore.docstring +2877 -0
  42. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageCore.py +1644 -460
  43. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageFiducials.py +170 -98
  44. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageIO.py +330 -191
  45. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageLineFeatures.py +71 -37
  46. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageMorph.py +296 -117
  47. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageMultiview.py +129 -82
  48. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImagePointFeatures.py +363 -419
  49. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageProcessing.py +1435 -0
  50. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageRegionFeatures.py +79 -88
  51. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageReshape.py +308 -214
  52. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/ImageSpatial.py +398 -936
  53. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageTensor.py +242 -0
  54. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/ImageWholeFeatures.py +1763 -0
  55. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/Kernel.py +753 -0
  56. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/PointCloud.py +122 -81
  57. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/Sources.py +4227 -0
  58. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/VisualServo.py +140 -99
  59. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/__init__.py +192 -0
  60. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/_image_typing.py +207 -0
  61. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/__init__.py +11 -6
  62. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/color.py +257 -156
  63. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/data.py +25 -24
  64. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/findpeaks.py +35 -10
  65. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/graphics.py +378 -164
  66. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/imageio.py +507 -216
  67. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/meshgrid.py +13 -3
  68. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/shapes.py +121 -62
  69. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/types.py +28 -16
  70. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/base/version.py +12 -5
  71. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/_bintools.py +61 -0
  72. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/bagtool.py +286 -0
  73. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/imtool.py +234 -0
  74. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/bin/imtool.py → machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/labeltool.py +14 -28
  75. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/mvtbtool.py +372 -0
  76. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/ocrtool.py +155 -0
  77. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/bin/tagtool.py +290 -0
  78. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/camera.py +14 -56
  79. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/test_blocks.py +6 -5
  80. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/camera_derivatives.py +1098 -0
  81. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/cvfuncs.py +40 -0
  82. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/decorators.py +17 -9
  83. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/docbugs.py +47 -0
  84. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/mvtb_types.py +23 -0
  85. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/newcameras.py +4 -2
  86. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/test_skimage.py +12 -0
  87. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/testblobplots.py +17 -0
  88. machinevision_toolbox_python-2.0.0/src/machinevisiontoolbox/x.json +296 -0
  89. machinevision_toolbox_python-2.0.0/ss +1 -0
  90. machinevision_toolbox_python-2.0.0/sunday.py +71 -0
  91. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/symbolic/bundle-adjust.py +29 -9
  92. machinevision_toolbox_python-2.0.0/x.json +254 -0
  93. machinevision_toolbox_python-2.0.0/xx.mp4 +0 -0
  94. machinevision_toolbox_python-1.0.2/CHANGELOG.md +0 -103
  95. machinevision_toolbox_python-1.0.2/Makefile +0 -43
  96. machinevision_toolbox_python-1.0.2/NOTES +0 -19
  97. machinevision_toolbox_python-1.0.2/bun.png +0 -0
  98. machinevision_toolbox_python-1.0.2/camtest.py +0 -76
  99. machinevision_toolbox_python-1.0.2/dependencies.pdf +0 -0
  100. machinevision_toolbox_python-1.0.2/examples/morphdemo.py +0 -38
  101. machinevision_toolbox_python-1.0.2/examples/mwe.py +0 -15
  102. machinevision_toolbox_python-1.0.2/examples/readme.py +0 -79
  103. machinevision_toolbox_python-1.0.2/examples/showzip.py +0 -9
  104. machinevision_toolbox_python-1.0.2/figs/MVTBDataLogo.png +0 -0
  105. machinevision_toolbox_python-1.0.2/figs/VisionToolboxLogo_CircBlack.png +0 -0
  106. machinevision_toolbox_python-1.0.2/figs/VisionToolboxLogo_NoBackgnd@2x.png +0 -0
  107. machinevision_toolbox_python-1.0.2/figs/blobs_graph.png +0 -0
  108. machinevision_toolbox_python-1.0.2/figs/colorspace.png +0 -0
  109. machinevision_toolbox_python-1.0.2/figs/cube.png +0 -0
  110. machinevision_toolbox_python-1.0.2/figs/cube_fisheye.png +0 -0
  111. machinevision_toolbox_python-1.0.2/figs/gallery1.png +0 -0
  112. machinevision_toolbox_python-1.0.2/figs/hough.png +0 -0
  113. machinevision_toolbox_python-1.0.2/figs/matching.png +0 -0
  114. machinevision_toolbox_python-1.0.2/figs/matching_ransac.png +0 -0
  115. machinevision_toolbox_python-1.0.2/figs/mona+smooth.png +0 -0
  116. machinevision_toolbox_python-1.0.2/figs/mona.png +0 -0
  117. machinevision_toolbox_python-1.0.2/figs/mona_smooth.png +0 -0
  118. machinevision_toolbox_python-1.0.2/figs/multi.png +0 -0
  119. machinevision_toolbox_python-1.0.2/figs/multi_labelled.png +0 -0
  120. machinevision_toolbox_python-1.0.2/figs/shark2+boxes.png +0 -0
  121. machinevision_toolbox_python-1.0.2/notebooks/IBVS.ipynb +0 -472
  122. machinevision_toolbox_python-1.0.2/notebooks/ImageMotion.ipynb +0 -694
  123. machinevision_toolbox_python-1.0.2/notebooks/Untitled.ipynb +0 -497
  124. machinevision_toolbox_python-1.0.2/notebooks/Untitled1.ipynb +0 -4182
  125. machinevision_toolbox_python-1.0.2/notebooks/blob.ipynb +0 -378
  126. machinevision_toolbox_python-1.0.2/notebooks/calibration-fixture.png +0 -0
  127. machinevision_toolbox_python-1.0.2/notebooks/calibration.ipynb +0 -2862
  128. machinevision_toolbox_python-1.0.2/notebooks/camera.ipynb +0 -1494
  129. machinevision_toolbox_python-1.0.2/notebooks/chap10.ipynb +0 -969
  130. machinevision_toolbox_python-1.0.2/notebooks/color-images.ipynb +0 -2191
  131. machinevision_toolbox_python-1.0.2/notebooks/cones.ipynb +0 -1188
  132. machinevision_toolbox_python-1.0.2/notebooks/fiducuals.ipynb +0 -2344
  133. machinevision_toolbox_python-1.0.2/notebooks/finding-blobs.ipynb +0 -4307
  134. machinevision_toolbox_python-1.0.2/notebooks/gamma.ipynb +0 -2054
  135. machinevision_toolbox_python-1.0.2/notebooks/greyscale-images.ipynb +0 -8116
  136. machinevision_toolbox_python-1.0.2/notebooks/homogeneous-coords.ipynb +0 -696
  137. machinevision_toolbox_python-1.0.2/notebooks/homography.ipynb +0 -385
  138. machinevision_toolbox_python-1.0.2/notebooks/image-features.ipynb +0 -836
  139. machinevision_toolbox_python-1.0.2/notebooks/image.ipynb +0 -723
  140. machinevision_toolbox_python-1.0.2/notebooks/imageprocessing.ipynb +0 -591
  141. machinevision_toolbox_python-1.0.2/notebooks/images/apriltags.png +0 -0
  142. machinevision_toolbox_python-1.0.2/notebooks/images/aruco.png +0 -0
  143. machinevision_toolbox_python-1.0.2/notebooks/images/butterfly.jpg +0 -0
  144. machinevision_toolbox_python-1.0.2/notebooks/images/calib-image.png +0 -0
  145. machinevision_toolbox_python-1.0.2/notebooks/images/calibration-fixture.png +0 -0
  146. machinevision_toolbox_python-1.0.2/notebooks/images/coordinate-frames.png +0 -0
  147. machinevision_toolbox_python-1.0.2/notebooks/images/output_9.png +0 -0
  148. machinevision_toolbox_python-1.0.2/notebooks/point-features.ipynb +0 -11637
  149. machinevision_toolbox_python-1.0.2/notebooks/sift.ipynb +0 -213
  150. machinevision_toolbox_python-1.0.2/notebooks/unknown_camera.py +0 -40
  151. machinevision_toolbox_python-1.0.2/setup.cfg +0 -2
  152. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/ImageConstants.py +0 -645
  153. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/ImageProcessing.py +0 -1053
  154. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/ImageWholeFeatures.py +0 -1101
  155. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/Sources.py +0 -840
  156. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/__init__.py +0 -45
  157. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/base/esttheta.py +0 -97
  158. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/bin/ce.py +0 -27
  159. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/bin/mvtbtool.py +0 -192
  160. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/bin/tagtool.py +0 -250
  161. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/camera_derivatives.py +0 -7
  162. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/machinevision-toolbox-python.code-workspace +0 -7
  163. machinevision_toolbox_python-1.0.2/src/machinevisiontoolbox/mvtb_types.py +0 -15
  164. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/LICENSE +0 -0
  165. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/README.md +0 -0
  166. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/blobs1.py +0 -0
  167. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/blobs2.py +0 -0
  168. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/corners.py +0 -0
  169. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/monalisa.py +0 -0
  170. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/examples/ransac_line.py +0 -0
  171. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/findimages.py +0 -0
  172. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/ilabel.c +0 -0
  173. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/ilabel.py-unopt +0 -0
  174. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/phone.py +0 -0
  175. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/aruco0.pdf +0 -0
  176. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/aruco50.pdf +0 -0
  177. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/camera.png +0 -0
  178. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/estpose_p.png +0 -0
  179. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/icons.sh +0 -0
  180. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/imageplane.png +0 -0
  181. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/Icons/visjac_p.png +0 -0
  182. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/blocks/__init__.py +0 -0
  183. {machinevision_toolbox_python-1.0.2 → machinevision_toolbox_python-2.0.0}/src/machinevisiontoolbox/fiducial.py +0 -0
  184. {machinevision_toolbox_python-1.0.2 → 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
+