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 замінено новою реалізацією. Набір сімейств змінився:

Коміт: 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-вводу (зміни бібліотеки МН).