.. _changelog_v2_1_0: v2.1.0 ====== v2.1.0 is a massive API-modernization release. It replaces the FREAK keypoint descriptor with **ORB**, reworks ``find_blobs()`` / histograms / statistics into **object-based APIs**, renames the :mod:`sensor` auto exposure/gain/white- balance functions, adds **QR-code detection** and OV7725 lens correction, and brings up the initial **OpenMV Cam M7** board. Many APIs changed — read the breaking changes below. .. contents:: On this page :local: :depth: 1 Highlights ---------- - **ORB keypoints** — the FREAK descriptor was replaced with ORB (``find_keypoints()`` / ``match_descriptor()`` reworked). - **Object APIs** — ``find_blobs()``, ``get_histogram()``, ``get_statistics()`` now return objects with named accessors. - **QR codes** — ``image.find_qrcodes()`` detection added. - **OpenMV Cam M7** — initial board support. - **Sensor** — ``set_auto_whitebal()`` / ``set_auto_gain()`` / ``set_auto_exposure()`` (renamed) and ``set_lens_correction()``. - **Breaking:** the keypoint/descriptor, blob/histogram/statistics, sensor auto-function, and several other APIs changed — see the breaking changes. New features ------------ - **OpenMV Cam M7** — added initial OpenMV 3 (M7) board support. - **QR codes** — added ``image.find_qrcodes()`` with a ``qrcodes.py`` example. - **ORB keypoints** — new ORB descriptor system: ``find_keypoints()`` with a ``corner_detector`` argument (``CORNER_FAST`` / ``CORNER_AGAST``), ``max_keypoints`` / ``scale_factor``; ``match_descriptor()`` with a ``filter_outliers`` keyword and a rotation estimate; keypoint save/load. - **Object APIs** — ``image.get_histogram()`` / ``get_statistics()`` / ``get_percentile()`` return histogram/statistics objects; ``find_blobs()`` returns blob objects (``rect()`` / ``cx()`` / ``cy()`` / ``code()`` / ``area()`` / ``pixels()``) with ``area_threshold`` / ``pixels_threshold`` / ``merge`` / ``margin`` / ``invert`` and ``x_stride`` / ``y_stride``. - **Sensor** — added ``sensor.set_lens_correction(enable, radi, coef)`` for OV7725 lens shading, :func:`sensor.set_windowing` now also accepts a ``(w, h)`` tuple (auto-centered), and ``image.Image(..., copy_to_fb=True)`` / ``load_image(copy_to_fb=True)``. - Added color-tracking, Arduino SPI/I2C-slave, keypoints, and histogram/statistics example scripts. Other changes and improvements ------------------------------ - The IDE can now interrupt a running ``main.py``; faster ``find_blobs()`` / ``find_qrcodes()`` / ``get_statistics()``; ORB uses a popcount Hamming distance; lens correction uses less RAM; a Linux ``udev`` rule stops ModemManager from grabbing the serial port. Bug fixes --------- Camera and imaging: - Fixed M7 DMA cache clean/invalidate (corrupted frames), a spurious extra line at the end of each frame, JPEG framebuffer overflow bounds, freeing the framebuffer on ``compress()`` failure, ORB accuracy / ROI / empty-set handling, and ``load_image(copy_to_fb=True)`` geometry. System: - Fixed F7 ADC support, an OV7725 register name, bootloader/USB timing, used WFI while waiting for snapshots, and made the MJPEG streamer example non-blocking with per-client timeouts. Hardware and board support -------------------------- - **OpenMV Cam M7 (OpenMV 3)** — initial board support. - **OV7725** — lens-correction (shading) support. Breaking API changes -------------------- User-visible API breaks between v2.0.0 and v2.1.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_1_0_orb: FREAK replaced with ORB; descriptor API reworked *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The FREAK keypoint descriptor was removed and replaced with ORB: ``image.FREAK`` no longer exists (use ``image.ORB``). :func:`image.match_descriptor` / ``save_descriptor()`` / ``load_descriptor()`` no longer take a leading descriptor-type argument (it is inferred from the object), ``match_descriptor()`` now returns an 8-element tuple ``(cx, cy, x, y, w, h, match_count, rotation)`` (the last element is a raw count, not a percentage), and ``draw_keypoints()`` requires a keypoints object instead of a raw ``(x, y, angle)`` list. ``find_keypoints()`` gained ``corner_detector`` / ``max_keypoints`` / ``scale_factor`` with changed defaults. *Commits:* `e2d0c4840 `__, `bba8e5a9e `__, `6000684cb `__ .. _v2_1_0_autofuncs: Sensor auto-function rename *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``sensor.set_whitebal()`` / ``set_gain_ctrl()`` / ``set_exposure_ctrl()`` were renamed to :func:`sensor.set_auto_whitebal` / ``set_auto_gain()`` / ``set_auto_exposure()`` (the old names were removed). Each gained an optional ``value=`` keyword to set a manual value instead of auto. *Commits:* `1b22a2961 `__ .. _v2_1_0_histogram: Histogram / statistics reworked to object APIs *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The histogram/statistics surface was reworked into object-based ``image.get_histogram()`` / ``get_statistics()`` / ``get_percentile()`` returning histogram/statistics objects. The old flat histogram/statistics results and the ``bin_count`` / ``l_bin_count`` / ``a_bin_count`` / ``b_bin_count`` methods were removed (use ``len(histogram.bins())`` etc.). *Commits:* `011108412 `__, `9f37c83de `__ .. _v2_1_0_findfeatures: ``find_features()`` ``scale`` renamed *(major)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.find_features()`` (Haar) renamed its ``scale=`` keyword to ``scale_factor=``. Update ``find_features(cascade, scale=...)`` calls to ``scale_factor=...``. *Commits:* `96e4f770c `__ .. _v2_1_0_findblobs: ``find_blobs()`` returns objects; ``find_markers()`` removed *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.find_blobs()`` now returns blob objects with named accessors (index access still works for backward compatibility), and ``image.find_markers()`` was removed — use ``find_blobs(..., merge=True, margin=...)`` instead. The advanced color-blob filter callback is no longer supported. *Commits:* `af15ec6eb `__ .. _v2_1_0_copytofb: ``img.copy_to_fb()`` replaced *(minor)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``img.copy_to_fb()`` method was replaced by a ``copy_to_fb=`` keyword on :class:`image.Image` / ``load_image()``. Use ``image.Image(path, copy_to_fb=True)`` to load large images straight into the framebuffer. *Commits:* `1645ab94b `__ .. _v2_1_0_compress: ``compress()`` rejects out-of-range quality *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.compress()`` / ``compressed()`` now raise an error when ``quality`` is outside 1–100 instead of silently clamping. Clamp ``quality`` into 1–100 before calling. Separately, the OpenMV 3 JPEG buffer was reduced from 64 KB to 23000 bytes, so large frames may now raise out-of-memory — lower the JPEG quality or framesize. *Commits:* `9efd7474a `__, `9a7c3defc `__ .. _v2_1_0_lenscorr: ``lens_corr()`` zoom is now functional *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``image.lens_corr()`` now actually applies its ``zoom`` argument (it was previously parsed but ineffective), so output differs for scripts that passed a non-default zoom. Re-check ``lens_corr()`` tuning. *Commits:* `d6b49adef `__ .. _v2_1_0_migration: Migration checklist ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For a clean port to v2.1.0 the typical work is: #. Replace ``image.FREAK`` with ``image.ORB``, drop the descriptor-type argument, and update ``match_descriptor()`` tuple unpacking / ``draw_keypoints()`` to the keypoints object (:ref:`the ORB rework `). #. Rename ``sensor.set_whitebal()`` / ``set_gain_ctrl()`` / ``set_exposure_ctrl()`` to the ``set_auto_*`` forms (:ref:`the auto-function rename `). #. Move histogram/statistics code to the object methods (:ref:`the histogram/statistics rework `). #. Rename ``find_features()`` ``scale=`` to ``scale_factor=`` (:ref:`the find_features rename `). #. Use blob-object accessors and replace ``find_markers()`` with ``find_blobs(merge=True, ...)`` (:ref:`the find_blobs change `); replace ``img.copy_to_fb()`` with the ``copy_to_fb=`` keyword (:ref:`the copy_to_fb change `). #. Clamp ``compress()`` quality to 1–100 and re-check JPEG sizes on the OpenMV 3 (:ref:`the compress change `); re-tune ``lens_corr()`` zoom (:ref:`the lens_corr change `). All other scripts run unchanged.