machinevision-toolbox-python 2.0.0__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/PKG-INFO +1 -1
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/pyproject.toml +1 -1
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageBlobs.py +199 -25
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/Sources.py +19 -3
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/.gitignore +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/CHANGELOG.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/CODEAUTOLINK_FORK_PLAN.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/LICENSE +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/MIGRATION.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/Makefile +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/NOTES +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/OPENCV_FUNCTIONS-original.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/OPENCV_FUNCTIONS.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/README.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/audit_typing.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/bags/RenderOption_2026-03-29-12-09-23.json +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/deprecation_warnings.csv +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/README.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/blobs1.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/blobs2.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/bunny.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/bus.jpg +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/color.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/corners.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/matching.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/monalisa.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/morphdemo.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/randomdots.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/ransac_line.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/ros_stream.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/showzip.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/street_scene.jpg +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/torch-yolo.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/torch_seg.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/yolo26n.pt +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/findimages.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/flowers.jpg +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/fmtparser.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/ilabel.c +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/ilabel.py-unopt +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/inspect_bag.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/machinevision-toolbox-python.pdf +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/machinevision-toolbox-python.svg +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/machinevisiontoolbox.pdf +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/phone.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/plot_call_inventory.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/readbag.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/BagOfWords.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/BundleAdjust.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/Camera.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageColor.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageConstants.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageCore.docstring +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageCore.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageFiducials.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageIO.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageLineFeatures.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageMorph.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageMultiview.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImagePointFeatures.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageProcessing.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageRegionFeatures.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageReshape.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageSpatial.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageTensor.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/ImageWholeFeatures.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/Kernel.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/PointCloud.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/VisualServo.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/__init__.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/_image_typing.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/aruco0.pdf +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/aruco50.pdf +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/__init__.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/color.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/data.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/findpeaks.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/graphics.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/imageio.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/meshgrid.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/shapes.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/types.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/base/version.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/_bintools.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/bagtool.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/imtool.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/labeltool.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/mvtbtool.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/ocrtool.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/bin/tagtool.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/Icons/camera.png +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/Icons/estpose_p.png +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/Icons/icons.sh +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/Icons/imageplane.png +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/Icons/visjac_p.png +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/__init__.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/camera.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/blocks/test_blocks.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/camera_derivatives.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/cvfuncs.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/decorators.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/docbugs.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/fiducial.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/mvtb_types.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/newcameras.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/test_skimage.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/testblobplots.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/src/machinevisiontoolbox/x.json +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/ss +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/sunday.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/symbolic/README.md +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/symbolic/bundle-adjust.py +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/x.json +0 -0
- {machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/xx.mp4 +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: machinevision-toolbox-python
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: Object-oriented machine vision for Python.
|
|
5
5
|
Project-URL: Homepage, https://github.com/petercorke/machinevision-toolbox-python
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/pypa/sampleproject/issues
|
|
@@ -3,6 +3,8 @@ Detection and description of 2D blob (connected region) features in images.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import copy
|
|
6
|
+
import io
|
|
7
|
+
import json
|
|
6
8
|
import subprocess
|
|
7
9
|
import sys
|
|
8
10
|
import tempfile
|
|
@@ -1194,7 +1196,7 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
1194
1196
|
>>> blobs[2].level
|
|
1195
1197
|
>>> blobs.level
|
|
1196
1198
|
|
|
1197
|
-
:seealso: :meth:`color` :meth:`parent` :meth:`children` :meth:`dotfile`
|
|
1199
|
+
:seealso: :meth:`color` :meth:`parent` :meth:`children` :meth:`dotfile` :meth:`graph`
|
|
1198
1200
|
"""
|
|
1199
1201
|
return [b.level for b in self.data]
|
|
1200
1202
|
|
|
@@ -1247,7 +1249,7 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
1247
1249
|
|
|
1248
1250
|
A parent of -1 is the image background.
|
|
1249
1251
|
|
|
1250
|
-
:seealso: :meth:`id` :meth:`children` :meth:`level` :meth:`dotfile`
|
|
1252
|
+
:seealso: :meth:`id` :meth:`children` :meth:`level` :meth:`dotfile` :meth:`graph`
|
|
1251
1253
|
"""
|
|
1252
1254
|
return [b.parent.id if b.parent is not None else -1 for b in self.data]
|
|
1253
1255
|
|
|
@@ -1272,7 +1274,7 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
1272
1274
|
>>> blobs[6].id
|
|
1273
1275
|
|
|
1274
1276
|
|
|
1275
|
-
:seealso: :meth:`parent` :meth:`children` :meth:`level` :meth:`dotfile`
|
|
1277
|
+
:seealso: :meth:`parent` :meth:`children` :meth:`level` :meth:`dotfile` :meth:`graph`
|
|
1276
1278
|
"""
|
|
1277
1279
|
return [b.id for b in self.data]
|
|
1278
1280
|
|
|
@@ -1293,7 +1295,7 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
1293
1295
|
>>> blobs = im.blobs()
|
|
1294
1296
|
>>> blobs[5].children
|
|
1295
1297
|
|
|
1296
|
-
:seealso: :meth:`parent` :meth:`level` :meth:`dotfile`
|
|
1298
|
+
:seealso: :meth:`parent` :meth:`level` :meth:`dotfile` :meth:`graph`
|
|
1297
1299
|
"""
|
|
1298
1300
|
return [[c.id for c in b.children] for b in self.data]
|
|
1299
1301
|
|
|
@@ -2380,6 +2382,180 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
2380
2382
|
|
|
2381
2383
|
return image.__class__(labels)
|
|
2382
2384
|
|
|
2385
|
+
def graph(
|
|
2386
|
+
self,
|
|
2387
|
+
format: str = "dot",
|
|
2388
|
+
filename: str | io.TextIOBase | None = None,
|
|
2389
|
+
direction: str | None = None,
|
|
2390
|
+
) -> str:
|
|
2391
|
+
"""
|
|
2392
|
+
Render blob hierarchy graph text.
|
|
2393
|
+
|
|
2394
|
+
:param format: graph output format: ``"dot"``, ``"mermaid"``,
|
|
2395
|
+
``"mermaid_fenced"``, ``"graphml"`` or ``"elk"``
|
|
2396
|
+
:type format: str, optional
|
|
2397
|
+
:param filename: destination path or open text stream, defaults to None
|
|
2398
|
+
:type filename: str | file handle | None, optional
|
|
2399
|
+
:param direction: graph direction for DOT output, defaults to None
|
|
2400
|
+
:type direction: str, optional
|
|
2401
|
+
:return: rendered graph text
|
|
2402
|
+
:rtype: str
|
|
2403
|
+
|
|
2404
|
+
Creates graph text representing the blob hierarchy. If ``filename`` is
|
|
2405
|
+
provided, the rendered text is also written to it.
|
|
2406
|
+
|
|
2407
|
+
Mermaid outputs:
|
|
2408
|
+
|
|
2409
|
+
- ``"mermaid"`` returns plain Mermaid text.
|
|
2410
|
+
- ``"mermaid_fenced"`` returns Markdown fenced text suitable for
|
|
2411
|
+
direct display via ``IPython.display.Markdown``.
|
|
2412
|
+
|
|
2413
|
+
The blob hierarchy is represented as a directed graph where each node is
|
|
2414
|
+
a blob id and each edge points from parent blob to child blob.
|
|
2415
|
+
|
|
2416
|
+
:seealso: :meth:`dotfile` :meth:`parent` :meth:`children` :meth:`level`
|
|
2417
|
+
"""
|
|
2418
|
+
|
|
2419
|
+
graph_format = format.lower().replace("-", "_")
|
|
2420
|
+
|
|
2421
|
+
def _parent_id(blob: Any) -> int:
|
|
2422
|
+
parent = blob.parent
|
|
2423
|
+
if parent is None:
|
|
2424
|
+
return -1
|
|
2425
|
+
if isinstance(parent, int):
|
|
2426
|
+
return parent
|
|
2427
|
+
return parent.id
|
|
2428
|
+
|
|
2429
|
+
hierarchy_edges = [(_parent_id(blob), blob.id) for blob in self]
|
|
2430
|
+
node_ids_set = {blob.id for blob in self}
|
|
2431
|
+
if any(parent_id == -1 for parent_id, _ in hierarchy_edges):
|
|
2432
|
+
node_ids_set.add(-1)
|
|
2433
|
+
|
|
2434
|
+
if graph_format == "dot":
|
|
2435
|
+
lines = ["digraph {"]
|
|
2436
|
+
if direction is not None:
|
|
2437
|
+
lines.append(f"rankdir = {direction}")
|
|
2438
|
+
|
|
2439
|
+
for node_id in sorted(node_ids_set):
|
|
2440
|
+
lines.append(f' "{node_id}"')
|
|
2441
|
+
|
|
2442
|
+
for parent_id, child_id in hierarchy_edges:
|
|
2443
|
+
lines.append(f' "{parent_id}" -> "{child_id}"')
|
|
2444
|
+
|
|
2445
|
+
lines.append("}")
|
|
2446
|
+
text = "\n".join(lines) + "\n"
|
|
2447
|
+
|
|
2448
|
+
elif graph_format in ("mermaid", "mermaid_fenced"):
|
|
2449
|
+
lines = ["flowchart TB"]
|
|
2450
|
+
node_ids: dict[Any, str] = {}
|
|
2451
|
+
sorted_nodes = sorted(node_ids_set)
|
|
2452
|
+
|
|
2453
|
+
for i, node in enumerate(sorted_nodes):
|
|
2454
|
+
node_alias = f"b{i}"
|
|
2455
|
+
node_ids[node] = node_alias
|
|
2456
|
+
lines.append(f' {node_alias}["{node}"]')
|
|
2457
|
+
|
|
2458
|
+
for parent_id, child_id in hierarchy_edges:
|
|
2459
|
+
lines.append(f" {node_ids[parent_id]} --> {node_ids[child_id]}")
|
|
2460
|
+
|
|
2461
|
+
mermaid_text = "\n".join(lines) + "\n"
|
|
2462
|
+
if graph_format == "mermaid_fenced":
|
|
2463
|
+
text = f"```mermaid\n{mermaid_text}```\n"
|
|
2464
|
+
else:
|
|
2465
|
+
text = mermaid_text
|
|
2466
|
+
|
|
2467
|
+
elif graph_format == "graphml":
|
|
2468
|
+
|
|
2469
|
+
def _xml_escape(value: str) -> str:
|
|
2470
|
+
return (
|
|
2471
|
+
value.replace("&", "&")
|
|
2472
|
+
.replace("<", "<")
|
|
2473
|
+
.replace(">", ">")
|
|
2474
|
+
.replace('"', """)
|
|
2475
|
+
.replace("'", "'")
|
|
2476
|
+
)
|
|
2477
|
+
|
|
2478
|
+
lines = [
|
|
2479
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
2480
|
+
'<graphml xmlns="http://graphml.graphdrawing.org/xmlns"',
|
|
2481
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',
|
|
2482
|
+
' xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns',
|
|
2483
|
+
' http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">',
|
|
2484
|
+
' <key id="node_label" for="node" attr.name="label" attr.type="string"/>',
|
|
2485
|
+
' <graph id="G" edgedefault="directed">',
|
|
2486
|
+
]
|
|
2487
|
+
|
|
2488
|
+
for node in sorted(node_ids_set):
|
|
2489
|
+
node_id = f"n{node}"
|
|
2490
|
+
lines.extend(
|
|
2491
|
+
[
|
|
2492
|
+
f' <node id="{node_id}">',
|
|
2493
|
+
f' <data key="node_label">{_xml_escape(str(node))}</data>',
|
|
2494
|
+
" </node>",
|
|
2495
|
+
]
|
|
2496
|
+
)
|
|
2497
|
+
|
|
2498
|
+
edge_id = 0
|
|
2499
|
+
for parent_id, child_id in hierarchy_edges:
|
|
2500
|
+
lines.append(
|
|
2501
|
+
f' <edge id="e{edge_id}" source="n{parent_id}" target="n{child_id}"/>'
|
|
2502
|
+
)
|
|
2503
|
+
edge_id += 1
|
|
2504
|
+
|
|
2505
|
+
lines.extend([" </graph>", "</graphml>"])
|
|
2506
|
+
text = "\n".join(lines) + "\n"
|
|
2507
|
+
|
|
2508
|
+
elif graph_format == "elk":
|
|
2509
|
+
children = []
|
|
2510
|
+
edges = []
|
|
2511
|
+
|
|
2512
|
+
for node in sorted(node_ids_set):
|
|
2513
|
+
children.append(
|
|
2514
|
+
{
|
|
2515
|
+
"id": f"n{node}",
|
|
2516
|
+
"labels": [{"text": str(node)}],
|
|
2517
|
+
"width": 60,
|
|
2518
|
+
"height": 40,
|
|
2519
|
+
}
|
|
2520
|
+
)
|
|
2521
|
+
|
|
2522
|
+
edge_id = 0
|
|
2523
|
+
for parent_id, child_id in hierarchy_edges:
|
|
2524
|
+
edges.append(
|
|
2525
|
+
{
|
|
2526
|
+
"id": f"e{edge_id}",
|
|
2527
|
+
"sources": [f"n{parent_id}"],
|
|
2528
|
+
"targets": [f"n{child_id}"],
|
|
2529
|
+
}
|
|
2530
|
+
)
|
|
2531
|
+
edge_id += 1
|
|
2532
|
+
|
|
2533
|
+
elk_graph = {
|
|
2534
|
+
"id": "root",
|
|
2535
|
+
"layoutOptions": {
|
|
2536
|
+
"org.eclipse.elk.algorithm": "layered",
|
|
2537
|
+
"org.eclipse.elk.direction": "DOWN",
|
|
2538
|
+
},
|
|
2539
|
+
"children": children,
|
|
2540
|
+
"edges": edges,
|
|
2541
|
+
}
|
|
2542
|
+
text = json.dumps(elk_graph, indent=2) + "\n"
|
|
2543
|
+
|
|
2544
|
+
else:
|
|
2545
|
+
raise ValueError(
|
|
2546
|
+
"unsupported graph format "
|
|
2547
|
+
f"'{format}', expected 'dot', 'mermaid', 'mermaid_fenced', 'graphml' or 'elk'"
|
|
2548
|
+
)
|
|
2549
|
+
|
|
2550
|
+
if filename is not None:
|
|
2551
|
+
if isinstance(filename, str):
|
|
2552
|
+
with open(filename, "w") as file:
|
|
2553
|
+
file.write(text)
|
|
2554
|
+
else:
|
|
2555
|
+
filename.write(text)
|
|
2556
|
+
|
|
2557
|
+
return text
|
|
2558
|
+
|
|
2383
2559
|
def dotfile(
|
|
2384
2560
|
self, filename: Any = None, direction: str | None = None, show: bool = False
|
|
2385
2561
|
) -> None:
|
|
@@ -2400,50 +2576,48 @@ class Blobs(UserList): # lgtm[py/missing-equals]
|
|
|
2400
2576
|
.. note:: If ``filename`` is a file object then the file will *not*
|
|
2401
2577
|
be closed after the GraphViz model is written.
|
|
2402
2578
|
|
|
2403
|
-
:seealso: :meth:`child` :meth:`parent` :meth:`level`
|
|
2579
|
+
:seealso: :meth:`graph` :meth:`child` :meth:`parent` :meth:`level`
|
|
2404
2580
|
"""
|
|
2405
2581
|
|
|
2406
2582
|
if show:
|
|
2407
2583
|
# create the temporary dotfile
|
|
2408
2584
|
filename = tempfile.TemporaryFile(mode="w")
|
|
2585
|
+
dot_text = self.graph(format="dot", direction=direction)
|
|
2586
|
+
|
|
2409
2587
|
if filename is None:
|
|
2410
2588
|
f = sys.stdout
|
|
2589
|
+
f.write(dot_text)
|
|
2411
2590
|
elif isinstance(filename, str):
|
|
2412
|
-
|
|
2591
|
+
with open(filename, "w") as f:
|
|
2592
|
+
f.write(dot_text)
|
|
2413
2593
|
else:
|
|
2414
2594
|
f = filename
|
|
2415
|
-
|
|
2416
|
-
print("digraph {", file=f)
|
|
2417
|
-
|
|
2418
|
-
if direction is not None:
|
|
2419
|
-
print(f"rankdir = {direction}", file=f)
|
|
2420
|
-
|
|
2421
|
-
# add the nodes including name and position
|
|
2422
|
-
for id, blob in enumerate(self):
|
|
2423
|
-
print(' "{:d}"'.format(id), file=f)
|
|
2424
|
-
print(
|
|
2425
|
-
' "{:d}" -> "{:d}"'.format(blob.parent if blob.parent else -1, id),
|
|
2426
|
-
file=f,
|
|
2427
|
-
)
|
|
2428
|
-
|
|
2429
|
-
print("}", file=f)
|
|
2595
|
+
f.write(dot_text)
|
|
2430
2596
|
|
|
2431
2597
|
if show:
|
|
2432
2598
|
# rewind the dot file, create PDF file in the filesystem, run dot
|
|
2433
|
-
|
|
2599
|
+
if filename is None:
|
|
2600
|
+
dot_stream = tempfile.TemporaryFile(mode="w+")
|
|
2601
|
+
dot_stream.write(dot_text)
|
|
2602
|
+
dot_stream.seek(0)
|
|
2603
|
+
elif isinstance(filename, str):
|
|
2604
|
+
dot_stream = open(filename, "r")
|
|
2605
|
+
else:
|
|
2606
|
+
f.seek(0)
|
|
2607
|
+
dot_stream = f
|
|
2608
|
+
|
|
2434
2609
|
pdffile = tempfile.NamedTemporaryFile(suffix=".pdf", delete=False)
|
|
2435
2610
|
subprocess.run(
|
|
2436
2611
|
["dot", "-Tpdf"],
|
|
2437
|
-
stdin=cast(Any,
|
|
2612
|
+
stdin=cast(Any, dot_stream),
|
|
2438
2613
|
stdout=pdffile,
|
|
2439
2614
|
check=True,
|
|
2440
2615
|
)
|
|
2441
2616
|
|
|
2442
2617
|
# open the PDF file in browser (hopefully portable), then cleanup
|
|
2443
2618
|
webbrowser.open(f"file://{pdffile.name}")
|
|
2444
|
-
else:
|
|
2445
2619
|
if filename is None or isinstance(filename, str):
|
|
2446
|
-
|
|
2620
|
+
dot_stream.close()
|
|
2447
2621
|
|
|
2448
2622
|
|
|
2449
2623
|
class ImageBlobsMixin:
|
|
@@ -631,6 +631,9 @@ class VideoCamera(ImageSource):
|
|
|
631
631
|
self.rgb = rgb
|
|
632
632
|
self.i = 0
|
|
633
633
|
|
|
634
|
+
def __len__(self) -> int:
|
|
635
|
+
raise TypeError("VideoCamera is a live stream and has no defined length")
|
|
636
|
+
|
|
634
637
|
def __iter__(self) -> VideoCamera:
|
|
635
638
|
self.i = 0
|
|
636
639
|
self.cap.release()
|
|
@@ -1749,6 +1752,9 @@ class WebCam(ImageSource):
|
|
|
1749
1752
|
self.args = kwargs
|
|
1750
1753
|
self.cap = None
|
|
1751
1754
|
|
|
1755
|
+
def __len__(self) -> int:
|
|
1756
|
+
raise TypeError("WebCam is a live stream and has no defined length")
|
|
1757
|
+
|
|
1752
1758
|
def __iter__(self) -> WebCam:
|
|
1753
1759
|
if self.cap is not None:
|
|
1754
1760
|
self.cap.release()
|
|
@@ -1851,7 +1857,7 @@ class EarthView(ImageSource):
|
|
|
1851
1857
|
|
|
1852
1858
|
.. note::
|
|
1853
1859
|
- If the key is not passed in, a value is sought from the
|
|
1854
|
-
environment variable ``
|
|
1860
|
+
environment variable ``GOOGLE_API_KEY``.
|
|
1855
1861
|
- Uses the `Google Maps Static API <https://developers.google.com/maps/documentation/maps-static/start>`_
|
|
1856
1862
|
|
|
1857
1863
|
:references:
|
|
@@ -1878,7 +1884,7 @@ class EarthView(ImageSource):
|
|
|
1878
1884
|
) -> None:
|
|
1879
1885
|
|
|
1880
1886
|
if key is None:
|
|
1881
|
-
self.key = os.getenv("
|
|
1887
|
+
self.key = os.getenv("GOOGLE_API_KEY")
|
|
1882
1888
|
else:
|
|
1883
1889
|
self.key = key
|
|
1884
1890
|
|
|
@@ -1888,6 +1894,16 @@ class EarthView(ImageSource):
|
|
|
1888
1894
|
self.shape = shape
|
|
1889
1895
|
self.args = kwargs
|
|
1890
1896
|
|
|
1897
|
+
def __len__(self) -> int:
|
|
1898
|
+
raise TypeError(
|
|
1899
|
+
"EarthView is an on-demand image service and has no defined length"
|
|
1900
|
+
)
|
|
1901
|
+
|
|
1902
|
+
def __iter__(self) -> Iterator:
|
|
1903
|
+
raise TypeError(
|
|
1904
|
+
"EarthView is not iterable; use grab() to retrieve individual images"
|
|
1905
|
+
)
|
|
1906
|
+
|
|
1891
1907
|
def grab(
|
|
1892
1908
|
self,
|
|
1893
1909
|
lat: float,
|
|
@@ -1946,7 +1962,7 @@ class EarthView(ImageSource):
|
|
|
1946
1962
|
# https://developers.google.com/maps/documentation/maps-static/start#URL_Parameters
|
|
1947
1963
|
|
|
1948
1964
|
# now read the map
|
|
1949
|
-
url = f"https://maps.googleapis.com/maps/api/staticmap?center={lat},{lon}&zoom={zoom}&size={shape[0]}x{shape[1]}&scale={scale}&format=png&maptype={type}&key={self.key}
|
|
1965
|
+
url = f"https://maps.googleapis.com/maps/api/staticmap?center={lat},{lon}&zoom={zoom}&size={shape[0]}x{shape[1]}&scale={scale}&format=png&maptype={type}&key={self.key}"
|
|
1950
1966
|
|
|
1951
1967
|
opturl = []
|
|
1952
1968
|
|
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/CODEAUTOLINK_FORK_PLAN.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/OPENCV_FUNCTIONS.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/deprecation_warnings.csv
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/README.md
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/blobs1.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/blobs2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/corners.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/matching.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/monalisa.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/morphdemo.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/randomdots.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/ransac_line.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/ros_stream.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/showzip.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/street_scene.jpg
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/torch-yolo.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/torch_seg.py
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/examples/yolo26n.pt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/machinevisiontoolbox.pdf
RENAMED
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/plot_call_inventory.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/symbolic/README.md
RENAMED
|
File without changes
|
{machinevision_toolbox_python-2.0.0 → machinevision_toolbox_python-2.0.1}/symbolic/bundle-adjust.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|