v5.0.1#
v5.0.1 是建立在 v5.0.0 之上的維護版本——舊有的 sensor 模組變成建立在 csi 之上的 Python 相容層、載入影格緩衝區的影像現在會像相機影格一樣預覽、JPEG 編碼器不再有 1 MB 的輸出限制並能正確處理溢位,此外還有一批相機、協定、網路與 ML 函式庫的修正。對於針對 csi 撰寫的指令碼,本版本未引入任何破壞性 API 變更;少數行為變更列於 破壞性 API 變更 之下。
重點亮點#
舊有的
sensor模組現在是一個凍結的 Python 模組,建立於csi之上。匯入時會印出棄用警告;少數csi模組無法支援的函式現在會引發OSError。請參閱 sensor 模組變更。載入的影像會像相機影格一樣預覽。 以
copy_to_fb=True放入影格緩衝區的影像(image.Image、image.ImageIO.read()、fir.snapshot()、tof.snapshot())會在下一張影像覆寫影格緩衝區時——連同在其上繪製的任何內容——才送出到 IDE,而非立即送出。請參閱 預覽變更。JPEG 編碼器大幅翻修。 1 MB 的輸出緩衝區上限已移除(緩衝區大小依可用記憶體決定),軟體與硬體路徑上的溢位都會被妥善處理而非寫出截斷的檔案,而將壓縮影像以另一種壓縮副檔名儲存時會引發例外,而非寫出垃圾資料。
新增
protocol.poll(),以及供protocol.CBORChannel使用的 六個新 CBOR 小工具(text、lineedit、pushbutton、spinbox、radio、waveform)。YOLO Pro 後處理器、FLIR Lepton 3.1R / UW 支援、IMU 連續讀取、OpenMV N6 上的 CAN,以及一個 具備網路功能的 simulator 目標。
新功能#
YoloPro—— 適用於 Edge Impulse YOLO Pro 物件偵測模型的新後處理器,並附上yolo_pro_detector.py範例。(f3f150ebd、ea7bbb398)protocol.poll()—— 可依需求執行協定任務的一次迭代,供不由 USB 中斷或poll_ms計時器驅動的自訂傳輸使用。protocol.init()也可以再次呼叫以重新初始化堆疊。(c00c215f9、f849ffb1b)更多 CBOR 通道小工具 ——
protocol.CBORChannel.add()新增text(靜態字串)、lineedit(可寫入字串)、pushbutton(瞬時動作)、spinbox(步進數值輸入)、radio(選項群組)與waveform(1D 時間序列,具有sample_rate、series與typecode引數;指派交錯的樣本位元組即可串流)。(8016d29ba)csi.CUSTOM—— 在設定自訂(w, h)解析度之後,csi.CSI.framesize()現在會回傳一個可用的常數,而非匿名整數。(af8841654)IMU 連續讀取 ——
imu.__read_reg()接受一個選用的可寫入緩衝區,並在單一交易中以連續暫存器的內容填滿它。(244ca480a)FLIR Lepton 3.1R 與 Lepton UW 現在能被 Lepton 驅動程式辨識,包括其輻射測溫增益模式。(0fc356632)
Simulator 網路功能 ——
MPS2_AN500QEMU 目標現在具備 lwIP 與使用者模式 NIC,並凍結了requests、mqtt與sensor,還附有一個網路單元測試。(23546dfb1、61d187305、15096c3a2)OpenAI 相容 API 範例 ——
openai_compatible.py會擷取一張 JPEG 快照,並將其張貼到 chat-completions 端點以進行場景描述。(79033c6aa)SX126x LoRa 範例 —— micropython-lib 的
lora-sx126x驅動程式(連同lora-sync/lora-async)已凍結進 OpenMV RT1062 韌體,並附有傳送端/接收端/乒乓/影像串流範例,示範如何將 SX1261 或 SX1262 模組接到 SPI 匯流排。這是由社群貢獻的支援;OpenMV 並不販售 LoRa 硬體。(19576e1b1)
其他變更與改進#
requests函式庫重寫 —— 分塊傳輸回應會被解碼、開放了timeout引數(預設 5 秒)、JSON 與字串主體會被正確序列化/編碼、標頭的解析不區分大小寫且狀態行依位置解析、呼叫端的headers字典會被複製(因此auth不再洩漏到後續請求),且主體會以區塊方式讀入bytearray。(889f0b096)mqtt會延遲匯入ssl,因此本模組與純(非 TLS)連線在不支援 SSL 的建置上也能運作。(c2e0899e8)JPEG 輸出緩衝區大小依可用記憶體決定,而非固定的 1 MB 上限;編碼器會在影像寫出之前將緩衝區修剪為編碼後的大小,因此大型感測器的高品質擷取不再失敗。(aa1ca6776)
ML 後處理整理 —— 邊界框的產生方式在 Darknet、Edge Impulse 與 Ultralytics 後處理器之間已標準化,且 YOLOv8 的輸出會在閾值篩選後轉置,使其如同其他模型一樣以每個偵測一列的方式儲存。(b5c7853f2、c45f99cad)
PAG7936 安全關機 —— 新的感測器停止旗標會在切換 RESET/PWDN 之前讓 PAG7936 進入睡眠,修正了感測器透過延長排線使用時的當機問題。驅動程式現在也會在執行階段依感測器的 I2C 位址選擇其 MIPI CSI-2 或平行介面暫存器組,而非在建置時決定。(10026530c、f6acf14ec、5f0251c74)
ImageIO的播放節奏控制現在會在等待影格間隔時處理待處理的事件,而非在WFI中休眠。(a54790193)MicroPython 子模組更新 —— QEMU 移植版的完整網路支援、STM32 上透過備援 SRAM/BKP 暫存器實作的
machine.mem_backup、STM32F4 上維持停用的 SDIO 硬體流量控制,以及不可快取區域的 MPU 屬性重用。(31ada5626、ab61d27a6、06bddf13a)differential-translation.py現在透過其csi.CSI物件擷取影像,而非使用已棄用的sensor模組;範例中的 import 間距也已統一。(68c866e7f、9ceff4513)
錯誤修正#
相機與感測器:
連續設定兩個自訂
(w, h)解析度時,感測器會停留在第一個大小,而csi.CSI.width()/height()卻回報第二個;「無變更」的快速路徑現在會排除自訂大小。(cfbb70156)csi.CSI.lens_correction()將radi與coef解析為布林值,導致傳給驅動程式的值並非所給定的值。(ab44b3a77)PAG7936:連續設定曝光與增益時會互相覆蓋(兩者共用同一個手動模式,且回讀暫存器會延遲一個影格);驅動程式現在只在進入手動模式時初始化手動暫存器,並且只寫入正在設定的那個控制項。(e7a18c0a0)
在 OpenMV N6 上,PAG7936 與 PS5520 的 BAYER 擷取在全解析度以外的任何大小都會以「Failed to initialize the CSI interface」失敗,因為 N6 的 ISP 無法縮放原始 Bayer 資料。這些感測器現在在 BAYER 模式下會以符合所要求大小的原生模式執行(PS5520:VGA、HD、SXGA-M、FHD、QHD、WQXGA2;QVGA 沒有原生模式,因此不支援)。(fe6790055、b7622b245)
影像編碼與儲存:
軟體 JPEG 編碼器:由於 realloc 路徑被停用,輸出緩衝區溢位一律是致命錯誤;現在當編碼器擁有該緩衝區時會將其擴大(每次擴大一半),在記憶體用盡時會乾淨地回退,並修剪結果。
jpeg_write/mjpeg_write在編碼失敗後不再將緩衝區寫出。(28e1110be)硬體 JPEG 編碼器(STM32):溢位時會回傳一張以配置大小為長度、僅部分編碼的影像,產生沒有 EOI 標記的截斷檔案(例如以品質 100 擷取的 5 MP 影像,其下半部一片空白)。現在會回報溢位,失敗時釋放緩衝區,成功時則修剪緩衝區。(22ce9619c)
VC8000 編碼器對每個請求都默默地產生 4:2:0 色度;非 4:2:0 的子取樣現在會回退到支援它的硬體編解碼器。(71f2be7f2)
以
image.Image.save()將 PNG 影像存成.jpg會寫出最多 1 MB 未初始化的堆積內容,而將 JPEG 影像存成.png則會寫出空檔案。兩者現在都會引發例外;已是目標格式的影像仍會原樣複製。(6c1fdf822)png_write現在會檢查壓縮器的回傳值,並在建立檔案之前先進行壓縮,因此失敗時不再留下空檔案。(557f52d66)
影像模組:
在 BAYER 與 YUV 影像上以
rgbtuple=True呼叫image.Image.get_pixel()時,會將轉換後的像素寫到堆疊區域變數之外、由呼叫端控制的偏移位置。(13f2a17b6)gif.Gif.add_frame()移除了一個無法到達的 Bayer/YUV 轉換分支;如同 Python API 原本就強制要求的,僅接受 GRAYSCALE 與 RGB565 影像。(f20d99d96)
協定:
在所有通道槽都已被使用時註冊動態通道會造成越界寫入;現在會先檢查通道 ID,並以靜態斷言確保保留的通道 ID 能容納於通道表中。(68f635d1f)
動態通道物件在軟重置後仍殘留於根指標中,導致 GC 持續掃描前一次執行遺留的過期堆積區塊;該表現在會在初始化時清除。(ef0ebb03b、e23641145)
移植版:
i.MX RT:補上了軟重置時缺少的 CAN 與 Encoder 解除初始化。(7cb9d3dc2)
硬體與板卡支援#
OpenMV N6 —— 現已啟用 CAN(
machine.CAN)。(294f0febd、91e1c9573)OpenMV AE3 —— 為 AE3 電池擴充板 上的 microSD 插槽凍結了
sdcardSPI 驅動程式。(a258f4814)OpenMV RT1062 —— 已凍結
lora-sx126x/lora-sync/lora-async(請參閱「新功能」)。FLIR Lepton 3.1R / UW —— 在所有支援 Lepton 的板卡上都能被 Lepton 驅動程式辨識。
PAG7936 —— 安全關機停止、執行階段介面選擇、曝光/增益修正,以及 N6 上的 BAYER 擷取。
PS5520 —— N6 上以原生大小進行 BAYER 擷取。
Simulator (MPS2_AN500) —— 網路功能。
所有板卡 ——
sensor相容模組已凍結進每塊板卡的 manifest 中。
破壞性 API 變更#
v5.0.1 未對 csi 或 image API 引入任何破壞性變更。在 v5.0.0 上能執行的指令碼無需修改即可執行,僅有下列行為變更。
sensor 模組 (behavior)#
原生的 sensor 模組(modules/py_csi.c)已移除,改由一個凍結的 Python 模組取代,該模組在 csi 之上實作相同的 API。請參閱 sensor。
提交: 5e3d40631
import sensor會在終端機印出WARNING: The sensor module is deprecated and will be removed in a future release. Please use the csi module instead.。隱藏的
csi.CSI物件會在匯入時建立,因此缺少相機時現在會在import sensor時就引發錯誤,而非在sensor.reset()時。由於
csi沒有對應的功能,下列函式現在會引發OSError:get_fb()、alloc_extra_fb()、dealloc_extra_fb()、set_auto_rotation()、get_auto_rotation()、disable_delays()、disable_full_flush()。(兩個*_extra_fb函式在 v5.0.0 中就已會引發例外。)最後兩個請改用csi.CSI(delays=False)/csi.CSI(fflush=False)。csi未匯出的影格大小(QQCIF、QQSIF、QQQQVGA、HQQQQVGA、HQQQVGA、HQQVGA、B64X32、B64X64、B128X64、B128X128、B160X160、B320X320、LCD、QQVGA2)現在是以自訂解析度傳遞的(w, h)元組。當相機仍處於該大小時,get_framesize()會回傳所設定的元組,因此與常數的相等比較仍可正常運作。ioctl()在請求之後最多轉發四個引數。sleep()/shutdown()在失敗時一如以往引發OSError(csi的RuntimeError會被轉換)。
請遷移至 csi —— 參閱 v5.0.0 遷移表。
影格緩衝區影像載入 (behavior)#
將影像載入影格緩衝區的函式——帶 copy_to_fb=True 的 image.Image、帶 copy_to_fb=True 的 image.Image.copy() / image.Image.scale() 與 to_* 轉換、image.ImageIO.read(),以及帶 copy_to_fb=True 的 fir.snapshot() 與 tof.snapshot()——以前會立即將新影像推送到 IDE 預覽,因此在回傳影像上繪製的任何內容都永遠看不到。現在它們會將影格緩衝區標記為待送出,並在下一張影像覆寫它之前,連同其上繪製的所有內容一併送出——與 csi.CSI.snapshot() 的行為相同。
提交: 87b6db5ee、7b1a35c2f、f773c740d
讀取一連串影像的迴圈無需任何修改,而且現在會顯示其繪製內容。載入 單一 影像後就停止的指令碼則必須明確送出它:
img = image.Image("example.bmp", copy_to_fb=True)
img.flush() # new: send it to the IDE preview now
time.sleep_ms(1000)
ML 函式庫 (behavior)#
僅影響繼承或複製隨附後處理器的程式碼。YoloV8 現在會在閾值篩選後轉置模型輸出,使保留下來的偵測以每個框一 列 的方式儲存(bb[:, 4:]),與 Darknet 及 Edge Impulse 後處理器一致,而非每個框一欄(bb[4:, :])。公開的 ((x, y, w, h), score) 結果不變。
protocol 模組 (minor)#
protocol.poll() 回歸了。v5.0.0 在協定任務移至計時器時將其移除;它現在以明確方式回歸,供自訂傳輸驅動該任務。其他一切不變——從未呼叫過它的指令碼不受影響。
提交: c00c215f9
建置/工具鏈 (tooling)#
這些都不影響 MicroPython 指令碼。py_image.c 已被拆分:描述元物件(級聯、關鍵點、LBP、關鍵點比對)移至 py_image_descriptor.c,統計物件(相似度、統計、百分位數、閾值、直方圖)移至 py_image_stats.c。imlib 編碼器 API 已與 imlib 的其餘部分對齊:jpeg_compress / png_compress 成功時回傳 0、錯誤時回傳 -1,且 jpeg_compress 移除了其 realloc 引數(是否重新調整大小取決於緩衝區的擁有權)。OMV_PROTOCOL_MAX_CHANNELS 更名為 OMV_PROTOCOL_CHANNEL_MAX(位於 omv_protocol_channel.h),且各移植版現在會在初始化時呼叫 py_protocol_init0()。OMV_PAG7936_MIPI_CSI2 板卡定義已移除(介面在執行階段選擇)。此外還有 CI 相依套件的版本更新,以及空白版本變更記錄的修正。與分支相關的細節請參閱 韌體儲存庫 的歷史。
遷移檢查清單#
仍在使用
import sensor嗎?它仍可運作,但會出現警告。請移至csi(v5.0.0 遷移);以csi.CSI()建構式引數取代disable_delays/disable_full_flush,並移除get_fb/ 自動旋轉的呼叫。以
copy_to_fb=True載入單一影像並期望看到它? 請在載入後加上img.flush()。複製了 YOLOv8 後處理器? 請以列(
bb[:, 4:])而非欄來索引閾值篩選後的輸出。在設定元組之後比較
csi0.framesize()的結果? 它現在會回傳csi.CUSTOM。其他一切:重新燒錄韌體並執行即可。