v5.0.0¶
v5.0.0 is a major release. Headlining it: the rebuilt OpenMV Protocol V2
host link, a class-based csi camera API that scales to multi-camera
boards, a runnable simulator target, MoveNet single-pose estimation,
MicroPython 1.28, and a large batch of camera, ML, and ToF fixes. It also lands
a number of breaking API changes — every user-visible change since v4.8.1 is
listed below, along with exactly how to migrate.
Highlights¶
OpenMV Protocol V2. The host/IDE link was rebuilt from the ground up: framed, sequenced, CRC-checked, with multiplexed channels for stdio, the stream preview, and user data. A new
protocolmodule lets scripts create their own transports and data channels. See the protocol module changes.Class-based
csicamera API.import sensorbecomesimport csi/csi.CSI, with native multi-camera support. See the csi migration.Simulator target. Firmware now builds and runs under the Arm FVP / QEMU simulator (MPS2/MPS3), including NPU, ROMFS, and PSRAM emulation — vision and ML scripts can run with no hardware attached.
MoveNet pose estimation. A new
MoveNetpost-processor plus a bundledmovenet_singlepose_192.tflitemodel on the OpenMV AE3 and N6.MicroPython 1.28 and ulab 6.12.0, ST Edge AI 4.0 tooling, and the externalized OpenMV SDK (see the build / tooling changes).
New features¶
The
protocolmodule — create custom transports and data channels from Python:protocol.init(),protocol.register(),protocol.is_active(), and aprotocol.ProtocolChannelclass withsend_event(), plusCHANNEL_FLAG_*andCHANNEL_ID_*constants. The finalprotocol.init()signature is documented in the protocol module changes.protocol.CBORChannel— a frozenprotocolextension package that serializes named fields to CBOR with display widgets (label, depth) and interactive controls (toggle, slider, select).Host memory and stream introspection — a new
SYS_MEMORYprotocol command exposes per-pool runtime memory statistics to the IDE, and a newSTREAM_SOURCEstream ioctl lets the host pick which camera feeds the preview on multi-camera boards (protocol version 1.0.1).Multi-camera streaming —
csi.CSItakes astream=argument that selects which sensor feeds the IDE preview; the stream frame header now carries an EMA-smoothed FPS so the IDE shows the frame rate withoutclock.fps()boilerplate. See the csi migration and the csi follow-ups.GenX320 event sensor — a new Spatio-Temporal Contrast filter (
csi.IOCTL_GENX320_SET_STCwith thecsi.GENX320_STC_DISABLE,csi.GENX320_STC_ONLY,csi.GENX320_STC_TRAIL_ONLY, andcsi.GENX320_STC_TRAILmodes) and raw event reading (csi.IOCTL_GENX320_READ_EVENTS_RAW), with new example scripts.MoveNet— a new MediaPipe single-pose post-processor (threshold,nms_threshold,nms_sigmakwargs) returning((x, y, w, h), score, keypoints)with a 17-joint COCO keypoint array; amovenet_singlepose_192.tflitemodel and example are bundled on the AE3 and N6.ml.utils.draw_predictions()— a new optionalscores=argument appends per-label confidence, font and box stroke now auto-scale to image width, and a newformat="point"mode draws a center marker for centerpoint/peak detectors.The new
display.TVDisplayclass (with a genericioctl()) replaces the standalonetvmodule. See the display module changes.A new
find_line_segments()detector (ED-Lines) — now available on all builds, with a newthreshold=argument. See the image module changes.
Other changes and improvements¶
MicroPython updated to 1.28.0 from the v4.8.1 base. Adds high-speed SD card mode on H5/H7/N6, AHB5 clocking in low-power mode, and controllable JTAG pins as GPIOs on the OPENMV_AE3.
ulab updated to 6.12.0 — native
%operator on ndarrays (theml.utils.mod()helper is removed; see the ML library changes).ST Edge AI tooling updated to 4.0 — affects on-device ST model compilation and deployment.
ml.Model— theload_to_fbkeyword argument was removed; model memory is handled automatically by the unified allocator.image.Image.scale()in place — scaling an image up in place (for exampleimg.scale(x_scale=2.0, y_scale=2.0)) now grows the frame buffer to fit instead of failing.Larger stdio buffer — the default text buffer to the IDE grew from 512 to 1024 bytes on OpenMV 2/3/4, Nicla Vision, AE3, and N6, so larger
print()bursts are not truncated.Smoother host event flow — stdout NOTIFY events to the host are throttled to at most one per host read instead of one per
print()crossing the ring buffer watermark.Interruptible long operations — long image-drawing, GPU (Nema/Dave2D), and NPU wait loops now service events on a deterministic interval, so scripts stay responsive to the IDE Stop button during heavy work.
Bug fixes¶
Camera and sensors:
find_apriltags()no longer corrupts results on D-cache/GPU boards (N6, AE3), and now works on the AE3.Fixed Bayer image output from the STM32 N6 ISP after switching pixel formats.
Fixed green auto-white-balance blowout on bright scenes and an uninitialized first-frame AWB-stats case; raised the STM32 ISP gamma clamp (32 to 63) for a wider gamma/contrast/brightness range.
PS5520 auto-exposure no longer oscillates in bright light; PAG7936 AEC/AGC behavior was reworked (combined control, corrected gain ceiling).
OV5640 autofocus firmware upload restored on Portenta/Nicla (MIMXRT I2C SUSPEND fix).
Fixed a camera capture deadlock when a frame-rate limit is combined with JPEG capture (STM32).
GenX320
csi.IOCTL_GENX320_READ_EVENTS_RAWreads no longer scramble the IDE preview.FLIR Lepton
csi.IOCTL_LEPTON_SET_MODEviacsi.CSI.ioctl()now works when called with a single argument.
Image processing:
Fixed
draw_image()/blend()alpha blending when a mask is supplied.Fixed 1-bit (BINARY) PNG encode/decode bit ordering and grayscale-from-1-bit decoding.
Fixed
mjpeg.Mjpegrecording duration/FPS metadata.Fixed a software-JPEG-decode stack overflow on small-stack boards (OpenMV M7).
Fixed JPEG/PNG file-format auto-detection on non-ARM hosts (simulator).
Time-of-Flight:
tof.read_depth()no longer raises on transient ranging errors and auto-recovers from bus faults; the defaulttof.read_depth()/tof.snapshot()timeout is now 100 ms (see the tof changes).Fixed VL53L5CX / VL53L8CX multi-zone depth-data corruption.
ML and system:
The NPU is cleaned up correctly when inference is interrupted on the N6.
Deep-sleep / standby wakeup restored on the N6; the AE3 jump-to-bootloader hang is fixed.
Fixed memory leaks on soft-reset (STM32 Nema GPU) and a prematurely collected auxiliary frame buffer.
Custom Python protocol channels now survive a soft-reboot, the USB transport recovers from bus reset / stalled endpoints, and USB SOF interrupt flooding is fixed.
Hardware and board support¶
OpenMV N6 — Ethernet enabled (wired networking); NPU AXI SRAM (1.75 MB) merged into a shared transient pool for more RAM between inferences; deep-sleep/standby wakeup; bundled TFLite models and Haar cascades in ROMFS.
OpenMV AE3 — bundled models and cascades in ROMFS;
cbor2frozen into the firmware.Alif (AE3, N6) — low-power
machine.RTCwakeup.High-resolution AprilTags — full-sensor-resolution
find_apriltags()on the AE3, Arduino Giga, and Arduino Portenta H7.Simulator targets — MPS2_AN500 / MPS3_AN547 (Arm FVP / QEMU), with NPU, ROMFS, and PSRAM emulation.
Breaking API changes¶
User-visible API breaks between v4.8.1 and v5.0.0. Scope: Python C-modules in
modules/ and Python libraries in scripts/libraries/.
Each change is tagged with its impact:
major — most scripts need edits.
minor — narrow API; only affects scripts that used it.
behavior — same API, different results; re-check tuned scripts.
tooling — only affects building from source / downstream forks.
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.
sensor replaced by csi (major)¶
Every official example was rewritten to drop import sensor in favor of
import csi. The legacy module-level functional API (sensor.reset(),
sensor.set_pixformat(), …) is superseded by the class-based
csi.CSI API, which scales naturally to boards with multiple cameras
(csi0, csi1, …) and is required for all new features (the stream=
kwarg, multi-sensor streaming, …).
The sensor qstr is still wired up in modules/py_csi.c for
backwards-compatible firmware builds, but it will not gain new features, and all
examples, docs, and library code now assume csi.
Module to class
Before (sensor):
import sensor
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
img = sensor.snapshot()
After (csi):
import csi
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)
img = csi0.snapshot()
Setter/getter pairs collapsed to combined accessors
In the new API a method called without arguments returns the current value;
called with a value it sets it. The set_*/get_* prefixes are gone.
Method names also lost the ing suffix where it was redundant
(windowing → window). The new-API column links to the reference docs.
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Functions with no direct equivalent
|
What to use instead |
|---|---|
|
|
|
|
|
Moved into the |
|
|
|
Removed. The image returned by |
|
|
New on csi.CSI
csi.CSI(stream=True|False)— a construct-time selector that chooses which CSI feeds the preview framebuffer (replaces the per-snapshotupdate=kwarg, see the csi follow-ups).csi.CSI(cid=N)/csi.devices()— multi-CSI support for boards with more than one image sensor.
image module — signature overhaul (major)¶
The image module saw the widest API change after csi — drawing
signatures, result objects, and several detectors all changed.
Coordinate arguments must be tuples
modules/py_image.c was rewritten on top of mp_arg_parse_all. All
drawing / pixel methods that previously took separate x, y, ... positional
arguments now require those coordinates packed into a single tuple.
Commits: d18bbc472, 0c60c94b9 (PR #3061)
Before |
After |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All are methods of image.Image.
Result objects converted to attrtuple
These types are now MicroPython attrtuple objects: similarity,
statistics, percentile,
threshold, line, circle,
rect, qrcode, apriltag,
datamatrix, barcode,
displacement, kptmatch. Attribute access
without parentheses is now canonical.
Commit: 3399d302e
Before (method-style):
img.draw_cross(match.cx(), match.cy())
img.draw_rectangle(blob.rect())
After (attribute-style):
img.draw_cross((match.cx, match.cy))
img.draw_rectangle(blob.rect)
blob and histogram are unchanged — they keep
their existing types and () accessors (an attrtuple can’t express a blob’s
lazily-computed values or a histogram’s argument-taking accessors).
find_features haar parameter rename
image.Image.find_features() — scale_factor= was renamed to
scale=.
Commit: be4c5cd73
get_regression — now always robust, target_size added
image.Image.get_regression() now always uses the robust (Theil-Sen)
regression. The old fast least-squares path was removed, so the robust=
keyword is gone — what used to require robust=True is now the only
behavior. A new target_size=(w, h) kwarg (default (80, 60)) area-scales
the ROI down before the O(N^2) Theil-Sen fit so it always runs on a sane image
size; the fitted line endpoints are mapped back to source coordinates. The
linear_regression_robust.py example was deleted and
linear_regression_fast.py was renamed to linear_regression.py.
find_line_segments — new algorithm
image.Image.find_line_segments() — the old LSD detector was replaced by
ED-Lines, and it gained a new threshold=50 kwarg. Output of
previously-tuned scripts will differ.
AprilTag library replaced
image.Image.find_apriltags() — the AprilTag detector was replaced with a
new implementation. The family set changed:
Removed |
Added |
|---|---|
|
|
Commit: e813bada7
csi module follow-up (minor)¶
Smaller csi follow-ups on top of the csi migration.
snapshot(update=…) removed
The update kwarg on csi.CSI.snapshot() is gone. To keep a CSI device
from feeding the preview framebuffer, opt out at construction time:
csi0 = csi.CSI(stream=False) # was: csi0.snapshot(update=False)
csi1.snapshot(blocking=False, image=fir_img) # was: ...(update=False, ...)
framebuffers() expand arg removed
csi.CSI.framebuffers() — the third positional argument (expand) is
gone; the signature is now framebuffers([count]).
Commit: 86cb3a5de
protocol module (minor)¶
Only affects scripts that drove the host link directly. See protocol.
timer_ms renamed to poll_ms
protocol.init() — the timer_ms argument was renamed to poll_ms.
protocol.init(..., poll_ms=10) # was: timer_ms=10
protocol.poll() removed
The protocol task is scheduled internally now. Calls to protocol.poll()
will raise AttributeError.
Commit: 8a0635e8c
soft_reboot config arg removed
protocol.init() — the soft_reboot argument is gone. All current
transports tolerate soft-reboots, so the behavior is now unconditional.
Commit: 0bf766aa2
display modules (minor)¶
TV output now goes through a display.TVDisplay object instead of the
standalone tv module. display also gained a generic ioctl().
tof module (behavior)¶
Same API as before; the defaults and error handling changed. See tof.
Default timeout changed
tof.read_depth() and tof.snapshot() (called with timeout=-1)
now default to 100 ms instead of waiting indefinitely. Pass an explicit
larger value if you need the old behavior.
Commit: b6772b80d
Automatic recovery
The driver now hard-resets the I2C bus and the sensor on ranging/timeout
errors. Examples no longer call tof.reset() in their exception handlers —
user code that did manual recovery should remove it (it will fight the new
auto-recovery).
ML library (behavior)¶
Same API, different numbers — re-check any tuned ML pipeline.
Preprocessing now stretches instead of letterboxes
Normalization now uses
image.SCALE_ASPECT_IGNORE (stretch) instead of
image.SCALE_ASPECT_EXPAND (letterbox). NMS
post-processing also switched to independent x/y scaling.
Note
Impact. YOLO-style detectors and keypoint regressors generally improve.
The BlazeFace,
BlazePalm,
FaceLandmarks, and
HandLandmarks examples now require a
manual square crop on the input ROI — the example scripts were updated;
custom user code must do the same.
Commit: 68dc29a33
ml.utils.mod() helper removed
ulab 6.12.0 supports % on ndarrays natively. Code that imported mod
from ml.utils must use a % b.
Build / tooling (tooling)¶
None of this affects MicroPython scripts. Building firmware from source now
requires the external OpenMV SDK (1.6.0, previously in-tree). Several
in-tree build tools were removed and the N6 moved to the TinyUSB stack;
downstream forks should review the
firmware repository history — notably the
file_open() signature dropping its buffered argument.
Migration checklist¶
For a clean port to v5.0.0 the typical work is:
Replace
import sensorwithimport csi; csi0 = csi.CSI()and translate everyset_*/get_*call to itscsi.CSIaccessor (the csi migration).Wrap coordinate arguments to
img.draw_*,get_pixel(), andset_pixel()in tuples (the image module changes).Drop
()from attrtuple result accessors if you want the new idiomatic form, or leave the old style alone since attrtuples still support callable accessors (the image module changes).Audit
find_line_segments(),get_regression(), and anyfind_apriltags()family choice (the image module changes).Rename
timer_ms→poll_msinprotocol.init()calls; removeprotocol.poll()andsoft_reboot=(the protocol module changes).For ML workflows: revisit any model that needed letterboxed input (the ML library changes).