Skip to content

Commit e79138d

Browse files
committed
sphinx doco cleanup
1 parent 2ec8851 commit e79138d

6 files changed

Lines changed: 181 additions & 59 deletions

File tree

docs/source/_templates/autosummary/class.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
{% block attributes %}
1919
{% if attributes %}
20-
.. rubric:: {{ _('Attributes') }}
20+
.. rubric:: {{ _('Properties') }}
2121

2222
.. autosummary::
2323
{% for item in attributes | sort(case_sensitive=False) %}

docs/source/conf.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#
1313
import os
1414
import sys
15+
import inspect
16+
import importlib
1517
from pathlib import Path
1618
from importlib.metadata import version as _pkg_version
1719

@@ -44,6 +46,7 @@
4446
extensions = [
4547
"sphinx.ext.autodoc",
4648
"sphinx.ext.autosummary",
49+
"sphinx.ext.linkcode",
4750
"sphinx.ext.todo",
4851
"sphinx.ext.viewcode",
4952
"sphinx.ext.mathjax",
@@ -61,7 +64,7 @@
6164
"blockname",
6265
]
6366

64-
# autoclass_content = 'both' # use __init__ or class docstring
67+
autoclass_content = "both" # use __init__ or class docstring
6568
add_function_parentheses = False
6669

6770
# -- sphinx-autorun setup ----------------------------------------------------
@@ -132,6 +135,60 @@
132135
}
133136
html_show_sourcelink = True
134137

138+
139+
# -- Source code links -------------------------------------------------------
140+
_REPO_ROOT = Path(__file__).resolve().parents[2]
141+
142+
143+
def linkcode_resolve(domain, info):
144+
"""Return GitHub source links for Python API objects."""
145+
if domain != "py":
146+
return None
147+
148+
module_name = info.get("module")
149+
fullname = info.get("fullname")
150+
if not module_name or not fullname:
151+
return None
152+
153+
try:
154+
module = importlib.import_module(module_name)
155+
except Exception:
156+
return None
157+
158+
obj = module
159+
for part in fullname.split("."):
160+
try:
161+
obj = getattr(obj, part)
162+
except Exception:
163+
return None
164+
165+
# Use underlying function for decorated descriptors.
166+
if isinstance(obj, property):
167+
obj = obj.fget
168+
169+
try:
170+
obj = inspect.unwrap(obj)
171+
except Exception:
172+
pass
173+
174+
try:
175+
source_file = Path(inspect.getsourcefile(obj)).resolve()
176+
source_lines, start_line = inspect.getsourcelines(obj)
177+
except Exception:
178+
return None
179+
180+
try:
181+
rel_path = source_file.relative_to(_REPO_ROOT).as_posix()
182+
except ValueError:
183+
return None
184+
185+
end_line = start_line + len(source_lines) - 1
186+
return (
187+
"https://github.com/petercorke/machinevision-toolbox-python/"
188+
f"blob/main/{rel_path}#L{start_line}-L{end_line}"
189+
)
190+
191+
135192
# -- sphinx-copybutton setup -------------------------------------------------
136193
# Strip interactive prompts (Python and shell) when users copy code snippets.
137194
copybutton_prompt_text = r">>> |\.\.\. |\$ "

docs/source/image_class.rst

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Describe the attributes of an :class:`~machinevisiontoolbox.ImageCore.Image`.
4545
~npixels
4646
~size
4747
~width
48+
~nplanes
4849

4950
Predicates
5051
^^^^^^^^^^
@@ -61,6 +62,30 @@ Test attributes of an ``Image``.
6162
~isint
6263
~isrgb
6364

65+
Color planes and channels
66+
^^^^^^^^^^^^^^^^^^^^^^^^^
67+
68+
Return information about the color planes of an ``Image`` instance.
69+
70+
.. autosummary::
71+
:nosignatures:
72+
:show-private:
73+
74+
~nplanes
75+
~iscolor
76+
~__mod__
77+
~Pstack
78+
~blue
79+
~green
80+
~plane
81+
~red
82+
~colordict
83+
~colordict2list
84+
~colordict2str
85+
~colororder
86+
~colororder2dict
87+
~colororder_str
88+
6489
Image coordinates
6590
^^^^^^^^^^^^^^^^^
6691

@@ -94,7 +119,7 @@ Return ``Image`` pixel data as a NumPy array.
94119
~to_int
95120
~view1d
96121

97-
Getting and setting pixels
122+
Getting pixels
98123
^^^^^^^^^^^^^^^^^^^^^^^^^^^
99124

100125
Access individual pixels or groups of pixels.
@@ -145,22 +170,6 @@ Extract sub-images or planes from an ``Image`` instance.
145170
~red
146171
~roi
147172

148-
Color info
149-
^^^^^^^^^^
150-
151-
Return information about the color planes of an ``Image`` instance.
152-
153-
.. autosummary::
154-
:nosignatures:
155-
156-
~colordict
157-
~colordict2list
158-
~colordict2str
159-
~colororder
160-
~colororder2dict
161-
~colororder_str
162-
~nplanes
163-
164173
Color space and gamma
165174
^^^^^^^^^^^^^^^^^^^^^
166175

docs/source/index.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
Machine Vision Toolbox for Python
77
=================================
88

9-
An object-oriented wrapper for `OpenCV <https://opencv.org>`_ and `Open3D <https://open3d.org>`_ that supports a suite of useful image
10-
processing operations from reading and display through to blob and point feature
11-
extraction.
9+
A unified, object-oriented Python API that bridges the gap between raw pixels and
10+
high-level spatial reasoning by harmonizing a 'best-of-breed' foundation of NumPy,
11+
OpenCV, and Open3D.
1212

1313
.. toctree::
1414
:maxdepth: 2
1515

1616
intro
1717
package
18+
installation
1819
cmdline-tools
1920
jupyter-notebooks
2021
ros

docs/source/intro.rst

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,18 @@ Introduction
55
Rationale
66
=========
77

8-
The goal of this package is to simplify the expression of computer vision algorithms in
9-
Python. Images can be represented as 2D or 3D arrays which are the domain of `NumPy
10-
<https://numpy.org>`_ but many powerful image and point cloud specific operations are
11-
provided by other popular packages such as `OpenCV <https://opencv.org>`_, `Pillow <https://pillow.readthedocs.io/en/stable/>`_,
12-
`SciPy <https://scipy.org>`_, `scikit-image <https://scikit-image.org>`_, and `Open3D <open3d.org>`_.
13-
OpenCV does an adequate job of displaying images but is nowhere nearly as powerful
14-
`matplotlib <https://matplotlib.org>`_ which can display a wide range of 2D graphics,
15-
but for 3D graphics Open3D is the go-to.
16-
17-
In practice, using these various packages together, to exploit their individual strengths,
18-
is complex -- each have their own way of working, similar options are accessed
19-
differently and some function require image pixels to have particular types. None of
20-
them consider the image as an object with a set of useful image and vision processing
21-
methods and operators.
8+
The Machine Vision Toolbox (MVTB) brings professional-grade vision algorithms to your
9+
fingertips with a Pythonic API. Built on a "best-of-breed" foundation—NumPy, SciPy,
10+
OpenCV, and Open3D —- it bridges the gap between raw pixel manipulation and high-level
11+
spatial reasoning.
12+
13+
While the Python ecosystem offers powerful individual tools, using them in concert is
14+
often complex. Libraries like OpenCV, scikit-image and Open3D provide excellent algorithms, but
15+
they frequently differ in API style, coordinate conventions, and expected data types.
16+
MVTB unifies these capabilities into a consistent, object-oriented framework. By
17+
treating images and cameras as first-class objects rather than just raw arrays, the
18+
Toolbox allows you to focus on the geometry and logic of your vision system rather than
19+
the boilerplate of library integration.
2220

2321
For example, to read an image using OpenCV, smooth it, and display it is::
2422

@@ -271,7 +269,7 @@ belongs to
271269
.. code-block:: python
272270
273271
out = f.labelImage(im)
274-
out.stats()
272+
out.stats
275273
out.disp(block=True, colormap="jet", cbar=True, vrange=[0,len(f)-1])
276274
277275
and request the blob label image which we then display

src/machinevisiontoolbox/ImageBlobs.py

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -128,51 +128,90 @@ def __init__(
128128
The list can be indexed, sliced or used as an iterator in a for loop
129129
or comprehension, for example:
130130
131-
.. code-block:: python
131+
.. code-block:: python
132132
133-
for blob in blobs:
134-
# do a thing
135-
areas = [blob.area for blob in blobs]
133+
for blob in blobs:
134+
# do a thing
135+
136+
areas = [blob.area for blob in blobs]
136137
137138
138139
However the last line can also be written as:
139140
140-
.. code-block:: python
141+
.. code-block:: python
141142
142-
areas = blobs.area
143+
areas = blobs.area
143144
144145
145146
since all methods return a scalar if applied to a single blob:
146147
147-
.. code-block:: python
148+
.. code-block:: python
148149
149-
blobs[1].area
150+
blobs[1].area
150151
151152
152153
or a list if applied to multiple blobs:
153154
154-
.. code-block:: python
155+
.. code-block:: python
155156
156-
blobs.area
157+
blobs.area
157158
158159
159160
A blob has many attributes:
160161
162+
Geometric attributes
163+
161164
.. list-table::
162165
:header-rows: 1
166+
:widths: 30 70
163167
164-
* - Attribute
168+
* - Property
165169
- Description
166170
* - :meth:`area`
167171
- The area of the blob.
168-
* - :meth:`u`, :meth:`v`
169-
- The centroid (center of mass) of the blob.
170172
* - :meth:`bbox`
171173
- The bounding box of the blob.
172-
* - :meth:`color`
173-
- The value of pixels within the blob.
174+
* - :meth:`umin`, :meth:`umax`
175+
- The horizontal extent of the bounding box.
176+
* - :meth:`vmin`, :meth:`vmax`
177+
- The vertical extent of the bounding box.
174178
* - :meth:`touch`
175-
- True if the blob touches the border.
179+
- True if the blob touches the border of the image.
180+
* - :meth:`fillfactor`
181+
- Ratio of blob area to bounding box area.
182+
* - :meth:`bboxarea`
183+
- Area of the bounding box.
184+
185+
186+
Moment attributes
187+
188+
.. list-table::
189+
:header-rows: 1
190+
:widths: 30 70
191+
192+
* - Property
193+
- Description
194+
* - :meth:`u`, :meth:`v`
195+
- The centroid (center of mass) of the blob.
196+
* - :meth:`orientation`
197+
- Orientation of the equivalent ellipse.
198+
* - :meth:`a, b`
199+
- The equivalent ellipse radii.
200+
* - :meth:`aligned_box`
201+
- A rotated bounding box with sides parallel to the axes of the equivalent ellipse.
202+
* - :meth:`moments`
203+
- The moments of the blob including central and normalised values up to 3rd order.
204+
* - :meth:`humoments`
205+
- Seven Hu moment invariants (invariant to position, orientation and scale).
206+
207+
Boundary and shape attributes
208+
209+
.. list-table::
210+
:header-rows: 1
211+
:widths: 30 70
212+
213+
* - Property
214+
- Description
176215
* - :meth:`contour_point`
177216
- A point on the contour of the blob.
178217
* - :meth:`perimeter`
@@ -181,18 +220,34 @@ def __init__(
181220
- The perimeter length of the blob.
182221
* - :meth:`circularity`
183222
- The circularity of the blob.
184-
* - :meth:`moments`
185-
- The moments of the blob including central, normalized upto 3rd order.
186-
* - :meth:`orientation`
187-
- Orientation of the equivalent ellipse.
188-
* - :meth:`a, b`
189-
- The equivalent ellipse radii.
223+
* - :meth:`perimeter_approx`
224+
- A polygonal approximation to the perimeter.
225+
* - :meth:`perimeter_hull`
226+
- The convex hull of the perimeter.
227+
* - :meth:`MEC`
228+
- The minimum enclosing circle.
229+
* - :meth:`MER`
230+
- The minimum enclosing rectangle.
231+
232+
233+
Hierarchy and region attributes
234+
235+
.. list-table::
236+
:header-rows: 1
237+
:widths: 30 70
238+
239+
* - Property
240+
- Description
241+
* - :meth:`color`
242+
- The value of pixels within the blob.
190243
* - :meth:`children`
191244
- A list of references to child :class:`Blob` instances.
192245
* - :meth:`parent`
193246
- A reference to the parent :class:`Blob` instance, or None if no parent.
194247
* - :meth:`level`
195248
- The depth of the blob in the region tree.
249+
* - :meth:`dotfile`
250+
- Write a GraphViz dot file representing the blob hierarchy.
196251
197252
.. note:: ``findContours`` can give surprising results for small images:
198253
@@ -2319,6 +2374,8 @@ def blobs(self, **kwargs) -> Blobs:
23192374
23202375
:references:
23212376
- |RVC3|, Section 12.1.2.1.
2377+
2378+
:seealso: :class:`Blobs` :class:`Blob`
23222379
"""
23232380

23242381
# TODO do the feature extraction here

0 commit comments

Comments
 (0)