v4.8.0

v4.8.0 is a major feature release. Headlining it: a brand-new class-based csi camera module with multi-camera support, the OpenMV N6 (STM32N6) board with a Neural-ART NPU, an NPU inference backend, GenX320 event-camera RAW event mode, a new crc module, a reorganized ML post-processing library, and MicroPython 1.26. It also removes a few legacy APIs — the buzzer module and the fir module’s FLIR Lepton control — so read the breaking changes below.

Highlights

  • New csi camera module. A class-based csi.CSI API with support for multiple simultaneous cameras, introduced alongside the legacy sensor module.

  • OpenMV N6. The STM32N6 board, with a Neural-ART NPU, triple buffering, Soft-CSI, and a ToF module.

  • NPU inference. A ST Neural-ART (STAI) backend for hardware-accelerated model inference.

  • GenX320 event mode. RAW event output plus draw_event_histogram() for event-camera rendering.

  • Reorganized ML post-processing — vendor subpackages (ml.postprocessing.ultralytics, mediapipe, edgeimpulse, darknet) with new BlazeFace / BlazePalm / hand- and face-landmark detectors.

  • New crc module — hardware-accelerated CRC-16 / CRC-32.

  • MicroPython updated to 1.26.0.

  • Breaking: the buzzer module and the fir module’s Lepton control were removed (the Lepton is now a regular camera). See the fir/Lepton change and the buzzer removal.

New features

  • The new csi camera module — a class-based csi.CSI object with multiple simultaneous cameras (up to three on the N6), non-blocking snapshot, custom (w, h) frame sizes, and an informative print() / repr. It is introduced alongside the legacy sensor module (not a drop-in replacement).

  • crccrc.crc16() and crc.crc32(), hardware-accelerated with a software fallback, on the OpenMV N6 and AE3.

  • image.Image.draw_image() gained a transform= keyword (a 2-D float ndarray matrix for affine/perspective warps, GPU-accelerated on STM32 and Alif); the same transform is available in image conversion.

  • draw_event_histogram() — render event-camera histograms.

  • GenX320 RAW event modecsi.IOCTL_GENX320_SET_MODE with csi.GENX320_MODE_HISTO / csi.GENX320_MODE_EVENT, csi.IOCTL_GENX320_READ_EVENTS, csi.IOCTL_GENX320_CALIBRATE, event-type constants, and new example scripts.

  • ML — a ST Neural-ART (STAI) NPU inference backend; ml.Model gained a postprocess= keyword (the post-processor now runs automatically inside predict() even without a callback); ml.postprocessing was reorganized into vendor subpackages — ml.postprocessing.ultralytics (YoloV5, YoloV8), ml.postprocessing.darknet (YoloV2, YoloLC), ml.postprocessing.edgeimpulse (Fomo), and ml.postprocessing.mediapipe (BlazeFace, BlazePalm, HandLandmarks, FaceLandmarks) — the old snake_case names remain as aliases; ml.utils.draw_keypoints() and ml.utils.draw_skeleton() were added; bundled ROMFS models grew (BlazeFace, YOLO-LC, YOLOv8n, palm/hand/face landmarks).

  • audio — MDF digital-microphone input on the STM32N6.

  • Display — an SSD1351 OLED driver and example; SPIDisplay controllers can override their init commands; the SPI display constructor gained hmirror / vflip keywords.

  • On-device profiler — SysTick + Armv8.1-M PMU cycle/event counters with function-level instrumentation, readable over the debug link (pyopenmv gained profiling and ELF-symbol support).

  • New sensor support — PixArt PS5520; FLIR BOSON on the OpenMV H7 Plus; GenX320 auto-detect.

Other changes and improvements

  • MicroPython updated to 1.26.0.

  • Camera startup — the sensor clock was decoupled from CSI state, camera detection at boot is faster (the most common config is tried first), and the OpenMV 3 OV7725 default clock was corrected.

  • Image quality — software ISP gamma correction (Alif and STM32) and bad-pixel correction (STM32) are on by default; the PAG7936 and PS5520 sensors gained auto-white-balance controls.

  • Performanceimage.Image.to_ndarray() is accelerated with Helium SIMD and the FOMO post-processor was vectorized with ulab.

  • FLIR Lepton driver rewritten to receive frames asynchronously in the background — rotation/transpose now works, drawing upscales bilinearly, and reset is faster.

  • Capture throughput — the i.MX RT1062 CSI now uses full DMA offload, and the STM32 N6 has a hardware-GPU draw_image().

Bug fixes

Camera and sensors:

  • Fixed RGB565 / GRAYSCALE / BAYER / YUV422 modes across the STM32 sensors, PAJ6100 on the OpenMV H7 / H7 Plus, OpenMV 2 QVGA RGB565, and the N6 CSI mono / RGB-YUV configuration; the software test camera now resets deterministically.

  • Auto-white-balance no longer turns the image green at low or variable frame rates (a 250 ms moving average replaces the every-100-frames sample), and PS5520 luminance flicker is fixed.

Image processing:

  • Fixed a draw-line rendering glitch; image.Image.flush() now flushes the JPEG buffer of the image it was called on; Normalization now applies mean/stdev to float inputs; image-from-file allocation is fixed.

Camera capture:

  • Fixed severe image corruption on non-JPEG transfers (the frame interrupt is now enabled only in JPEG mode), JPEG mode-3 support, and DMA line-size and small-buffer lockups on STM32; VOSPI / Lepton synchronization is more reliable, notably on the N6.

Misc:

  • omv.board_id() returns the correct UID on RT1060; YoloV2 no longer crashes when constructed without explicit anchors.

Hardware and board support

  • OpenMV N6 — STM32N6 with a Neural-ART NPU, triple buffering, SPI LCD/TV output, Soft-CSI, the tof module, and bundled ROMFS models.

  • Arduino GIGA — MIPI DSI display output.

  • New sensors — PixArt PS5520; FLIR BOSON on the OpenMV H7 Plus; GenX320 auto-detect.

  • OpenMV Pure Thermal — the FLIR Lepton is now a regular (secondary) camera sensor.

  • Alif AE3 — software ISP gamma correction, the crc module, and SPI fixes.

Breaking API changes

User-visible API breaks between v4.7.0 and v4.8.0. Scope: Python C-modules in modules/ and Python libraries in scripts/libraries/.

Each change is tagged with its impact:

  • major — most scripts that used it need edits.

  • minor — narrow API; only affects scripts that used it.

  • behavior — same API, different results; re-check tuned scripts.

  • tooling — only affects host tools / building from source.

Changes are grouped by impact in that order — major first, then minor, behavior, and tooling. If you just want to port your code, jump to the migration checklist at the end for a condensed to-do list. Each commit hash links to its diff on GitHub.

FLIR Lepton moved off the fir module (major)

The FLIR Lepton is now driven as a regular camera sensor instead of through the fir module. Lepton control was removed from fir: the FIR_LEPTON type and the radiometric(), register_vsync_cb(), register_frame_cb(), get_frame_available(), and trigger_ffc() methods are gone. Capture the Lepton like any other camera (it appears as a secondary sensor on the OpenMV Pure Thermal); the Pure Thermal example was rewritten to the new API. The non-Lepton fir sensors (Grid-EYE, MLX, AMG8833) are unchanged.

Commits: bacfb7aeb, 117710566, 592a22902, 1a614202e

buzzer module removed (minor)

The buzzer module was removed from the STM32 and i.MX RT ports. Drive the buzzer with machine.PWM instead; a Pure Thermal buzzer example using PWM was added.

Commits: ccb947924, 444120f2d

omv.disable_fb() removed (minor)

The omv.disable_fb() function was removed; frame-buffer streaming is controlled through the camera API now. The legacy RPC desktop scripts that relied on it were also removed.

Commits: 84c3db58a, 6fe99051c

csi is new — its API is not yet frozen (minor)

The csi module is introduced in v4.8.0 and its API evolved during the release: csi.fb() was removed, and csi.CSI.snapshot() (image=...) now requires a mutable image and draws/scales the captured frame into it instead of doing a raw deep copy. Early adopters of the new module should re-test; the legacy sensor API is unaffected.

Commits: 0bc0385eb, 8cd7a309f

image.ImageIO stream mode and close() (minor)

image.ImageIO — the mode argument now accepts only lowercase 'r' / 'w' (uppercase is rejected with an updated error message), and opening with 'w' always truncates/recreates the file instead of preserving an existing stream. ImageIO.close() is now idempotent (closing an already-closed stream no longer raises) and returns None instead of the stream object.

Commits: 715c4cbba, 21ceec422

BlazeFace / BlazePalm return value (minor)

The BlazeFace and BlazePalm post-processors (new in this release) now return a single bounding-box list instead of the full per-class list — callers index the result directly rather than [0].

Commit: 75e16b573

ML post-processor callback receives raw tensors (behavior)

A ml.Model predict() post-process callback now receives the raw (quantized) output-tensor references instead of pre-converted float ndarrays — this avoids memory exhaustion on large models. If no callback is supplied, the float ndarray is still returned. Custom callbacks must dequantize the tensors themselves (the built-in post-processors already do).

Commit: 84e6ee650

Camera clock decoupled from CSI state (behavior)

The sensor clock is now independent of CSI state. set_clock / set_frequency only reconfigures the clock when the requested frequency differs by more than a tolerance, and get_clk_frequency takes a boolean to return the exact (rather than nominal) frequency. The default clock is 24 MHz on the OpenMV N6 and AE3, so no explicit set_clock() is needed at boot. Scripts that toggled the clock for timing-sensitive captures should re-check their assumptions.

Commits: 2040a0a00, 09c0052df, 66ade9aea, 7e0a251bc, e6f43f3ca

USB debug protocol and firmware targets (tooling)

None of this affects MicroPython scripts. Obsolete USBDBG commands (SCRIPT_SAVE, TEMPLATE_SAVE, DESCRIPTOR_SAVE, ATTR_READ, ATTR_WRITE, TX_INPUT, SET_TIME) were removed and unsupported commands from older IDEs are now flushed instead of crashing TinyUSB boards on connect; the legacy STM32 UVC firmware target was removed. Old host tools should update; see the firmware repository history for detail.

Commits: 90bd11e93, 657c9a632, 35182f035

Migration checklist

For a clean port to v4.8.0 the typical work is:

  1. If you used the FLIR Lepton through fir, switch to capturing it as a camera sensor (the fir/Lepton change).

  2. Replace any buzzer use with machine.PWM (the buzzer removal).

  3. Remove omv.disable_fb() calls (the omv.disable_fb() removal).

  4. For image.ImageIO: use lowercase 'r'/'w' and expect 'w' to truncate (the ImageIO change).

  5. For custom ML post-process callbacks: dequantize the raw tensor references yourself, or rely on the default float path (the callback change).

  6. Re-check any script that drove the sensor clock for timing-sensitive captures (the clock change).