v5.0.0

v5.0.0 este o versiune majoră. Punctele principale: legătura cu gazda OpenMV Protocol V2 reconstruită, un API de cameră csi bazat pe clase care se extinde la plăci cu mai multe camere, o țintă simulator executabilă, estimarea pozei unice MoveNet, MicroPython 1.28 și un lot mare de corecții pentru cameră, ML și ToF. Aduce de asemenea o serie de modificări incompatibile de API — fiecare schimbare vizibilă pentru utilizator de la v4.8.1 este listată mai jos, împreună cu modul exact de migrare.

Puncte principale

  • OpenMV Protocol V2. Legătura gazdă/IDE a fost reconstruită de la zero: încadrată, secvențiată, verificată cu CRC, cu canale multiplexate pentru stdio, previzualizarea fluxului și datele utilizatorului. Un nou modul protocol permite scripturilor să își creeze propriile transporturi și canale de date. Vedeți modificările modulului protocol.

  • API de cameră csi bazat pe clase. import sensor devine import csi / csi.CSI, cu suport nativ pentru mai multe camere. Vedeți migrarea către csi.

  • Țintă simulator. Firmware-ul se compilează și rulează acum sub simulatorul Arm FVP / QEMU (MPS2/MPS3), inclusiv emularea NPU, ROMFS și PSRAM — scripturile de viziune și ML pot rula fără hardware atașat.

  • Estimarea pozei MoveNet. Un nou post-procesor MoveNet plus un model movenet_singlepose_192.tflite inclus pe OpenMV AE3 și N6.

  • MicroPython 1.28 și ulab 6.12.0, instrumentar ST Edge AI 4.0 și OpenMV SDK externalizat (vedeți modificările de compilare / instrumentar).

Caracteristici noi

  • Modulul protocol — creați transporturi și canale de date personalizate din Python: protocol.init(), protocol.register(), protocol.is_active() și o clasă protocol.ProtocolChannel cu send_event(), plus constantele CHANNEL_FLAG_* și CHANNEL_ID_*. Semnătura finală a protocol.init() este documentată în modificările modulului protocol.

  • protocol.CBORChannel — un pachet de extensie protocol înghețat care serializează câmpuri denumite în CBOR, cu widget-uri de afișare (etichetă, adâncime) și controale interactive (comutator, glisor, selecție).

  • Introspecția memoriei gazdei și a fluxului — o nouă comandă de protocol SYS_MEMORY expune IDE-ului statistici de memorie de execuție per-pool, iar un nou ioctl de flux STREAM_SOURCE permite gazdei să aleagă care cameră alimentează previzualizarea pe plăcile cu mai multe camere (versiunea de protocol 1.0.1).

  • Difuzarea de la mai multe camerecsi.CSI acceptă un argument stream= care selectează care senzor alimentează previzualizarea IDE; antetul cadrului de flux poartă acum un FPS netezit cu EMA, astfel încât IDE-ul afișează rata de cadre fără șablonul clock.fps(). Vedeți migrarea către csi și continuările csi.

  • Senzorul de evenimente GenX320 — un nou filtru Spatio-Temporal Contrast (csi.IOCTL_GENX320_SET_STC cu modurile csi.GENX320_STC_DISABLE, csi.GENX320_STC_ONLY, csi.GENX320_STC_TRAIL_ONLY și csi.GENX320_STC_TRAIL) și citirea brută a evenimentelor (csi.IOCTL_GENX320_READ_EVENTS_RAW), cu scripturi de exemplu noi.

  • MoveNet — un nou post-procesor MediaPipe de poză unică (argumentele cu cuvânt-cheie threshold, nms_threshold, nms_sigma) care returnează ((x, y, w, h), score, keypoints) cu un tablou de puncte-cheie COCO cu 17 articulații; un model movenet_singlepose_192.tflite și un exemplu sunt incluse pe AE3 și N6.

  • ml.utils.draw_predictions() — un nou argument opțional scores= adaugă încrederea per-etichetă, fontul și grosimea conturului casetei se scalează acum automat la lățimea imaginii, iar un nou mod format="point" desenează un marcaj central pentru detectorii de tip centerpoint/peak.

  • Noua clasă display.TVDisplay (cu un ioctl() generic) înlocuiește modulul de sine stătător tv. Vedeți modificările modulului display.

  • Un nou detector find_line_segments() (ED-Lines) — acum disponibil în toate compilările, cu un nou argument threshold=. Vedeți modificările modulului image.

Alte modificări și îmbunătățiri

  • MicroPython actualizat la 1.28.0 de la baza v4.8.1. Adaugă modul de card SD de mare viteză pe H5/H7/N6, ceasul AHB5 în modul de consum redus și pini JTAG controlabili ca GPIO-uri pe OPENMV_AE3.

  • ulab actualizat la 6.12.0 — operatorul % nativ pe ndarray-uri (funcția ajutătoare ml.utils.mod() este eliminată; vedeți modificările bibliotecii ML).

  • Instrumentarul ST Edge AI actualizat la 4.0 — afectează compilarea și implementarea modelelor ST pe dispozitiv.

  • ml.Model — argumentul cu cuvânt-cheie load_to_fb a fost eliminat; memoria modelului este gestionată automat de alocatorul unificat.

  • image.Image.scale() pe loc — scalarea unei imagini în sus pe loc (de exemplu img.scale(x_scale=2.0, y_scale=2.0)) crește acum tamponul de cadre (frame buffer) pentru a se potrivi, în loc să eșueze.

  • Tampon stdio mai mare — tamponul de text implicit către IDE a crescut de la 512 la 1024 octeți pe OpenMV 2/3/4, Nicla Vision, AE3 și N6, astfel încât rafalele mai mari de print() nu sunt trunchiate.

  • Flux de evenimente către gazdă mai fluent — evenimentele NOTIFY de stdout către gazdă sunt limitate la cel mult unul per citire a gazdei, în loc de unul per print() care trece de pragul tamponului inelar.

  • Operații lungi întreruptibile — buclele lungi de desenare a imaginilor, GPU (Nema/Dave2D) și de așteptare NPU servesc acum evenimentele la un interval determinist, astfel încât scripturile rămân receptive la butonul Stop al IDE-ului în timpul lucrului intens.

Corecții de erori

Cameră și senzori:

  • find_apriltags() nu mai corupe rezultatele pe plăcile cu D-cache/GPU (N6, AE3) și funcționează acum pe AE3.

  • S-a corectat ieșirea imaginii Bayer de la ISP-ul STM32 N6 după schimbarea formatelor de pixeli.

  • S-a corectat supraexpunerea verde a balansului automat de alb pe scenele luminoase și un caz de statistici AWB neinițializate la primul cadru; s-a ridicat limitarea gamma a ISP-ului STM32 (de la 32 la 63) pentru un interval mai larg de gamma/contrast/luminozitate.

  • Auto-expunerea PS5520 nu mai oscilează în lumină puternică; comportamentul AEC/AGC al PAG7936 a fost reproiectat (control combinat, plafon de amplificare (gain) corectat).

  • Încărcarea firmware-ului de autofocalizare OV5640 a fost restaurată pe Portenta/Nicla (corecție MIMXRT I2C SUSPEND).

  • S-a corectat un blocaj la captarea camerei când o limită a ratei de cadre este combinată cu captarea JPEG (STM32).

  • Citirile GenX320 csi.IOCTL_GENX320_READ_EVENTS_RAW nu mai bruiază previzualizarea IDE.

  • FLIR Lepton csi.IOCTL_LEPTON_SET_MODE prin csi.CSI.ioctl() funcționează acum când este apelat cu un singur argument.

Procesarea imaginilor:

  • S-a corectat amestecarea alfa draw_image() / blend() când este furnizată o mască.

  • S-a corectat ordinea biților la codarea/decodarea PNG pe 1 bit (BINARY) și decodarea în tonuri de gri din 1 bit.

  • S-au corectat metadatele de durată/FPS la înregistrarea mjpeg.Mjpeg.

  • S-a corectat o depășire de stivă la decodarea software a JPEG pe plăcile cu stivă mică (OpenMV M7).

  • S-a corectat detectarea automată a formatului de fișier JPEG/PNG pe gazdele non-ARM (simulator).

Time-of-Flight:

  • tof.read_depth() nu mai generează excepții la erori tranzitorii de telemetrie și se recuperează automat din defecțiunile de magistrală; timeout-ul implicit pentru tof.read_depth() / tof.snapshot() este acum de 100 ms (vedeți modificările tof).

  • S-a corectat coruperea datelor de adâncime multi-zonă VL53L5CX / VL53L8CX.

ML și sistem:

  • NPU este curățat corect când inferența este întreruptă pe N6.

  • Trezirea din somn profund / standby a fost restaurată pe N6; blocajul saltului la bootloader al AE3 este corectat.

  • S-au corectat scurgerile de memorie la resetare software (STM32 Nema GPU) și un tampon de cadre (frame buffer) auxiliar colectat prematur.

  • Canalele de protocol Python personalizate supraviețuiesc acum unei reporniri software, transportul USB se recuperează din resetarea magistralei / endpoint-urile blocate, iar inundarea cu întreruperi USB SOF este corectată.

Suport hardware și plăci

  • OpenMV N6 — Ethernet activat (rețea cu fir); NPU AXI SRAM (1,75 MB) integrat într-un pool tranzitoriu partajat pentru mai multă RAM între inferențe; trezire din somn profund/standby; modele TFLite și cascade Haar incluse în ROMFS.

  • OpenMV AE3 — modele și cascade incluse în ROMFS; cbor2 înghețat în firmware.

  • Alif (AE3, N6) — trezire machine.RTC cu consum redus.

  • AprilTag de înaltă rezoluțiefind_apriltags() la rezoluția completă a senzorului pe AE3, Arduino Giga și Arduino Portenta H7.

  • Ținte simulator — MPS2_AN500 / MPS3_AN547 (Arm FVP / QEMU), cu emulare NPU, ROMFS și PSRAM.

Modificări incompatibile de API

Modificări de API vizibile pentru utilizator între v4.8.1 și v5.0.0. Domeniu: C-module Python în modules/ și biblioteci Python în scripts/libraries/.

Fiecare modificare este etichetată cu impactul său:

  • major — majoritatea scripturilor necesită modificări.

  • minor — API restrâns; afectează doar scripturile care l-au folosit.

  • comportament — același API, rezultate diferite; reverificați scripturile reglate.

  • instrumentar — afectează doar compilarea din sursă / fork-urile derivate.

Modificările sunt grupate după impact în această ordine — major mai întâi, apoi minor, comportament și instrumentar. Dacă doriți doar să vă portați codul, săriți la lista de verificare a migrării de la final pentru o listă de sarcini condensată. Fiecare hash de commit are legătură către diff-ul său de pe GitHub.

sensor înlocuit cu csi (major)

Fiecare exemplu oficial a fost rescris pentru a renunța la import sensor în favoarea import csi. Vechiul API funcțional la nivel de modul (sensor.reset(), sensor.set_pixformat(), …) este înlocuit de API-ul csi.CSI bazat pe clase, care se extinde natural la plăcile cu mai multe camere (csi0, csi1, …) și este necesar pentru toate caracteristicile noi (argumentul cu cuvânt-cheie stream=, difuzarea de la mai mulți senzori, …).

Qstr-ul sensor este încă conectat în modules/py_csi.c pentru compilări de firmware compatibile retroactiv, dar nu va primi caracteristici noi, iar toate exemplele, documentația și codul de bibliotecă presupun acum csi.

Commit-uri: 945c5853c, 61f835b7e

De la modul la clasă

Înainte (sensor):

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

După (csi):

import csi
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)
img = csi0.snapshot()

Perechile setter/getter comprimate în accesori combinați

În noul API, o metodă apelată fără argumente returnează valoarea curentă; apelată cu o valoare, o setează. Prefixele set_*/get_* au dispărut. Numele metodelor au pierdut de asemenea sufixul ing acolo unde era redundant (windowingwindow). Coloana cu noul API are legături către documentația de referință.

sensor (vechi)

csi.CSI (nou)

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()

Funcții fără echivalent direct

sensor (eliminat)

Ce să folosiți în schimb

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

image.Image (w, h, pixfmt) — o imagine obișnuită alocată pe heap. Tamponul de cadre (frame buffer) nu mai este împărțit pentru tampoanele utilizatorului.

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

csi.CSI.snapshot() — saltul de cadre integrat în snapshot prin argumentele sale time= / frames=.

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

Mutate în constructorul csi.CSI: csi.CSI(delays=False) / csi.CSI(fflush=False).

sensor.get_frame_available()

csi.CSI.readable()

sensor.get_fb()

Eliminat. Imaginea returnată de csi.CSI.snapshot() este referința canonică.

sensor.set_framebuffers(n, expand=True)

csi.CSI.framebuffers() — argumentul expand a fost eliminat (vedeți continuările csi).

Nou pe csi.CSI

  • csi.CSI(stream=True|False) — un selector la momentul construirii care alege care CSI alimentează tamponul de cadre (frame buffer) de previzualizare (înlocuiește argumentul cu cuvânt-cheie update= per-instantaneu, vedeți continuările csi).

  • csi.CSI(cid=N) / csi.devices() — suport multi-CSI pentru plăcile cu mai mult de un senzor de imagine.

modulul image — revizuire a semnăturilor (major)

Modulul image a cunoscut cea mai amplă modificare de API după csi — semnăturile de desenare, obiectele de rezultat și mai mulți detectori s-au schimbat cu toții.

Argumentele de coordonate trebuie să fie tupluri

modules/py_image.c a fost rescris pe baza mp_arg_parse_all. Toate metodele de desenare / pixel care anterior luau argumente poziționale separate x, y, ... necesită acum aceste coordonate împachetate într-un singur tuplu.

Commit-uri: d18bbc472, 0c60c94b9 (PR #3061)

Înainte

După

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)

Toate sunt metode ale image.Image.

Obiectele de rezultat convertite la attrtuple

Aceste tipuri sunt acum obiecte MicroPython attrtuple: similarity, statistics, percentile, threshold, line, circle, rect, qrcode, apriltag, datamatrix, barcode, displacement, kptmatch. Accesul la atribute fără paranteze este acum forma canonică.

Commit: 3399d302e

Înainte (stil metodă):

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

După (stil atribut):

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

blob și histogram sunt neschimbate — își păstrează tipurile existente și accesorii () (un attrtuple nu poate exprima valorile calculate leneș ale unui blob sau accesorii cu argumente ai unei histograme).

Redenumirea parametrului haar al find_features

image.Image.find_features()scale_factor= a fost redenumit în scale=.

Commit: be4c5cd73

get_regression — acum întotdeauna robust, target_size adăugat

image.Image.get_regression() folosește acum întotdeauna regresia robustă (Theil-Sen). Vechea cale rapidă a celor mai mici pătrate a fost eliminată, deci cuvântul-cheie robust= a dispărut — ceea ce necesita anterior robust=True este acum singurul comportament. Un nou argument cu cuvânt-cheie target_size=(w, h) (implicit (80, 60)) scalează aria ROI-ului în jos înainte de potrivirea Theil-Sen O(N^2), astfel încât să ruleze întotdeauna pe o dimensiune de imagine rezonabilă; capetele liniei potrivite sunt mapate înapoi la coordonatele sursă. Exemplul linear_regression_robust.py a fost șters, iar linear_regression_fast.py a fost redenumit în linear_regression.py.

Commit-uri: c7c2e69a0, 0ff2afa72

find_line_segments — algoritm nou

image.Image.find_line_segments() — vechiul detector LSD a fost înlocuit de ED-Lines și a câștigat un nou argument cu cuvânt-cheie threshold=50. Rezultatele scripturilor reglate anterior vor diferi.

Commit-uri: 87da2a7b7, 2c47b5735

Biblioteca AprilTag înlocuită

image.Image.find_apriltags() — detectorul AprilTag a fost înlocuit cu o nouă implementare. Setul de familii s-a schimbat:

Commit: e813bada7

continuare a modulului csi (minor)

Continuări csi mai mici, peste migrarea către csi.

snapshot(update=…) eliminat

Argumentul cu cuvânt-cheie update de pe csi.CSI.snapshot() a dispărut. Pentru a împiedica un dispozitiv CSI să alimenteze tamponul de cadre (frame buffer) de previzualizare, renunțați la momentul construirii:

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

Commit-uri: 9a8077827, 26b79a2c5

argumentul expand al framebuffers() eliminat

csi.CSI.framebuffers() — al treilea argument pozițional (expand) a dispărut; semnătura este acum framebuffers([count]).

Commit: 86cb3a5de

modulul protocol (minor)

Afectează doar scripturile care au acționat direct legătura cu gazda. Vedeți protocol.

timer_ms redenumit în poll_ms

protocol.init() — argumentul timer_ms a fost redenumit în poll_ms.

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

Commit-uri: 8a0635e8c, 95a290607

protocol.poll() eliminat

Sarcina de protocol este acum programată intern. Apelurile la protocol.poll() vor genera AttributeError.

Commit: 8a0635e8c

argumentul de configurare soft_reboot eliminat

protocol.init() — argumentul soft_reboot a dispărut. Toate transporturile curente tolerează repornirile software, deci comportamentul este acum necondiționat.

Commit: 0bf766aa2

module display (minor)

Ieșirea TV trece acum printr-un obiect display.TVDisplay în loc de modulul de sine stătător tv. display a câștigat de asemenea un ioctl() generic.

Commit-uri: f0accb389, 1a5a87121, 920c097a0, 9eac55098

modulul tof (comportament)

Același API ca înainte; valorile implicite și gestionarea erorilor s-au schimbat. Vedeți tof.

Timeout-ul implicit modificat

tof.read_depth() și tof.snapshot() (apelate cu timeout=-1) au acum implicit 100 ms în loc să aștepte la nesfârșit. Transmiteți o valoare explicită mai mare dacă aveți nevoie de vechiul comportament.

Commit: b6772b80d

Recuperare automată

Driverul resetează acum hard magistrala I2C și senzorul la erori de telemetrie/timeout. Exemplele nu mai apelează tof.reset() în gestionarele lor de excepții — codul utilizatorului care făcea recuperare manuală ar trebui să o elimine (va intra în conflict cu noua recuperare automată).

Commit-uri: b6772b80d, 80ffaa5c3

biblioteca ML (comportament)

Același API, numere diferite — reverificați orice pipeline ML reglat.

Preprocesarea acum întinde în loc să folosească letterbox

Normalization folosește acum image.SCALE_ASPECT_IGNORE (întindere) în loc de image.SCALE_ASPECT_EXPAND (letterbox). Post-procesarea NMS a trecut de asemenea la scalare independentă pe x/y.

Notă

Impact. Detectorii de tip YOLO și regresorii de puncte-cheie se îmbunătățesc în general. Exemplele BlazeFace, BlazePalm, FaceLandmarks și HandLandmarks necesită acum o decupare pătrată manuală pe ROI-ul de intrare — scripturile de exemplu au fost actualizate; codul personalizat al utilizatorului trebuie să facă la fel.

Commit: 68dc29a33

funcția ajutătoare ml.utils.mod() eliminată

ulab 6.12.0 acceptă % pe ndarray-uri nativ. Codul care importa mod din ml.utils trebuie să folosească a % b.

Commit-uri: 35ece5728, 82fbd858c

Compilare / instrumentar (instrumentar)

Niciuna dintre acestea nu afectează scripturile MicroPython. Compilarea firmware-ului din sursă necesită acum OpenMV SDK extern (1.6.0, anterior inclus în arbore). Mai multe instrumente de compilare din arbore au fost eliminate, iar N6 a trecut la stiva TinyUSB; fork-urile derivate ar trebui să revizuiască istoricul depozitului de firmware — în special semnătura file_open() care renunță la argumentul său buffered.

Lista de verificare a migrării

Pentru o portare curată la v5.0.0, lucrul tipic este:

  1. Înlocuiți import sensor cu import csi; csi0 = csi.CSI() și traduceți fiecare apel set_*/get_* în accesorul său csi.CSI (migrarea către csi).

  2. Împachetați argumentele de coordonate către img.draw_*, get_pixel() și set_pixel() în tupluri (modificările modulului image).

  3. Renunțați la () din accesorii de rezultat attrtuple dacă doriți noua formă idiomatică, sau lăsați vechiul stil neatins, deoarece attrtuple-urile încă acceptă accesori apelabili (modificările modulului image).

  4. Auditați find_line_segments(), get_regression() și orice alegere de familie find_apriltags() (modificările modulului image).

  5. Redenumiți timer_mspoll_ms în apelurile protocol.init(); eliminați protocol.poll() și soft_reboot= (modificările modulului protocol).

  6. Pentru fluxurile de lucru ML: reexaminați orice model care avea nevoie de intrare letterbox (modificările bibliotecii ML).