.. _changelog_v1_2_0: v1.2.0 ====== v1.2.0 is a foundational, very large release that builds out most of the classic OpenMV imaging API: the **drawing** methods, **binary / morphology** operations, **keypoint descriptors** (FAST / FREAK / LBP), **color conversions** and :class:`image.statistics`, **BMP / PPM / JPEG** file I/O, the ``lcd``, :mod:`mjpeg`, :mod:`gif`, and ``mlx`` thermal modules, the **OV7725** camera, and many :mod:`sensor` controls. Some core :mod:`sensor` behavior changed — read the breaking changes below. .. contents:: On this page :local: :depth: 1 Highlights ---------- - **Drawing API** — ``draw_line()`` / ``draw_rectangle()`` / ``draw_circle()`` / ``draw_string()`` / ``draw_cross()`` / ``draw_keypoints()``. - **Binary / morphology** — ``binary()``, ``invert()``, ``and/or/xor/...``, ``erode()`` / ``dilate()`` / ``morph()``, ``negate()`` / ``difference()``. - **Keypoints** — FAST / FREAK / LBP descriptors with ``match_descriptor()`` / ``save_descriptor()`` / ``load_descriptor()``. - **New modules** — ``lcd``, :mod:`mjpeg`, :mod:`gif` (color), and ``mlx`` thermal. - **OV7725** camera support; :class:`image.statistics`; BMP/PPM/JPEG file I/O. - **Breaking:** :func:`sensor.reset`, :func:`sensor.snapshot`, and :func:`sensor.set_pixformat` behavior changed — see the breaking changes. New features ------------ - **Drawing** — added ``image.draw_line()`` / ``draw_rectangle()`` / ``draw_circle()`` / ``draw_string()`` / ``draw_cross()`` / ``draw_keypoints()`` with keyword arguments (color, thickness, …). - **Binary / morphology** — added ``image.binary()``, ``invert()``, ``and()`` / ``nand()`` / ``or()`` / ``nor()`` / ``xor()`` / ``xnor()``, ``erode()`` / ``dilate()`` / ``morph()``, ``negate()`` / ``difference()``, ``pixels()``, ``centroid()``, ``orientation_radians()`` / ``orientation_degrees()``, and ``width()`` / ``height()`` / ``format()``. - **Keypoints / descriptors** — FAST keypoint extraction via ``find_keypoints()``, a unified ``match_descriptor()`` and ``save_descriptor()`` / ``load_descriptor()`` for FREAK / LBP, plus a profile-face Haar/LBP cascade. - **Color / statistics** — :class:`image.statistics` and color-conversion functions (``rgb_to_lab`` / ``lab_to_rgb`` / ``rgb_to_grayscale`` / ``grayscale_to_rgb``). - **File I/O** — BMP / PPM (P2/P3/P5/P6) / JPEG load and save (including grayscale JPEG and 4:2:0 / 4:2:2 chroma subsampling). - **Modules** — new ``lcd`` (LCD shield), :mod:`mjpeg` (video recording), color :mod:`gif` (with ``Gif.loop()``), and ``mlx`` thermal-camera modules, each with example scripts. - **Sensor** — added :func:`sensor.get_id` (+ OV9650/OV2640/OV7725 PID constants), :func:`sensor.set_special_effect` (SDE_* constants), ``sensor.set_image_filter()`` (FILTER_BW / FILTER_SKIN), the ``HQVGA`` framesize, and ``image.set_pixel(x, y, …)``. - **WiFi** — added the ATWINC1500 WiFi driver and OpenMV 1/2 BSP groundwork, plus a BLE example. Other changes and improvements ------------------------------ - The framebuffer is now JPEG-compressed before streaming to OpenMV IDE (lower bandwidth); JPEG compression is done in place; OV7725 H/V zoom enables arbitrary scaling; improved (faster) Haar face detection that runs at QVGA. Bug fixes --------- Imaging: - Fixed the integral-image computation, ``median()`` filter corruption, the centroid computation, RGB skin / black-and-white filters on RGB input, and faster grayscale BMP/PPM read/write. Sensor and system: - Fixed the :class:`pyb.Servo` timers (Servo now works), HQVGA resolution, SD-card init reliability, re-initializing storage after a soft-reset, and re-running the REPL when no script is present. Hardware and board support -------------------------- - **OV7725** camera sensor. - **LCD shield** (``lcd`` module), ``mlx`` thermal camera, and **ATWINC1500** WiFi groundwork. Breaking API changes -------------------- User-visible API breaks between v1.1.0 and v1.2.0. Scope: Python C-modules in ``modules/`` and Python libraries in ``scripts/libraries/``. All three breaking changes are *behavior* changes to core :mod:`sensor` functions (same API, different behavior) — re-check affected scripts. Each commit hash links to its diff on GitHub. (The vast majority of this release is new API built out within the v1.1→v1.2 range and is therefore additive, not breaking.) .. _v1_2_0_reset: :func:`sensor.reset` no longer applies a default config *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.reset` no longer applies a built-in default configuration (pixformat / framesize / framerate / gain / contrast / brightness / saturation). Scripts that relied on ``reset()`` leaving a usable default must now explicitly call :func:`sensor.set_pixformat` and :func:`sensor.set_framesize` (and any other settings) after ``reset()``. *Commits:* `d1e782df3 `__ .. _v1_2_0_snapshot: :func:`sensor.snapshot` raises on timeout *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.snapshot` now raises ``RuntimeError("Sensor Timeout!!")`` when the sensor times out instead of hanging indefinitely. Wrap ``snapshot()`` in ``try`` / ``except RuntimeError`` if you need to tolerate timeouts. *Commits:* `e3f41d674 `__ .. _v1_2_0_setpixformat: :func:`sensor.set_pixformat` raises on unsupported format *(behavior)* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`sensor.set_pixformat` now raises an exception when given an unsupported pixel format instead of returning ``False``. Code that checked the ``False`` return must catch the exception instead. *Commits:* `e0c5822c2 `__ .. _v1_2_0_migration: Migration checklist ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For a clean port to v1.2.0 the typical work is: #. Explicitly set :func:`sensor.set_pixformat` / :func:`sensor.set_framesize` after :func:`sensor.reset` (:ref:`the reset change `). #. Wrap :func:`sensor.snapshot` in ``try`` / ``except RuntimeError`` if you need to tolerate sensor timeouts (:ref:`the snapshot change `). #. Catch the exception from :func:`sensor.set_pixformat` instead of checking for ``False`` (:ref:`the set_pixformat change `). All other scripts run unchanged.