v5.0.0

v5.0.0 — це мажорний реліз. Основні нововведення: перебудований OpenMV Protocol V2 для зв’язку з хостом, клас-орієнтований API камери csi, що масштабується на платформи з кількома камерами, запускаємий симулятор, оцінка пози MoveNet для однієї людини, MicroPython 1.28 та велика партія виправлень для камери, МН і ToF. Також внесено ряд несумісних змін API — усі помітні для користувача зміни з v4.8.1 перелічені нижче разом із точними інструкціями щодо міграції.

Основні можливості

  • OpenMV Protocol V2. Зв’язок між хостом/IDE було перебудовано з нуля: фреймування, послідовна нумерація, перевірка CRC, мультиплексовані канали для stdio, потокового перегляду та даних користувача. Новий модуль protocol дозволяє скриптам створювати власні транспорти та канали даних. Дивіться зміни модуля protocol.

  • Клас-орієнтований API камери csi. import sensor замінюється на import csi / csi.CSI, з вбудованою підтримкою кількох камер. Дивіться міграцію csi.

  • Ціль-симулятор. Мікропрограма тепер збирається та запускається в симуляторі Arm FVP / QEMU (MPS2/MPS3), включаючи емуляцію NPU, ROMFS і PSRAM — скрипти для зору та МН можна запускати без підключеного обладнання.

  • Оцінка пози MoveNet. Новий постпроцесор MoveNet та вбудована модель movenet_singlepose_192.tflite на OpenMV AE3 і N6.

  • MicroPython 1.28 і ulab 6.12.0, інструментарій ST Edge AI 4.0 та зовнішній OpenMV SDK (дивіться зміни збірки / інструментарію).

Нові можливості

  • Модуль protocol — створення власних транспортів і каналів даних з Python: protocol.init(), protocol.register(), protocol.is_active() та клас protocol.ProtocolChannel з send_event(), а також константи CHANNEL_FLAG_* і CHANNEL_ID_*. Остаточна сигнатура protocol.init() задокументована у змінах модуля protocol.

  • protocol.CBORChannel — заморожений пакет розширення protocol, який серіалізує іменовані поля у CBOR з віджетами відображення (label, depth) та інтерактивними елементами управління (toggle, slider, select).

  • Інтроспекція пам’яті та потоків хоста — нова команда протоколу SYS_MEMORY надає IDE статистику пам’яті по пулах у реальному часі, а новий ioctl STREAM_SOURCE дозволяє хосту вибирати, яка камера подається на попередній перегляд у платах з кількома камерами (версія протоколу 1.0.1).

  • Потокова передача з кількох камерcsi.CSI приймає аргумент stream=, який визначає, який датчик подається на попередній перегляд IDE; заголовок кадру потоку тепер містить згладжений EMA FPS, щоб IDE відображав частоту кадрів без шаблонного коду clock.fps(). Дивіться міграцію csi та подальші зміни csi.

  • Датчик подій GenX320 — новий фільтр Spatio-Temporal Contrast (csi.IOCTL_GENX320_SET_STC з режимами csi.GENX320_STC_DISABLE, csi.GENX320_STC_ONLY, csi.GENX320_STC_TRAIL_ONLY та csi.GENX320_STC_TRAIL) та зчитування необроблених подій (csi.IOCTL_GENX320_READ_EVENTS_RAW), з новими прикладами скриптів.

  • MoveNet — новий постпроцесор MediaPipe для одного положення (аргументи threshold, nms_threshold, nms_sigma), що повертає ((x, y, w, h), score, keypoints) з 17-суглобним масивом ключових точок COCO; модель movenet_singlepose_192.tflite і приклад вбудовані на AE3 і N6.

  • ml.utils.draw_predictions() — новий необов’язковий аргумент scores= додає впевненість для кожної мітки, шрифт і товщина рамки тепер автоматично масштабуються відповідно до ширини зображення, а новий режим format="point" малює центральний маркер для детекторів центральних точок/піків.

  • Новий клас display.TVDisplay (з універсальним ioctl()) замінює окремий модуль tv. Дивіться зміни модуля display.

  • Новий детектор find_line_segments() (ED-Lines) — тепер доступний у всіх збірках, з новим аргументом threshold=. Дивіться зміни модуля image.

Інші зміни та покращення

  • MicroPython оновлено до 1.28.0 з бази v4.8.1. Додає режим SD-картки з високою швидкістю на H5/H7/N6, тактування AHB5 у режимі низького енергоспоживання та керовані виводи JTAG як GPIO на OPENMV_AE3.

  • ulab оновлено до 6.12.0 — нативний оператор % для ndarrays (допоміжна функція ml.utils.mod() видалена; дивіться зміни бібліотеки МН).

  • Інструментарій ST Edge AI оновлено до 4.0 — впливає на компіляцію та розгортання моделей ST безпосередньо на пристрої.

  • ml.Model — аргумент ключового слова load_to_fb видалено; пам’яттю моделі керує уніфікований алокатор автоматично.

  • image.Image.scale() на місці — масштабування зображення вгору на місці (наприклад, img.scale(x_scale=2.0, y_scale=2.0)) тепер розширює кадровий буфер за потреби, замість того щоб видавати помилку.

  • Більший буфер stdio — стандартний текстовий буфер для IDE збільшено з 512 до 1024 байт на OpenMV 2/3/4, Nicla Vision, AE3 і N6, тому більші пакети print() не обрізаються.

  • Плавніший потік подій хоста — події stdout NOTIFY до хоста обмежені не більше ніж одною на зчитування хостом, замість однієї на кожен print(), що перетинає водяний знак кільцевого буфера.

  • Перериваємі тривалі операції — тривалі цикли малювання зображень, GPU (Nema/Dave2D) та NPU тепер обслуговують події з визначеним інтервалом, тому скрипти залишаються реактивними до кнопки «Стоп» IDE під час інтенсивної роботи.

Виправлення помилок

Камера та датчики:

  • find_apriltags() більше не пошкоджує результати на платах з D-cache/GPU (N6, AE3) та тепер працює на AE3.

  • Виправлено виведення зображень Bayer з ISP STM32 N6 після зміни форматів пікселів.

  • Виправлено перегрів зеленого каналу в авто-балансі білого на яскравих сценах та неініціалізований стан статистики AWB першого кадру; підвищено обмеження гами ISP STM32 (з 32 до 63) для ширшого діапазону гама/контраст/яскравість.

  • Автоматична витримка PS5520 більше не коливається при яскравому освітленні; поведінка AEC/AGC PAG7936 була перероблена (комбіноване управління, виправлена стеля підсилення).

  • Відновлено завантаження мікропрограми автофокусу OV5640 на Portenta/Nicla (виправлення SUSPEND I2C MIMXRT).

  • Виправлено зависання захоплення камери при поєднанні обмеження частоти кадрів із захопленням JPEG (STM32).

  • Зчитування csi.IOCTL_GENX320_READ_EVENTS_RAW GenX320 більше не спотворюють попередній перегляд IDE.

  • FLIR Lepton csi.IOCTL_LEPTON_SET_MODE через csi.CSI.ioctl() тепер працює при виклику з одним аргументом.

Обробка зображень:

  • Виправлено альфа-змішування draw_image() / blend() при застосуванні маски.

  • Виправлено порядок бітів при кодуванні/декодуванні 1-бітного (BINARY) PNG та декодування відтінків сірого з 1-бітного формату.

  • Виправлено метадані тривалості/FPS запису mjpeg.Mjpeg.

  • Виправлено переповнення стека при програмному декодуванні JPEG на платах з малим стеком (OpenMV M7).

  • Виправлено автовизначення формату файлів JPEG/PNG на не-ARM хостах (симулятор).

Датчик часу прольоту (ToF):

  • tof.read_depth() більше не виникає виключення при тимчасових помилках вимірювання та автоматично відновлюється після збоїв шини; стандартний тайм-аут tof.read_depth() / tof.snapshot() тепер становить 100 мс (дивіться зміни tof).

  • Виправлено пошкодження даних глибини в мультизонному режимі VL53L5CX / VL53L8CX.

МН та система:

  • NPU коректно очищається при перериванні інференсу на N6.

  • Відновлено пробудження з глибокого сну / режиму очікування на N6; виправлено зависання переходу до завантажувача на AE3.

  • Виправлено витоки пам’яті при програмному скиданні (STM32 Nema GPU) та передчасно зібраний допоміжний кадровий буфер.

  • Власні канали протоколу Python тепер виживають після програмного перезавантаження, USB-транспорт відновлюється після скидання шини / заблокованих ендпоінтів, та виправлено переповнення перериваннями USB SOF.

Підтримка обладнання та плат

  • OpenMV N6 — увімкнено Ethernet (дротова мережа); AXI SRAM NPU (1,75 МБ) об’єднано у спільний тимчасовий пул для більшого обсягу RAM між інференсами; пробудження з глибокого сну/режиму очікування; вбудовані моделі TFLite та каскади Haar у ROMFS.

  • OpenMV AE3 — вбудовані моделі та каскади у ROMFS; cbor2 заморожений у мікропрограмі.

  • Alif (AE3, N6) — пробудження machine.RTC з низьким енергоспоживанням.

  • AprilTag з повною роздільною здатністюfind_apriltags() у повній роздільній здатності датчика на AE3, Arduino Giga та Arduino Portenta H7.

  • Цілі симулятора — MPS2_AN500 / MPS3_AN547 (Arm FVP / QEMU), з емуляцією NPU, ROMFS і PSRAM.

Несумісні зміни API

Видимі для користувача несумісності API між v4.8.1 і v5.0.0. Область: C-модулі Python у modules/ та бібліотеки Python у scripts/libraries/.

Кожна зміна позначена за її впливом:

  • major — більшість скриптів потребує редагування.

  • minor — вузький API; впливає лише на скрипти, що його використовували.

  • behavior — той самий API, інші результати; перевірте налаштовані скрипти.

  • tooling — впливає лише на збирання з вихідного коду / форки.

Зміни згруповані за впливом у такому порядку — спочатку major, потім minor, behavior та tooling. Якщо ви просто хочете перенести свій код, перейдіть до контрольного списку міграції в кінці для стислого переліку завдань. Кожен хеш коміту посилається на його diff на GitHub.

sensor замінено на csi (major)

Кожен офіційний приклад було переписано, щоб замінити import sensor на import csi. Старий функціональний API на рівні модуля (sensor.reset(), sensor.set_pixformat(), …) замінено клас-орієнтованим API csi.CSI, який природно масштабується на плати з кількома камерами (csi0, csi1, …) і є обов’язковим для всіх нових можливостей (аргумент stream=, потокова передача з кількох датчиків, …).

Рядок sensor qstr все ще підключено у modules/py_csi.c для збірок з підтримкою зворотної сумісності, але він не отримуватиме нових можливостей, і всі приклади, документація та бібліотечний код тепер передбачають csi.

Коміти: 945c5853c, 61f835b7e

Від модуля до класу

До (sensor):

import sensor
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
img = sensor.snapshot()

Після (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 об’єднані у комбіновані аксесори

У новому API метод, викликаний без аргументів, повертає поточне значення; викликаний зі значенням — встановлює його. Префіксів set_*/get_* більше немає. Назви методів також позбулися суфікса ing, де він був зайвим (windowingwindow). Стовпець нового API посилається на довідкову документацію.

sensor (старий)

csi.CSI (новий)

set_pixformat(fmt) / get_pixformat()

pixformat([fmt])

set_framesize(sz) / get_framesize()

framesize([sz])

set_framerate(fps) / get_framerate()

framerate([fps])

set_windowing(roi) / get_windowing()

window([roi])

set_framebuffers(n) / get_framebuffers()

framebuffers([n])

set_gainceiling(g)

gainceiling([g])

set_brightness(v)

brightness([v])

set_contrast(v)

contrast([v])

set_saturation(v)

saturation([v])

set_quality(v)

quality([v])

set_colorbar(b)

colorbar([b])

set_special_effect(e)

special_effect([e])

set_lens_correction(...)

lens_correction(...)

set_hmirror(b) / get_hmirror()

hmirror([b])

set_vflip(b) / get_vflip()

vflip([b])

set_transpose(b) / get_transpose()

transpose([b])

set_auto_rotation(b) / get_auto_rotation()

auto_rotation([b])

set_auto_gain(b, [db, ceiling]) / get_gain_db()

auto_gain(...) / gain_db()

set_auto_exposure(b, [us]) / get_exposure_us()

auto_exposure(...) / exposure_us()

set_auto_whitebal(b, [rgb]) / get_rgb_gain_db()

auto_whitebal(...) / rgb_gain_db()

set_auto_blc(b, [regs]) / get_blc_regs()

auto_blc(...) / blc_regs()

set_color_palette(p) / get_color_palette()

color_palette([p])

set_frame_callback(cb)

frame_callback(cb)

set_vsync_callback(cb)

vsync_callback(cb)

get_id()

cid()

Функції без прямого еквівалента

sensor (видалено)

Що використовувати натомість

sensor.alloc_extra_fb(w, h, pixfmt) / sensor.dealloc_extra_fb()

image.Image (w, h, pixfmt) — звичайне зображення, виділене у купі. Кадровий буфер більше не нарізається для буферів користувача.

sensor.skip_frames(time=..., frames=...)

csi.CSI.snapshot() — пропуск кадрів інтегровано у snapshot через аргументи time= / frames=.

sensor.disable_delays(...) / sensor.disable_full_flush(...)

Переміщено у конструктор csi.CSI: csi.CSI(delays=False) / csi.CSI(fflush=False).

sensor.get_frame_available()

csi.CSI.readable()

sensor.get_fb()

Видалено. Зображення, повернуте csi.CSI.snapshot(), є канонічним дескриптором.

sensor.set_framebuffers(n, expand=True)

csi.CSI.framebuffers() — аргумент expand видалено (дивіться подальші зміни csi).

Нове у csi.CSI

  • csi.CSI(stream=True|False) — селектор часу конструювання, що визначає, який CSI подається у кадровий буфер попереднього перегляду (замінює аргумент update= для кожного знімка, дивіться подальші зміни csi).

  • csi.CSI(cid=N) / csi.devices() — підтримка декількох CSI для плат із кількома датчиками зображення.

Модуль image — переробка сигнатур (major)

Модуль image зазнав найширших змін API після csi — змінились сигнатури малювання, об’єкти результатів і декілька детекторів.

Аргументи координат мають бути кортежами

modules/py_image.c було переписано на основі mp_arg_parse_all. Усі методи малювання/піксельні методи, які раніше приймали окремі позиційні аргументи x, y, ..., тепер вимагають пакування цих координат в один кортеж.

Коміти: d18bbc472, 0c60c94b9 (PR #3061)

До

Після

img.draw_arrow(x0, y0, x1, y1, color=...)

img.draw_arrow((x0, y0, x1, y1), color=...)

img.draw_line(x0, y0, x1, y1, ...)

img.draw_line((x0, y0, x1, y1), ...)

img.draw_cross(x, y, ...)

img.draw_cross((x, y), ...)

img.draw_circle(x, y, r, ...)

img.draw_circle((x, y, r), ...)

img.draw_rectangle(x, y, w, h, ...)

img.draw_rectangle((x, y, w, h), ...)

img.draw_string(x, y, "txt", ...)

img.draw_string((x, y), "txt", ...)

img.draw_ellipse(x, y, rx, ry, rot, ...)

img.draw_ellipse((x, y, rx, ry, rot), ...)

img.flood_fill(x, y, ...)

img.flood_fill((x, y), ...)

img.get_pixel(x, y, rgbtuple=...)

img.get_pixel((x, y), rgbtuple=...)

img.set_pixel(x, y, color)

img.set_pixel((x, y), color)

Усі є методами image.Image.

Об’єкти результатів перетворені на attrtuple

Ці типи тепер є об’єктами MicroPython attrtuple: similarity, statistics, percentile, threshold, line, circle, rect, qrcode, apriltag, datamatrix, barcode, displacement, kptmatch. Доступ до атрибутів без дужок тепер є канонічним.

Коміт: 3399d302e

До (стиль методів):

img.draw_cross(match.cx(), match.cy())
img.draw_rectangle(blob.rect())

Після (стиль атрибутів):

img.draw_cross((match.cx, match.cy))
img.draw_rectangle(blob.rect)

blob та histogram залишаються незмінними — вони зберігають свої існуючі типи та аксесори () (attrtuple не може виражати ліниво обчислювані значення blob або аксесори histogram, що приймають аргументи).

Перейменування параметра haar у find_features

image.Image.find_features()scale_factor= перейменовано на scale=.

Коміт: be4c5cd73

get_regression — тепер завжди робастна, додано target_size

image.Image.get_regression() тепер завжди використовує робастну регресію (Theil-Sen). Старий швидкий шлях методу найменших квадратів видалено, тому аргумент robust= відсутній — те, що раніше вимагало robust=True, тепер є єдиною поведінкою. Новий аргумент target_size=(w, h) (за замовчуванням (80, 60)) масштабує ROI вниз за площею перед O(N^2) підбором Theil-Sen, щоб він завжди працював на нормальному розмірі зображення; кінцеві точки підібраної лінії відображаються назад до вихідних координат. Приклад linear_regression_robust.py видалено, а linear_regression_fast.py перейменовано на linear_regression.py.

Коміти: c7c2e69a0, 0ff2afa72

find_line_segments — новий алгоритм

image.Image.find_line_segments() — старий детектор LSD замінено на ED-Lines, і додано новий аргумент threshold=50. Результати раніше налаштованих скриптів відрізнятимуться.

Коміти: 87da2a7b7, 2c47b5735

Бібліотека AprilTag замінена

image.Image.find_apriltags() — детектор AprilTag замінено новою реалізацією. Набір сімейств змінився:

Видалено

Додано

image.TAG25H7, image.ARTOOLKIT

image.TAGCIRCLE21H7, image.TAGCIRCLE49H12, image.TAGCUSTOM48H12, image.TAGSTANDARD41H12, image.TAGSTANDARD52H13

Коміт: e813bada7

Подальші зміни модуля csi (minor)

Дрібніші подальші зміни csi на додаток до міграції csi.

snapshot(update=…) видалено

Аргумент update у csi.CSI.snapshot() видалено. Щоб запобігти подачі пристрою CSI у кадровий буфер попереднього перегляду, вимкніть це при конструюванні:

csi0 = csi.CSI(stream=False)                  # was: csi0.snapshot(update=False)
csi1.snapshot(blocking=False, image=fir_img)  # was: ...(update=False, ...)

Коміти: 9a8077827, 26b79a2c5

Аргумент expand у framebuffers() видалено

csi.CSI.framebuffers() — третій позиційний аргумент (expand) видалено; сигнатура тепер framebuffers([count]).

Коміт: 86cb3a5de

Модуль protocol (minor)

Стосується лише скриптів, що напряму керували з’єднанням із хостом. Дивіться protocol.

timer_ms перейменовано на poll_ms

protocol.init() — аргумент timer_ms перейменовано на poll_ms.

protocol.init(..., poll_ms=10)   # was: timer_ms=10

Коміти: 8a0635e8c, 95a290607

protocol.poll() видалено

Завдання протоколу тепер планується внутрішньо. Виклики protocol.poll() видаватимуть AttributeError.

Коміт: 8a0635e8c

Аргумент конфігурації soft_reboot видалено

protocol.init() — аргумент soft_reboot видалено. Усі поточні транспорти підтримують програмні перезавантаження, тому поведінка тепер є безумовною.

Коміт: 0bf766aa2

Модулі display (minor)

Виведення на ТВ тепер здійснюється через об’єкт display.TVDisplay замість окремого модуля tv. display також отримав універсальний ioctl().

Коміти: f0accb389, 1a5a87121, 920c097a0, 9eac55098

Модуль tof (behavior)

Той самий API, що й раніше; змінились стандартні значення та обробка помилок. Дивіться tof.

Стандартний тайм-аут змінено

tof.read_depth() та tof.snapshot() (викликані з timeout=-1) тепер за замовчуванням 100 мс замість нескінченного очікування. Передайте явне більше значення, якщо вам потрібна стара поведінка.

Коміт: b6772b80d

Автоматичне відновлення

Драйвер тепер виконує жорстке скидання шини I2C та датчика при помилках вимірювання/тайм-аутах. Приклади більше не викликають tof.reset() у своїх обробниках виключень — користувацький код з ручним відновленням слід його видалити (він буде конфліктувати з новим авто-відновленням).

Коміти: b6772b80d, 80ffaa5c3

Бібліотека МН (behavior)

Той самий API, інші результати — перевірте будь-який налаштований конвеєр МН.

Попередня обробка тепер розтягує замість letterbox

Normalization тепер використовує image.SCALE_ASPECT_IGNORE (розтягування) замість image.SCALE_ASPECT_EXPAND (letterbox). Постобробка NMS також перейшла до незалежного масштабування по x/y.

Примітка

Вплив. Детектори у стилі YOLO та регресори ключових точок загалом покращуються. Приклади BlazeFace, BlazePalm, FaceLandmarks та HandLandmarks тепер вимагають ручного квадратного обрізання вхідного ROI — приклади скриптів оновлено; власний користувацький код повинен зробити те саме.

Коміт: 68dc29a33

Допоміжна функція ml.utils.mod() видалена

ulab 6.12.0 підтримує % для ndarrays нативно. Код, що імпортував mod з ml.utils, має використовувати a % b.

Коміти: 35ece5728, 82fbd858c

Збірка / інструментарій (tooling)

Жодне з цього не впливає на скрипти MicroPython. Збірка мікропрограми з вихідного коду тепер вимагає зовнішнього OpenMV SDK (1.6.0, раніше вбудованого). Кілька вбудованих інструментів збірки було видалено, а N6 перейшов на стек TinyUSB; downstream-форки повинні переглянути репозиторій мікропрограми — зокрема сигнатуру file_open(), яка втратила аргумент buffered.

Контрольний список міграції

Для чистого переходу на v5.0.0 типова робота така:

  1. Замінити import sensor на import csi; csi0 = csi.CSI() та перетворити кожен виклик set_*/get_* на відповідний аксесор csi.CSI (міграція csi).

  2. Упакуйте аргументи координат для img.draw_*, get_pixel() та set_pixel() у кортежі (зміни модуля image).

  3. Видаліть () з аксесорів результатів attrtuple, якщо ви хочете використовувати новий ідіоматичний стиль, або залиште старий стиль — attrtuples продовжують підтримувати виклик аксесорів (зміни модуля image).

  4. Перевірте find_line_segments(), get_regression() та будь-який вибір сімейства find_apriltags() (зміни модуля image).

  5. Перейменуйте timer_mspoll_ms у викликах protocol.init(); видаліть protocol.poll() та soft_reboot= (зміни модуля protocol).

  6. Для робочих процесів МН: перегляньте будь-яку модель, що вимагала letterbox-вводу (зміни бібліотеки МН).