diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 193c7529..78ee4f94 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -108,7 +108,7 @@ jobs: new_lines = [] changed = False for line in lines: - if line.strip() == "%matplotlib ipympl": + if line.strip() in ("%matplotlib ipympl", "%matplotlib widget"): newline = "\n" if line.endswith("\n") else "" new_lines.append(f"%matplotlib inline{newline}") changed = True diff --git a/docs/lite/jupyter-lite.json b/docs/lite/jupyter-lite.json index a357bb21..8a633d47 100644 --- a/docs/lite/jupyter-lite.json +++ b/docs/lite/jupyter-lite.json @@ -1,6 +1,6 @@ { "jupyter-lite-schema-version": 0, "jupyter-config-data": { - "appUrl": "./lab/index.html?path=files/index.ipynb" + "appUrl": "./lab/index.html?path=index.ipynb" } } \ No newline at end of file diff --git a/docs/notebooks/IBVS.ipynb b/docs/notebooks/IBVS.ipynb index 89de1890..a080bc17 100644 --- a/docs/notebooks/IBVS.ipynb +++ b/docs/notebooks/IBVS.ipynb @@ -27,6 +27,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -35,14 +128,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - " \n", "import numpy as np\n", "import math\n", "\n", diff --git a/docs/notebooks/_mvtb_nb_bootstrap.py b/docs/notebooks/_mvtb_nb_bootstrap.py index a4170470..6eb31f55 100644 --- a/docs/notebooks/_mvtb_nb_bootstrap.py +++ b/docs/notebooks/_mvtb_nb_bootstrap.py @@ -31,14 +31,17 @@ async def ensure_installed() -> bool: "mvtb-data", "tqdm", "requests", + "ipywidgets", ] ) import cv2 # noqa: F401 - force cv2 into module registry before toolbox import wheels = sorted(Path("/pypi").glob("machinevision_toolbox_python-*.whl")) if wheels: - # Prefer the wheel bundled with this JupyterLite site. - await micropip.install(wheels[-1].as_posix(), deps=False) + # Prefer the wheel bundled with this JupyterLite site. Relative, + # not absolute: a leading slash resolves against the origin, not + # this site's own base URL (a GitHub Pages project subpath). + await micropip.install(f"pypi/{wheels[-1].name}", deps=False) else: # Fall back to PyPI when running outside the published site layout. await micropip.install("machinevision-toolbox-python", deps=False) @@ -63,8 +66,11 @@ async def ensure_installed() -> bool: ) where, colab = "on Colab", True + import cv2 + import machinevisiontoolbox version = getattr(machinevisiontoolbox, "__version__", "unknown") - print(f"Running {where} using MVTB v{version}") + opencv_version = getattr(cv2, "__version__", "unknown") + print(f"Running {where} using MVTB v{version} with OpenCV {opencv_version}") return colab diff --git a/docs/notebooks/calibration.ipynb b/docs/notebooks/calibration.ipynb index f0b406d0..5fa94f99 100644 --- a/docs/notebooks/calibration.ipynb +++ b/docs/notebooks/calibration.ipynb @@ -18,18 +18,103 @@ }, { "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "execution_count": null, - "metadata": {}, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "from machinevisiontoolbox import *\n", "import numpy as np\n", "np.set_printoptions(linewidth=120, formatter={'float': lambda x: f\"{x:8.4g}\" if abs(x) > 1e-10 else f\"{0:8.4g}\"})" diff --git a/docs/notebooks/camera.ipynb b/docs/notebooks/camera.ipynb index b9c0dbdb..dbec864c 100644 --- a/docs/notebooks/camera.ipynb +++ b/docs/notebooks/camera.ipynb @@ -29,6 +29,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -37,14 +130,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - " \n", "%matplotlib inline\n", "\n", "import numpy as np\n", diff --git a/docs/notebooks/camera_animation.ipynb b/docs/notebooks/camera_animation.ipynb index b1615af8..6a730926 100644 --- a/docs/notebooks/camera_animation.ipynb +++ b/docs/notebooks/camera_animation.ipynb @@ -25,6 +25,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/notebooks/color-images.ipynb b/docs/notebooks/color-images.ipynb index 6556ccde..d4b84cbd 100644 --- a/docs/notebooks/color-images.ipynb +++ b/docs/notebooks/color-images.ipynb @@ -27,18 +27,103 @@ }, { "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "execution_count": null, - "metadata": {}, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "%matplotlib widget\n", "import matplotlib.pyplot as plt\n", "\n", diff --git a/docs/notebooks/exploring-images.ipynb b/docs/notebooks/exploring-images.ipynb index d4853821..f41811a1 100644 --- a/docs/notebooks/exploring-images.ipynb +++ b/docs/notebooks/exploring-images.ipynb @@ -23,6 +23,99 @@ "Set matplotlib for interactive display within the notebook, then import the `Image` object from the Machine Vision Toolbox." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/notebooks/fiducials.ipynb b/docs/notebooks/fiducials.ipynb index 6e6a1cb1..9f3eaccf 100644 --- a/docs/notebooks/fiducials.ipynb +++ b/docs/notebooks/fiducials.ipynb @@ -29,6 +29,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -37,14 +130,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - "\n", "%matplotlib ipympl\n", "\n", "import numpy as np\n", @@ -98,7 +183,7 @@ "- the focal length, in this case 4.25mm\n", "- the image size\n", "- the principal point, where the optical axis passes through the image plane\n", - "- the pixel size, in this case 1.4Ξm\n", + "- the pixel size, in this case 1.4\u03bcm\n", "\n", "From the camera model we can derive the intrinsic parameter matrix" ] diff --git a/docs/notebooks/finding-blobs.ipynb b/docs/notebooks/finding-blobs.ipynb index 5beab15f..640dd381 100644 --- a/docs/notebooks/finding-blobs.ipynb +++ b/docs/notebooks/finding-blobs.ipynb @@ -29,6 +29,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -37,14 +130,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print(\"Running on CoLab\")\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - "\n", "%matplotlib ipympl\n", "import matplotlib.pyplot as plt\n", "import matplotlib\n", diff --git a/docs/notebooks/gamma.ipynb b/docs/notebooks/gamma.ipynb index 467c4940..440c14c8 100644 --- a/docs/notebooks/gamma.ipynb +++ b/docs/notebooks/gamma.ipynb @@ -27,18 +27,103 @@ }, { "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "execution_count": null, - "metadata": {}, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "%matplotlib widget\n", "import matplotlib.pyplot as plt\n", "\n", diff --git a/docs/notebooks/greyscale-images.ipynb b/docs/notebooks/greyscale-images.ipynb index 12b4a974..616a4d32 100644 --- a/docs/notebooks/greyscale-images.ipynb +++ b/docs/notebooks/greyscale-images.ipynb @@ -25,20 +25,105 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - "\n", "%matplotlib widget\n", "import matplotlib.pyplot as plt\n", "\n", @@ -50,8 +135,7 @@ "if COLAB:\n", " %config ZMQInteractiveShell.ast_node_interactivity = 'last_expr_or_assign'\n", "# make NumPy display a bit nicer\n", - "np.set_printoptions(linewidth=100, formatter={'float': lambda x: f\"{x:10.4g}\" if abs(x) > 1e-10 else f\"{0:10.4g}\"})\n", - "\n" + "np.set_printoptions(linewidth=100, formatter={'float': lambda x: f\"{x:10.4g}\" if abs(x) > 1e-10 else f\"{0:10.4g}\"})\n" ] }, { diff --git a/docs/notebooks/homogeneous-coords.ipynb b/docs/notebooks/homogeneous-coords.ipynb index 99e905cb..1bb3cee3 100644 --- a/docs/notebooks/homogeneous-coords.ipynb +++ b/docs/notebooks/homogeneous-coords.ipynb @@ -16,6 +16,99 @@ "Robotics, Vision & Control: Python, see Excurse 2.7, Appendix C.2" ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -228,7 +321,7 @@ "@widgets.interact\n", "def animate( x = widgets.FloatSlider(value=2, description='x:', min=-4, max=4),\n", " y = widgets.FloatSlider(value=3, description='y:', min=-4, max=4),\n", - " lam = widgets.FloatSlider(value=1, description='𝜆', min=0.2, max=5)):\n", + " lam = widgets.FloatSlider(value=1, description='\ud835\udf06', min=0.2, max=5)):\n", " \n", " # Update the quiver (arrow)\n", " global quiver, scatter\n", diff --git a/docs/notebooks/homography.ipynb b/docs/notebooks/homography.ipynb index 9f25ff62..b47aa12b 100644 --- a/docs/notebooks/homography.ipynb +++ b/docs/notebooks/homography.ipynb @@ -29,6 +29,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -37,14 +130,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - " \n", "%matplotlib ipympl\n", "\n", "import numpy as np\n", diff --git a/docs/notebooks/image-convolution.ipynb b/docs/notebooks/image-convolution.ipynb index 12fe757a..2fb5d8f9 100644 --- a/docs/notebooks/image-convolution.ipynb +++ b/docs/notebooks/image-convolution.ipynb @@ -27,18 +27,103 @@ }, { "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "execution_count": null, - "metadata": {}, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "%matplotlib widget\n", "import matplotlib.pyplot as plt\n", "\n", diff --git a/docs/notebooks/image-features.ipynb b/docs/notebooks/image-features.ipynb index 3f175601..eccfce32 100644 --- a/docs/notebooks/image-features.ipynb +++ b/docs/notebooks/image-features.ipynb @@ -29,6 +29,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -37,14 +130,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - "\n", "%matplotlib ipympl\n", "import matplotlib.pyplot as plt\n", "import matplotlib\n", diff --git a/docs/notebooks/image-motion.ipynb b/docs/notebooks/image-motion.ipynb index 36518192..f51598e5 100644 --- a/docs/notebooks/image-motion.ipynb +++ b/docs/notebooks/image-motion.ipynb @@ -27,6 +27,99 @@ "If you're running locally you need to have these packages installed. If you're running on CoLab we have to first install machinevisiontoolbox which is not preinstalled, this will be a bit slow." ] }, + { + "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "execution_count": null, + "outputs": [], + "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -35,14 +128,6 @@ }, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", - "\n", "import numpy as np\n", "from machinevisiontoolbox import CentralCamera\n", "from spatialmath import SE3\n", @@ -165,7 +250,7 @@ "id": "y8NBvdhAk5E9" }, "source": [ - "which is an approximation to the partial derivative $\\partial p / \\partial x$. It shows that 1 m of camera motion would lead to −160 pixel of feature motion in the u-direction. \n", + "which is an approximation to the partial derivative $\\partial p / \\partial x$. It shows that 1 m of camera motion would lead to \u2212160 pixel of feature motion in the u-direction. \n", "\n", "We can repeat this for z-axis translation, ie. moving the camera forward\n" ] diff --git a/docs/notebooks/image-processing.ipynb b/docs/notebooks/image-processing.ipynb index f8e2a7ff..753c95d0 100644 --- a/docs/notebooks/image-processing.ipynb +++ b/docs/notebooks/image-processing.ipynb @@ -27,18 +27,103 @@ }, { "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "execution_count": null, - "metadata": {}, "outputs": [], "source": [ - "try:\n", - " import google.colab\n", - " print('Running on CoLab')\n", - " %pip install machinevision-toolbox-python\n", - " COLAB = True\n", - "except:\n", - " COLAB = False\n", + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", + "import sys\n", + "from pathlib import Path\n", + "\n", + "\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", + "\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", + " )\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", + "\n", + "COLAB = await ensure_installed()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "%matplotlib widget\n", "import matplotlib.pyplot as plt\n", "\n", diff --git a/docs/lite/files/index.ipynb b/docs/notebooks/index.ipynb similarity index 100% rename from docs/lite/files/index.ipynb rename to docs/notebooks/index.ipynb diff --git a/docs/lite/files/intro.ipynb b/docs/notebooks/intro.ipynb similarity index 53% rename from docs/lite/files/intro.ipynb rename to docs/notebooks/intro.ipynb index 1864ed9f..f38007a4 100644 --- a/docs/lite/files/intro.ipynb +++ b/docs/notebooks/intro.ipynb @@ -4,51 +4,99 @@ "cell_type": "markdown", "id": "0f90fd53", "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
Machine Vision Toolbox for Python — Interactive Demo
\n", - "\n", - "This notebook runs entirely in your browser using [JupyterLite](https://jupyterlite.readthedocs.io) and [Pyodide](https://pyodide.org).\n", - "No installation required. The cell below installs the toolbox the first time it is run (and will take a few seconds)." - ] + "source": "\n \n \n \n \n
Machine Vision Toolbox for Python \u2014 Interactive Demo
\n\nA quick, runnable introduction to the toolbox. Works locally, on Google Colab, or entirely in your browser via [JupyterLite](https://jupyterlite.readthedocs.io) and [Pyodide](https://pyodide.org) -- no installation required either way. The cell below installs the toolbox the first time it is run (and will take a few seconds on Colab or in the browser)." }, { "cell_type": "code", + "id": "mvtb-bootstrap-cell", + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "execution_count": null, - "id": "c663dd60", - "metadata": {}, "outputs": [], "source": [ + "# MVTB_BOOTSTRAP_CELL -- sets up the environment (Colab / JupyterLite / local install); click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by sync_bootstrap.py -- do not hand-edit.\n", + "\n", + "\"\"\"Environment bootstrap for machinevision-toolbox-python's Jupyter notebooks.\n", + "\n", + "Installs the toolbox (and reports how) across the three environments a notebook in\n", + "this folder might run in: a local Jupyter/VS Code install, Google Colab, and\n", + "JupyterLite (Pyodide/WASM, in-browser).\n", + "\n", + "This file is the single source of truth for that logic. Every notebook's own\n", + "bootstrap cell is a generated copy of this file's content, produced by\n", + "sync_bootstrap.py -- see docs/notebooks/README.md for the full explanation.\n", + "\"\"\"\n", + "\n", + "import subprocess\n", "import sys\n", + "from pathlib import Path\n", "\n", - "if sys.platform == \"emscripten\":\n", - " import micropip\n", "\n", - " await micropip.install([\n", - " \"opencv-python\",\n", - " \"spatialmath-python\",\n", - " \"pgraph-python\",\n", - " \"ansitable\",\n", - " \"mvtb-data\",\n", - " ])\n", + "async def ensure_installed() -> bool:\n", + " \"\"\"Install machinevision-toolbox-python if needed, and report the environment.\n", "\n", - " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + " :returns: True if running on Google Colab, False otherwise.\n", + " \"\"\"\n", + " if sys.platform == \"emscripten\":\n", + " import micropip\n", "\n", - " # Prefer the wheel bundled with this JupyterLite site.\n", - " # Fall back to PyPI when running outside the published site layout.\n", - " try:\n", " await micropip.install(\n", - " \"/pypi/machinevision_toolbox_python-2.0.0-py3-none-any.whl\",\n", - " deps=False,\n", + " [\n", + " \"opencv-python\",\n", + " \"spatialmath-python\",\n", + " \"pgraph-python\",\n", + " \"ansitable\",\n", + " \"mvtb-data\",\n", + " \"tqdm\",\n", + " \"requests\",\n", + " \"ipywidgets\",\n", + " ]\n", " )\n", - " except Exception:\n", - " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " import cv2 # noqa: F401 - force cv2 into module registry before toolbox import\n", + "\n", + " wheels = sorted(Path(\"/pypi\").glob(\"machinevision_toolbox_python-*.whl\"))\n", + " if wheels:\n", + " # Prefer the wheel bundled with this JupyterLite site. Relative,\n", + " # not absolute: a leading slash resolves against the origin, not\n", + " # this site's own base URL (a GitHub Pages project subpath).\n", + " await micropip.install(f\"pypi/{wheels[-1].name}\", deps=False)\n", + " else:\n", + " # Fall back to PyPI when running outside the published site layout.\n", + " await micropip.install(\"machinevision-toolbox-python\", deps=False)\n", + " where, colab = \"in browser\", False\n", + " else:\n", + " try:\n", + " import google.colab # noqa: F401\n", + " except ImportError:\n", + " where, colab = \"locally\", False\n", + " else:\n", + " print(\"Installing machinevision-toolbox-python...\")\n", + " subprocess.run(\n", + " [\n", + " sys.executable,\n", + " \"-m\",\n", + " \"pip\",\n", + " \"install\",\n", + " \"-q\",\n", + " \"machinevision-toolbox-python\",\n", + " ],\n", + " check=True,\n", + " )\n", + " where, colab = \"on Colab\", True\n", + "\n", + " import cv2\n", + "\n", + " import machinevisiontoolbox\n", + "\n", + " version = getattr(machinevisiontoolbox, \"__version__\", \"unknown\")\n", + " opencv_version = getattr(cv2, \"__version__\", \"unknown\")\n", + " print(f\"Running {where} using MVTB v{version} with OpenCV {opencv_version}\")\n", + " return colab\n", "\n", - "print(\"Ready.\")\n" + "COLAB = await ensure_installed()\n" ] }, { @@ -164,7 +212,7 @@ "source": [ "## Colour planes\n", "\n", - "Access individual colour planes by name — the toolbox tracks the colour order so\n", + "Access individual colour planes by name \u2014 the toolbox tracks the colour order so\n", "you never need to worry about BGR vs RGB." ] }, diff --git a/docs/notebooks/sync_bootstrap.py b/docs/notebooks/sync_bootstrap.py index cce8ff26..b209ab96 100644 --- a/docs/notebooks/sync_bootstrap.py +++ b/docs/notebooks/sync_bootstrap.py @@ -21,9 +21,14 @@ MARKER = "# MVTB_BOOTSTRAP_CELL" GENERATED_HEADER = ( - f"{MARKER} - generated from docs/notebooks/_mvtb_nb_bootstrap.py " - "by sync_bootstrap.py; do not hand-edit\n" + f"{MARKER} -- sets up the environment (Colab / JupyterLite / local install); " + "click to expand. Generated from docs/notebooks/_mvtb_nb_bootstrap.py by " + "sync_bootstrap.py -- do not hand-edit.\n" ) +# Folds the cell's code by default (VS Code and JupyterLab both honour this) -- +# a reader sees the one-line header above and the printed status line below, +# not the boilerplate, unless they choose to expand it. +FOLDED_METADATA = {"jupyter": {"source_hidden": True}} HERE = Path(__file__).resolve().parent TEMPLATE_PATH = HERE / "_mvtb_nb_bootstrap.py" @@ -62,15 +67,19 @@ def process_notebook(path: Path, template: str, fix: bool) -> bool: if not is_bootstrap_cell(cell): continue - desired = generated_source(template) - current = cell.get("source", []) - if not isinstance(current, list): - current = [current] + desired_source = generated_source(template) + current_source = cell.get("source", []) + if not isinstance(current_source, list): + current_source = [current_source] - if current != desired: + current_jupyter_metadata = cell.get("metadata", {}).get("jupyter", {}) + desired_jupyter_metadata = FOLDED_METADATA["jupyter"] + + if current_source != desired_source or current_jupyter_metadata != desired_jupyter_metadata: changed = True if fix: - cell["source"] = desired + cell["source"] = desired_source + cell.setdefault("metadata", {})["jupyter"] = dict(desired_jupyter_metadata) break if changed and fix: diff --git a/docs/source/jupyter-notebooks.rst b/docs/source/jupyter-notebooks.rst index dc2da7aa..3d09ec82 100644 --- a/docs/source/jupyter-notebooks.rst +++ b/docs/source/jupyter-notebooks.rst @@ -122,7 +122,7 @@ Quick Start :widths: 28, 16, 16, 40 "Notebook", "|jupyterlite_image|", "|colab_image|", "Description" - "`Introduction `_", "`open `_", "`open `_", "A quick introduction to the toolbox." + "`Introduction `_", "`open `_", "`open `_", "A quick introduction to the toolbox." Image Fundamentals ~~~~~~~~~~~~~~~~~~