.. _changelog_v2_7_0: v2.7.0 ====== v2.7.0 modernizes the :mod:`sensor` auto-gain / auto-exposure / white-balance API to physical units (dB / microseconds), overhauls phase-correlation ``find_displacement()`` (adding rotation/scale), and adds ``get_similarity()`` (SSIM), ``chrominvar()`` / ``illuminvar()``, extra framebuffers, and an MQTT library. It is a large breaking release — read the breaking changes below. .. contents:: On this page :local: :depth: 1 Highlights ---------- - **Modern sensor API** — ``set_auto_gain()`` / ``set_auto_exposure()`` / ``set_auto_whitebal()`` now use dB / microseconds, with matching ``get_gain_db()`` / ``get_exposure_us()`` / ``get_rgb_gain_db()``. - **Phase correlation** — reworked ``find_displacement()`` with rotation / scale and ``find_rotscale()`` / ``linpolar()`` / ``logpolar()``. - **SSIM** — ``image.get_similarity()`` structural similarity. - **Extra framebuffers** — :func:`sensor.alloc_extra_fb` / ``dealloc_extra_fb()``. - **MQTT** — a new MQTT library. - **Breaking:** the sensor gain/exposure/whitebal API, ``find_displacement()`` / FFT framesizes, ``find_number()``, the WINC firmware tools, and AprilTag ``z_rotation()`` all changed — see the breaking changes. New features ------------ - **Sensor** — added :func:`sensor.get_gain_db`, :func:`sensor.get_exposure_us`, :func:`sensor.get_rgb_gain_db`, a ``gain_db_ceiling`` keyword on ``set_auto_gain()``, MT9V034 ``hmirror`` / ``vflip`` support, and :func:`sensor.alloc_extra_fb` / :func:`sensor.dealloc_extra_fb` for extra in-RAM framebuffers. - **Image** — added ``remove_shadows()``, ``min()`` / ``max()`` (frame differencing), ``get_similarity()`` (SSIM) with a structural-similarity example, ``chrominvar()`` / ``illuminvar()``, ``find_rotscale()``, ``linpolar()`` / ``logpolar()``, threshold / offset / invert keywords on the ``mean()`` / ``mode()`` / ``median()`` / ``midpoint()`` adaptive filters, ``len()`` / indexing on the keypoints object, and a ``.match()`` accessor on the keypoint-match object. - **Libraries / network** — added an MQTT library (with a WiFi MQTT example) and a ``network.WINC.MODE_BSP`` mode for programming WINC firmware over the debug UART. - **Examples** — added low-power ``deep_sleep.py`` / ``stop_mode.py``, advanced optical-flow, and linear/log-polar example scripts; the firmware now parses ``uart.ini`` on boot to enable a REPL UART. Other changes and improvements ------------------------------ - ``get_regression()`` gained ``area_threshold`` / ``pixels_threshold`` keywords and a faster robust regression (for line-following / racing); ``get_pixel()`` now supports Bayer images; added STM32H7 groundwork (CMSIS headers / HAL / bootloader — the H7 board is not yet usable); updated the bundled WINC1500 firmware (19.4.4 / 19.5.2). Bug fixes --------- Imaging: - Fixed the ``find_template()`` diamond-search out-of-bounds bug, ``logpolar`` / ``linpolar`` corruption, and ``illuminvar()`` going wild on near-zero color values. Sensor and system: - Fixed auto-gain-control bugs, restored the ``MAIN_FB`` size on ``snapshot()`` (so ``copy_to_fb`` at a different resolution, FB resize, and optical-flow pooling work again), the WINC ``gethostbyname`` timeout, the ``pydfu`` clear-status on the H7 bootloader, and low-power stop/standby modes. Hardware and board support -------------------------- - **STM32H7** — groundwork (CMSIS / HAL / bootloader); the OpenMV H7 board is not yet usable in this release. - **WINC1500** — updated bundled firmware. Breaking API changes -------------------- User-visible API breaks between v2.6.0 and v2.7.0. Scope: Python C-modules in ``modules/`` and Python libraries in ``scripts/libraries/``. Each change is tagged with its impact: - *major* — affects most scripts that used the feature; you will need to port code. - *minor* — narrow API; only affects scripts that used it. - *behavior* — same API, different results; re-check tuned scripts. Changes are grouped by impact in that order. If you just want to port your code, jump to the :ref:`migration checklist ` at the end. Each commit hash links to its diff on GitHub. .. _v2_7_0_autogain: :func:`sensor.set_auto_gain` reworked to dB *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.set_auto_gain` no longer accepts the integer ``value=`` keyword and no longer returns ``True`` / ``False``. Use ``sensor.set_auto_gain(False, gain_db=...)`` (a float dB value), read it back with the new :func:`sensor.get_gain_db`, and wrap the call in ``try`` / ``except`` since failure now raises ``ValueError``. *Commits:* `b906c5f19 `__ .. _v2_7_0_autoexposure: :func:`sensor.set_auto_exposure` reworked to microseconds *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.set_auto_exposure` no longer accepts the integer ``value=`` keyword and no longer returns ``True`` / ``False``. Use ``sensor.set_auto_exposure(False, exposure_us=...)``, read it back with the new :func:`sensor.get_exposure_us`, and handle the ``ValueError`` raised on failure. *Commits:* `7be0a7a18 `__ .. _v2_7_0_displacement: ``find_displacement()`` / FFT framesizes overhauled *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Phase-correlation was overhauled. ``image.find_displacement()`` now returns a displacement object (with ``x_translation()`` / ``y_translation()`` — formerly ``x_offset`` / ``y_offset`` — plus ``rotation()`` / ``scale()`` and new ``logpolar`` / ``fix_rotation_scale`` keywords); the separate rot-scale object was removed and ``find_rotscale()`` added. The FFT framesize constants were renamed/removed: ``sensor.B40x30`` was removed entirely, and ``sensor.B64x32`` / ``B64x64`` were renamed to uppercase ``sensor.B64X32`` / ``B64X64`` (with new ``B128X64`` / ``B128X128``). *Commits:* `c78f91b42 `__, `213396d09 `__ .. _v2_7_0_whitebal: :func:`sensor.set_auto_whitebal` reworked to dB *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.set_auto_whitebal` replaced its integer ``value=[r, g, b]`` keyword with ``rgb_gain_db=[r, g, b]`` (float dB) and now returns ``None`` (raising ``ValueError`` on failure) instead of ``True`` / ``False``. Use the new :func:`sensor.get_rgb_gain_db` to read the gains back. *Commits:* `30ecbdc4f `__ .. _v2_7_0_mirror: ``set_hmirror()`` / ``set_vflip()`` return ``None`` *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.set_hmirror` and :func:`sensor.set_vflip` now return ``None`` and raise ``ValueError`` on failure instead of returning a ``True`` / ``False`` status. Remove any code that branches on their return value. *Commits:* `aeb023804 `__ .. _v2_7_0_winc: WINC firmware tools require a file path *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :class:`network.WINC` firmware tooling changed: ``wlan.fw_dump()`` / ``wlan.fw_update()`` now take a mandatory firmware-file-path argument and the WINC is opened in a programming mode (``network.WINC(mode=...)``). Update no-argument calls to pass a path (e.g. ``wlan.fw_update("/winc_19_5_2.bin")``). *Commits:* `fcc3b0b9c `__ .. _v2_7_0_findnumber: ``image.find_number()`` requires a 28x28 ROI *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.find_number()`` (LeNet) now requires an exactly 28x28 ROI that fits inside the image and raises an error otherwise (instead of running on an arbitrary/full-image ROI). Pass an explicit ``roi=(x, y, 28, 28)``. *Commits:* `4d09a13f3 `__ .. _v2_7_0_zrotation: AprilTag ``z_rotation()`` sign flipped *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The AprilTag ``z_rotation()`` (and related ``rotation()``) now uses a right-handed coordinate convention, so the returned angle is negated versus prior releases. Scripts that depend on the old sign must invert the value or adjust their angle math. *Commits:* `7673aaf74 `__ .. _v2_7_0_migration: Migration checklist ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For a clean port to v2.7.0 the typical work is: #. Port ``set_auto_gain()`` to ``gain_db=`` + ``get_gain_db()`` and handle ``ValueError`` (:ref:`the auto-gain rework `). #. Port ``set_auto_exposure()`` to ``exposure_us=`` + ``get_exposure_us()`` (:ref:`the auto-exposure rework `). #. Update ``find_displacement()`` to the displacement object and rename FFT framesize constants (:ref:`the find_displacement overhaul `). #. Port ``set_auto_whitebal()`` to ``rgb_gain_db=`` + ``get_rgb_gain_db()`` (:ref:`the white-balance rework `) and stop checking the return of ``set_hmirror()`` / ``set_vflip()`` (:ref:`the mirror/flip change `). #. Pass a firmware path to the WINC ``fw_*`` tools (:ref:`the WINC tools change `). #. Pass a 28x28 ``roi`` to ``find_number()`` (:ref:`the find_number change `) and adjust AprilTag angle math for the flipped ``z_rotation()`` sign (:ref:`the z_rotation change `). All other scripts run unchanged.