.. _changelog_v1_4_0: v1.4.0 ====== v1.4.0 is a foundational imlib reorganization. ``find_blobs()`` / ``find_markers()`` were rewritten for direct color-threshold tracking, many standalone image methods were folded into blob tuples, and several image methods were renamed (``subimg`` → ``copy``, ``blit`` → ``replace``, ``find_eyes`` → ``find_eye``, ``compress`` → ``compressed``). It also adds :func:`sensor.get_fb` / AGC / AEC toggles and ~60 example scripts. This is a heavily breaking release — read the breaking changes below. .. contents:: On this page :local: :depth: 1 Highlights ---------- - **Color-based blob tracking** — ``find_blobs()`` takes color thresholds directly and returns a flat list of blob tuples. - **Imlib cleanup** — ``subimg()`` → ``copy()``, ``blit()`` → ``replace()``, ``find_eyes()`` → ``find_eye()``, ``compress()`` → ``compressed()``. - **Sensor** — added :func:`sensor.get_fb` and AGC/AEC enable toggles. - **~60 example scripts** added/expanded. - **Breaking:** the blob API, removed image methods, and several renames — see the breaking changes. New features ------------ - **Sensor** — added :func:`sensor.get_fb` (retrieve the last snapshot framebuffer), ``sensor.set_gain_ctrl(enable)`` (toggle AGC), and ``sensor.set_exposure_ctrl(enable)`` (toggle AEC). - **Image** — image subscript (``img[i]``) now supports both reading and writing pixels (grayscale / RGB565 / JPEG); added an in-place ``image.compress()`` and a ``quality=`` keyword on the JPEG functions; ``find_blobs()`` / ``find_markers()`` / ``find_features()`` now return an empty (iterable) list instead of a non-list when nothing is found. - Added ~60 example scripts (board control, image filters, color tracking, face / eye / feature detection, WiFi shield) and a second iris-detection example. Other changes and improvements ------------------------------ - ``image.histeq()`` now works on RGB565 images, not just grayscale. Bug fixes --------- - Initialized :class:`pyb.DAC` on boot so the DAC works (#121), fixed a broken ``image.dilate()``, the WINC ``client.send()`` zero-byte corruption, blob merge re-iteration, a file-buffer reinitialization bug that broke the filesystem after first use, the thermopile ``To_min`` / ``To_max`` computation (#113), and applied an upstream MicroPython HAL I2C/DMA patch. Hardware and board support -------------------------- - **WiFi shield** — WINC1500 updated to Rev-B board files. - :class:`pyb.DAC` — DAC peripheral enabled. Breaking API changes -------------------- User-visible API breaks between v1.3.0 and v1.4.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. 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. .. _v1_4_0_findblobs: ``find_blobs()`` / ``find_markers()`` rewritten *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.find_blobs()`` / ``find_markers()`` were rewritten for color-based tracking: you now pass color thresholds (and an optional filter function) directly instead of operating on a pre-segmented image, and the result is a single flat list of 10-element blob tuples (with a color-code field) instead of a nested per-color tree. Rework color-tracking scripts to pass color thresholds and iterate the flat list. *Commits:* `d1ff36602 `__, `16daeb83a `__ .. _v1_4_0_removed: Standalone image methods removed *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :class:`image.threshold`, ``image.centroid()``, ``image.orientation_radians()``, ``image.orientation_degrees()``, and ``image.pixels()`` were removed. The centroid / orientation / pixel-count data is now available as fields of the blob tuples returned by ``find_blobs()``. *Commits:* `9e5d379c1 `__ .. _v1_4_0_imlibrename: Imlib method renames *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Several image methods were renamed/reworked: ``image.subimg()`` → ``image.copy()``, ``image.blit()`` → ``image.replace()``, and ``image.blend()`` was changed to match the other two-image ops. The ``image.scale()`` / ``scaled()`` / ``rainbow()`` methods were removed (``rainbow`` moved to the FIR module). Update calls to the new names. *Commits:* `b534dc6ff `__ .. _v1_4_0_findeye: ``find_eyes()`` renamed to ``find_eye()`` *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.find_eyes()`` was renamed to ``image.find_eye()`` and now returns a 2-tuple iris ``(x, y)`` instead of the previous eyes tuple. Rename the call and update the return handling. *Commits:* `7a01a9bed `__ .. _v1_4_0_compress: ``image.compress()`` renamed to ``compressed()`` *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.compress()`` (which returned a new JPEG image) was renamed to ``image.compressed()``; the new ``image.compress()`` instead compresses the image in place and returns ``None``. ``image.save()`` also gained a ``quality=`` keyword and now returns ``None`` instead of ``True``. Migrate ``img.compress(q)`` (expecting a returned image) to ``img.compressed(quality=q)``. *Commits:* `367e5fdd3 `__ .. _v1_4_0_migration: Migration checklist ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For a clean port to v1.4.0 the typical work is: #. Rework color-tracking code to pass color thresholds to ``find_blobs()`` / ``find_markers()`` and iterate the flat blob-tuple list (:ref:`the find_blobs rewrite `). #. Read centroid / orientation / pixel data from the blob tuples instead of the removed standalone methods (:ref:`the removed image methods `). #. Rename ``subimg`` → ``copy``, ``blit`` → ``replace``, fix ``blend()`` calls, and replace ``scale`` / ``scaled`` / ``rainbow`` (:ref:`the imlib renames `). #. Rename ``find_eyes()`` → ``find_eye()`` (:ref:`the find_eye rename `) and ``compress()`` → ``compressed()`` (:ref:`the compress rename `). All other scripts run unchanged.