v5.0.1#
v5.0.1 ist ein Wartungs-Release auf Basis von v5.0.0 — das veraltete sensor-Modul wird zu einer Python-Kompatibilitätsschicht über csi, in den Framebuffer geladene Bilder erscheinen nun wie Kamerabilder in der Vorschau, die JPEG-Encoder verlieren ihr 1-MB-Ausgabelimit und behandeln Überläufe korrekt, und es gibt eine Reihe von Korrekturen für Kamera, Protokoll, Netzwerk und ML-Bibliothek. Es bringt keine API-Brüche für Skripte mit sich, die gegen csi geschrieben wurden; die wenigen Verhaltensänderungen sind unter API-Brüche aufgeführt.
Highlights#
Das Modul
sensorist jetzt ein eingefrorenes Python-Modul, das aufcsiaufbaut. Beim Import gibt es eine Veraltet-Warnung aus; einige Funktionen, die dascsi-Modul nicht unterstützen kann, lösen nunOSErroraus. Siehe die Änderungen am sensor-Modul.Geladene Bilder erscheinen in der Vorschau wie Kamerabilder. Ein mit
copy_to_fb=Truein den Framebuffer gelegtes Bild (image.Image,image.ImageIO.read(),fir.snapshot(),tof.snapshot()) wird — mit allem, was darauf gezeichnet wurde — an die IDE ausgegeben, wenn das nächste Bild den Framebuffer überschreibt, statt sofort. Siehe die Änderungen an der Vorschau.Überarbeitung der JPEG-Encoder. Die 1-MB-Obergrenze für den Ausgabepuffer ist weg (der Puffer wird anhand des freien Speichers dimensioniert), Überläufe werden sowohl auf dem Software- als auch auf dem Hardware-Pfad behandelt, statt abgeschnittene Dateien zu schreiben, und das Speichern eines komprimierten Bildes unter der jeweils anderen komprimierten Dateiendung löst eine Ausnahme aus, statt Datenmüll zu schreiben.
Neu:
protocol.poll()sowie sechs neue CBOR-Widgets (text,lineedit,pushbutton,spinbox,radio,waveform) fürprotocol.CBORChannel.YOLO Pro-Postprozessor, Unterstützung für FLIR Lepton 3.1R / UW, IMU-Burst-Lesevorgänge, CAN auf dem OpenMV N6 und ein netzwerkfähiges Simulator-Target.
Neue Funktionen#
YoloPro— ein neuer Postprozessor für Edge Impulse YOLO Pro-Objekterkennungsmodelle, plus einyolo_pro_detector.py-Beispiel. (f3f150ebd, ea7bbb398)protocol.poll()— führt bei Bedarf eine Iteration der Protokoll-Task aus, für benutzerdefinierte Transporte, die weder vom USB-Interrupt noch vompoll_ms-Timer angetrieben werden.protocol.init()kann außerdem erneut aufgerufen werden, um den Stack neu zu initialisieren. (c00c215f9, f849ffb1b)Weitere CBOR-Kanal-Widgets —
protocol.CBORChannel.add()erhälttext(statischer String),lineedit(beschreibbarer String),pushbutton(momentane Aktion),spinbox(schrittweise Zahleneingabe),radio(Optionsgruppe) undwaveform(1D-Zeitreihe mit den Argumentensample_rate,seriesundtypecode; weisen Sie verschachtelte Abtastwert-Bytes zu, um sie zu streamen). (8016d29ba)csi.CUSTOM—csi.CSI.framesize()gibt nun nach dem Setzen einer benutzerdefinierten(w, h)-Auflösung eine verwendbare Konstante zurück statt einer anonymen Ganzzahl. (af8841654)IMU-Burst-Lesevorgang —
imu.__read_reg()akzeptiert einen optionalen beschreibbaren Puffer und füllt ihn in einer Transaktion aus aufeinanderfolgenden Registern. (244ca480a)FLIR Lepton 3.1R und Lepton UW werden vom Lepton-Treiber erkannt, einschließlich ihrer radiometrischen Gain-Modi. (0fc356632)
Simulator-Netzwerk — das
MPS2_AN500-QEMU-Target hat nun lwIP und eine User-Mode-NIC, mit eingefrorenemrequests,mqttundsensorsowie einem Netzwerk-Unit-Test. (23546dfb1, 61d187305, 15096c3a2)Beispiel für eine OpenAI-kompatible API —
openai_compatible.pynimmt ein JPEG auf und sendet es per POST an einen Chat-Completions-Endpunkt zur Szenenbeschreibung. (79033c6aa)SX126x-LoRa-Beispiele — der
lora-sx126x-Treiber aus micropython-lib (mitlora-sync/lora-async) ist in die OpenMV RT1062-Firmware eingefroren, mit Sender-/Empfänger-/Ping-Pong-/Bildstream-Beispielen für den Anschluss eines SX1261- oder SX1262-Moduls an den SPI-Bus. Dies ist von der Community beigesteuerte Unterstützung; OpenMV verkauft keine LoRa-Hardware. (19576e1b1)
Weitere Änderungen und Verbesserungen#
Neuimplementierung der Bibliothek
requests— Antworten mit Chunked Transfer werden decodiert, eintimeout-Argument (Standard 5 s) wird bereitgestellt, JSON- und String-Bodys werden korrekt serialisiert/kodiert, Header werden ohne Berücksichtigung der Groß-/Kleinschreibung und die Statuszeile positionsbasiert geparst, dasheaders-Dict des Aufrufers wird kopiert (sodassauthnicht mehr in spätere Anfragen durchsickert), und der Body wird blockweise in einbytearraygelesen. (889f0b096)mqttimportiertsslerst bei Bedarf, sodass das Modul und unverschlüsselte (Nicht-TLS-)Verbindungen auf Builds ohne SSL-Unterstützung funktionieren. (c2e0899e8)JPEG-Ausgabepuffer nach freiem Speicher dimensioniert statt einer festen 1-MB-Obergrenze; die Encoder kürzen den Puffer vor dem Schreiben des Bildes auf die kodierte Größe, sodass Aufnahmen großer Sensoren bei hoher Qualität nicht mehr fehlschlagen. (aa1ca6776)
Aufräumen der ML-Nachverarbeitung — die Erzeugung von Bounding-Boxes ist über die Darknet-, Edge Impulse- und Ultralytics-Postprozessoren hinweg vereinheitlicht, und die YOLOv8-Ausgabe wird nach dem Schwellwertvergleich transponiert, sodass sie wie bei den anderen Modellen mit einer Zeile pro Erkennung gespeichert wird. (b5c7853f2, c45f99cad)
Sicheres Herunterfahren des PAG7936 — ein neues Sensor-Halt-Flag versetzt den PAG7936 vor dem Umschalten von RESET/PWDN in den Schlafmodus und behebt Blockaden, wenn der Sensor an einem Verlängerungskabel betrieben wird. Der Treiber wählt außerdem seinen MIPI-CSI-2- oder Parallel-Registersatz zur Laufzeit anhand der I2C-Adresse des Sensors statt zur Build-Zeit. (10026530c, f6acf14ec, 5f0251c74)
Die
ImageIO-Wiedergabetaktung bedient nun während des Wartens auf das Intervall zwischen den Einzelbildern anstehende Ereignisse, statt inWFIzu schlafen. (a54790193)Aktualisierungen des MicroPython-Submoduls — volle Netzwerkunterstützung auf dem QEMU-Port,
machine.mem_backupauf STM32 über Backup-SRAM/BKP-Register, SDIO-Hardware-Flusskontrolle auf STM32F4 weiterhin deaktiviert und Wiederverwendung von MPU-Attributen für nicht cachebare Regionen. (31ada5626, ab61d27a6, 06bddf13a)differential-translation.pynimmt über seincsi.CSI-Objekt statt über das veraltetesensor-Modul auf, und die Abstände bei den Imports in den Beispielen wurden vereinheitlicht. (68c866e7f, 9ceff4513)
Fehlerbehebungen#
Kamera und Sensoren:
Das Setzen zweier benutzerdefinierter
(w, h)-Auflösungen nacheinander ließ den Sensor auf der ersten Größe, währendcsi.CSI.width()/height()die zweite meldeten; der „keine Änderung“-Schnellpfad schließt benutzerdefinierte Größen nun aus. (cfbb70156)csi.CSI.lens_correction()parsteradiundcoefals Booleans, sodass die an den Treiber übergebenen Werte nicht die angegebenen waren. (ab44b3a77)PAG7936: Das direkt aufeinanderfolgende Setzen von Belichtung und Gain überschrieb sich gegenseitig (beide teilen sich einen manuellen Modus, und die zurückgelesenen Register hinken ein Einzelbild hinterher); der Treiber initialisiert die manuellen Register nun nur beim Wechsel in den manuellen Modus und schreibt nur die jeweils gesetzte Steuergröße. (e7a18c0a0)
Die BAYER-Aufnahme mit PAG7936 und PS5520 auf dem OpenMV N6 schlug bei jeder Größe außer der vollen Auflösung mit „Failed to initialize the CSI interface“ fehl, weil der ISP des N6 rohe Bayer-Daten nicht skalieren kann. Die Sensoren laufen für BAYER nun in einem nativen Modus, der zur angeforderten Größe passt (PS5520: VGA, HD, SXGA-M, FHD, QHD, WQXGA2; QVGA hat keinen nativen Modus und wird nicht unterstützt). (fe6790055, b7622b245)
Bildkodierung und Speichern:
Software-JPEG-Encoder: Ein Überlauf des Ausgabepuffers war immer fatal, weil der Realloc-Pfad deaktiviert war; er vergrößert den Puffer nun (jeweils um die Hälfte seiner Größe), wenn er ihn besitzt, fällt sauber zurück, wenn der Speicher ausgeht, und kürzt das Ergebnis.
jpeg_write/mjpeg_writeschreiben den Puffer nach einer fehlgeschlagenen Kodierung nicht mehr heraus. (28e1110be)Hardware-JPEG-Encoder (STM32): Bei einem Überlauf wurde ein teilweise kodiertes Bild mit der Allokationsgröße zurückgegeben, was abgeschnittene Dateien ohne EOI-Marker erzeugte (z. B. eine 5-MP-Aufnahme bei Qualität 100 mit leerer unterer Hälfte). Sie melden nun den Überlauf, geben den Puffer bei Fehlern frei und kürzen ihn bei Erfolg. (22ce9619c)
Der VC8000-Encoder erzeugte stillschweigend für jede Anforderung 4:2:0-Chroma; Subsampling außer 4:2:0 fällt nun auf den HW-Codec zurück, der es unterstützt. (71f2be7f2)
image.Image.save()eines PNG-Bildes als.jpgschrieb bis zu 1 MB uninitialisierten Heap, und eines JPEG-Bildes als.pngschrieb eine leere Datei. Beide lösen nun eine Ausnahme aus; ein Bild, das bereits im Zielformat vorliegt, wird weiterhin unverändert kopiert. (6c1fdf822)png_writeprüft nun den Rückgabewert des Kompressors und komprimiert vor dem Anlegen der Datei, sodass ein Fehler keine leere Datei mehr zurücklässt. (557f52d66)
image-Modul:
image.Image.get_pixel()mitrgbtuple=Trueauf BAYER- und YUV-Bildern schrieb den konvertierten Pixel über eine lokale Stack-Variable hinaus an einen vom Aufrufer bestimmten Offset. (13f2a17b6)Aus
gif.Gif.add_frame()wurde ein unerreichbarer Bayer/YUV-Konvertierungszweig entfernt; es werden nur GRAYSCALE- und RGB565-Bilder akzeptiert, wie es die Python-API bereits erzwang. (f20d99d96)
Protokoll:
Das Registrieren eines dynamischen Kanals, wenn bereits alle Slots belegt waren, verursachte einen Schreibzugriff außerhalb der Grenzen; die Kanal-ID wird nun zuerst geprüft, und für die reservierten Kanal-IDs wird statisch sichergestellt, dass sie in die Kanaltabelle passen. (68f635d1f)
Dynamische Kanalobjekte überlebten einen Soft-Reset in Root-Pointern, sodass der GC weiterhin veraltete Heap-Blöcke des vorherigen Laufs durchsuchte; die Tabelle wird nun beim Initialisieren geleert. (ef0ebb03b, e23641145)
Ports:
i.MX RT: Die fehlende Deinitialisierung von CAN und Encoder beim Soft-Reset wurde ergänzt. (7cb9d3dc2)
Hardware- und Board-Unterstützung#
OpenMV N6 — CAN ist nun aktiviert (
machine.CAN). (294f0febd, 91e1c9573)OpenMV AE3 — der
sdcard-SPI-Treiber ist für den microSD-Steckplatz auf dem AE3 Battery Shield eingefroren. (a258f4814)OpenMV RT1062 —
lora-sx126x/lora-sync/lora-asynceingefroren (siehe Neue Funktionen).FLIR Lepton 3.1R / UW — werden vom Lepton-Treiber auf allen Lepton-fähigen Boards erkannt.
PAG7936 — Halt für sicheres Herunterfahren, Schnittstellenauswahl zur Laufzeit, Belichtungs-/Gain-Korrektur und BAYER-Aufnahme auf dem N6.
PS5520 — BAYER-Aufnahme auf dem N6 in nativen Größen.
Simulator (MPS2_AN500) — Netzwerkunterstützung.
Alle Boards — das
sensor-Kompatibilitätsmodul ist in das Manifest jedes Boards eingefroren.
API-Brüche#
v5.0.1 bringt keine Brüche in den APIs von csi und image. Skripte, die auf v5.0.0 liefen, laufen unverändert, mit den folgenden Verhaltensänderungen.
sensor-Modul (behavior)#
Das native sensor-Modul (modules/py_csi.c) wurde entfernt und durch ein eingefrorenes Python-Modul ersetzt, das dieselbe API auf Basis von csi implementiert. Siehe sensor.
Commit: 5e3d40631
import sensorgibtWARNING: The sensor module is deprecated and will be removed in a future release. Please use the csi module instead.im Terminal aus.Das verborgene
csi.CSI-Objekt wird beim Import erstellt, sodass eine fehlende Kamera nun beiimport sensorstatt beisensor.reset()eine Ausnahme auslöst.Diese Funktionen lösen nun
OSErroraus, weilcsikeine Entsprechung hat:get_fb(),alloc_extra_fb(),dealloc_extra_fb(),set_auto_rotation(),get_auto_rotation(),disable_delays(),disable_full_flush(). (Die beiden*_extra_fb-Funktionen lösten bereits in v5.0.0 eine Ausnahme aus.) Verwenden Sie für die letzten beidencsi.CSI(delays=False)/csi.CSI(fflush=False).Framesizes, die
csinicht exportiert (QQCIF,QQSIF,QQQQVGA,HQQQQVGA,HQQQVGA,HQQVGA,B64X32,B64X64,B128X64,B128X128,B160X160,B320X320,LCD,QQVGA2), sind nun(w, h)-Tupel, die als benutzerdefinierte Auflösungen durchgereicht werden.get_framesize()gibt das gesetzte Tupel zurück, solange die Kamera noch diese Größe hat, sodass Gleichheitsprüfungen gegen die Konstanten weiterhin funktionieren.ioctl()reicht höchstens vier Argumente nach der Anforderung weiter.sleep()/shutdown()lösen bei Fehlern wie bisherOSErroraus (derRuntimeErrorvoncsiwird übersetzt).
Migrieren Sie zu csi — siehe die v5.0.0-Migrationstabelle.
Laden von Bildern in den Framebuffer (behavior)#
Funktionen, die ein Bild in den Framebuffer laden — image.Image mit copy_to_fb=True, image.Image.copy() / image.Image.scale() und die to_*-Konvertierungen mit copy_to_fb=True, image.ImageIO.read(), fir.snapshot() und tof.snapshot() mit copy_to_fb=True — schickten das neue Bild bisher sofort an die IDE-Vorschau, sodass alles, was auf das zurückgegebene Bild gezeichnet wurde, nie zu sehen war. Sie markieren den Framebuffer nun als ausstehend und geben ihn, mit allem, was darauf gezeichnet wurde, unmittelbar bevor das nächste Bild ihn überschreibt aus — dasselbe Verhalten wie csi.CSI.snapshot().
Commits: 87b6db5ee, 7b1a35c2f, f773c740d
Schleifen, die einen Strom von Bildern lesen, brauchen keine Änderung und zeigen nun ihre Zeichnungen. Ein Skript, das ein einzelnes Bild lädt und dann stoppt, muss es explizit ausgeben:
img = image.Image("example.bmp", copy_to_fb=True)
img.flush() # new: send it to the IDE preview now
time.sleep_ms(1000)
ML-Bibliothek (behavior)#
Betrifft nur Code, der die mitgelieferten Postprozessoren ableitet oder kopiert. YoloV8 transponiert die Modellausgabe nun nach dem Schwellwertvergleich, sodass verbleibende Erkennungen mit einer Zeile pro Box gespeichert werden (bb[:, 4:]), passend zu den Darknet- und Edge Impulse-Postprozessoren, statt mit einer Spalte pro Box (bb[4:, :]). Die öffentlichen ((x, y, w, h), score)-Ergebnisse sind unverändert.
protocol-Modul (minor)#
protocol.poll() ist zurück. v5.0.0 hatte es entfernt, als die Protokoll-Task auf den Timer umzog; es kehrt als expliziter Weg zurück, die Task für benutzerdefinierte Transporte anzutreiben. Sonst hat sich nichts geändert — Skripte, die es nie aufgerufen haben, sind nicht betroffen.
Commit: c00c215f9
Build / Tooling (tooling)#
Nichts davon betrifft MicroPython-Skripte. py_image.c wurde aufgeteilt, wobei die Deskriptor-Objekte (cascade, keypoints, LBP, keypoint match) nach py_image_descriptor.c und die Statistik-Objekte (similarity, statistics, percentile, threshold, histogram) nach py_image_stats.c umgezogen sind. Die imlib-Encoder-API wurde an den Rest von imlib angeglichen: jpeg_compress / png_compress geben 0 bei Erfolg und -1 bei Fehlern zurück, und jpeg_compress hat sein realloc-Argument verloren (die Größenänderung hängt vom Pufferbesitz ab). OMV_PROTOCOL_MAX_CHANNELS wurde in omv_protocol_channel.h zu OMV_PROTOCOL_CHANNEL_MAX, und Ports rufen nun py_protocol_init0() beim Initialisieren auf. Das Board-Define OMV_PAG7936_MIPI_CSI2 ist weg (die Schnittstelle wird zur Laufzeit ausgewählt). CI-Abhängigkeitsaktualisierungen und eine Korrektur für leere Release-Changelogs runden es ab. Für Fork-relevante Details siehe die Historie des Firmware-Repositorys.
Migrations-Checkliste#
Noch bei
import sensor? Es funktioniert, mit einer Warnung. Wechseln Sie zucsi(v5.0.0-Migration); ersetzen Siedisable_delays/disable_full_flushdurch die Konstruktorargumente voncsi.CSI()und entfernen Sieget_fb- / Auto-Rotations-Aufrufe.Sie laden ein einzelnes Bild mit
copy_to_fb=Trueund erwarten, es zu sehen? Fügen Sie nach dem Ladenimg.flush()hinzu.Den YOLOv8-Postprozessor kopiert? Indizieren Sie die schwellwertgefilterte Ausgabe zeilenweise (
bb[:, 4:]) statt spaltenweise.Sie vergleichen
csi0.framesize()nach dem Setzen eines Tupels? Es gibt nuncsi.CUSTOMzurück.Alles andere: neu flashen und ausführen.