v5.0.0

v5.0.0 是一個重大版本。其中的亮點包括:重新打造的 OpenMV Protocol V2 主機連結、可擴充至多相機板卡的類別式 csi 相機 API、可執行的 simulator(模擬器)目標、MoveNet 單一姿態估測、MicroPython 1.28,以及一大批相機、ML 與 ToF 的修正。本版本也帶來了多項破壞性 API 變更——自 v4.8.1 以來所有使用者可見的變更都列在下方,並附上確切的遷移方式。

重點亮點

  • OpenMV Protocol V2。 主機/IDE 連結從頭重建:採用分框、序號、CRC 校驗,並為 stdio、串流預覽與使用者資料提供多工通道。新的 protocol 模組讓指令碼能建立自己的傳輸與資料通道。請參閱 protocol 模組變更

  • 類別式 csi 相機 API。 import sensor 改為 import csi / csi.CSI,並原生支援多相機。請參閱 csi 遷移

  • Simulator 目標。 韌體現在可在 Arm FVP / QEMU 模擬器(MPS2/MPS3)下建置與執行,包含 NPU、ROMFS 與 PSRAM 模擬——機器視覺與 ML 指令碼可在不連接任何硬體的情況下執行。

  • MoveNet 姿態估測。 新增 MoveNet 後處理器,並在 OpenMV AE3 與 N6 上隨附 movenet_singlepose_192.tflite 模型。

  • MicroPython 1.28ulab 6.12.0ST Edge AI 4.0 工具鏈,以及外部化的 OpenMV SDK(請參閱 建置/工具鏈變更)。

新功能

  • 新增 protocol 模組 —— 可從 Python 建立自訂傳輸與資料通道:protocol.init()protocol.register()protocol.is_active(),以及具有 send_event()protocol.ProtocolChannel 類別,外加 CHANNEL_FLAG_*CHANNEL_ID_* 常數。最終的 protocol.init() 簽章記載於 protocol 模組變更

  • protocol.CBORChannel —— 一個凍結的 protocol 擴充套件,可將具名欄位序列化為 CBOR,並提供顯示小工具(標籤、深度)與互動控制項(切換、滑桿、選擇)。

  • 主機記憶體與串流自省 —— 新的 SYS_MEMORY 協定指令向 IDE 公開每個記憶體池的執行階段記憶體統計,而新的 STREAM_SOURCE 串流 ioctl 讓主機在多相機板卡上挑選由哪一台相機提供預覽(協定版本 1.0.1)。

  • 多相機串流 —— csi.CSI 接受 stream= 引數,用以選擇由哪一個感測器提供 IDE 預覽;串流影格標頭現在攜帶經 EMA 平滑處理的 FPS,因此 IDE 無需 clock.fps() 樣板程式碼即可顯示影格率。請參閱 csi 遷移csi 後續調整

  • GenX320 事件感測器 —— 新增時空對比濾波器(csi.IOCTL_GENX320_SET_STC,具有 csi.GENX320_STC_DISABLEcsi.GENX320_STC_ONLYcsi.GENX320_STC_TRAIL_ONLYcsi.GENX320_STC_TRAIL 模式)以及原始事件讀取(csi.IOCTL_GENX320_READ_EVENTS_RAW),並附上新的範例指令碼。

  • MoveNet —— 新的 MediaPipe 單一姿態後處理器(thresholdnms_thresholdnms_sigma 關鍵字引數),回傳 ((x, y, w, h), score, keypoints) 以及 17 個關節的 COCO 關鍵點陣列;AE3 與 N6 上隨附 movenet_singlepose_192.tflite 模型與範例。

  • ml.utils.draw_predictions() —— 新增可選的 scores= 引數以附加每個標籤的信賴度,字型與框線粗細現在會依影像寬度自動縮放,並新增 format="point" 模式為中心點/峰值偵測器繪製中心標記。

  • 新的 display.TVDisplay 類別(具有通用的 ioctl())取代了獨立的 tv 模組。請參閱 display 模組變更

  • 新的 find_line_segments() 偵測器(ED-Lines)—— 現在所有建置版本皆可使用,並新增 threshold= 引數。請參閱 image 模組變更

其他變更與改進

  • MicroPython 自 v4.8.1 基底更新至 1.28.0。 在 H5/H7/N6 上新增高速 SD 卡模式、低功耗模式下的 AHB5 時脈,以及 OPENMV_AE3 上可作為 GPIO 控制的 JTAG 接腳。

  • ulab 更新至 6.12.0 —— ndarray 上原生支援 % 運算子(ml.utils.mod() 輔助函式已移除;請參閱 ML 函式庫變更)。

  • 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 緩衝區 —— OpenMV 2/3/4、Nicla Vision、AE3 與 N6 上傳送至 IDE 的預設文字緩衝區從 512 位元組增加到 1024 位元組,因此較大的 print() 爆發不會被截斷。

  • 更順暢的主機事件流 —— 傳送至主機的 stdout NOTIFY 事件被節流為每次主機讀取最多一個,而非每次 print() 越過環形緩衝區水位線時就觸發一個。

  • 可中斷的長時間運算 —— 長時間的影像繪製、GPU(Nema/Dave2D)與 NPU 等待迴圈現在會以確定的間隔處理事件,因此指令碼在繁重工作期間仍能對 IDE 的停止按鈕保持回應。

錯誤修正

相機與感測器:

  • find_apriltags() 在採用 D-cache/GPU 的板卡(N6、AE3)上不再損壞結果,且現在可在 AE3 上運作。

  • 修正 STM32 N6 ISP 在切換像素格式後的 Bayer 影像輸出。

  • 修正了亮場景下綠色自動白平衡溢爆,以及未初始化的首幀 AWB 統計情況;提高了 STM32 ISP 的 gamma 鉗制值(32 至 63),以獲得更廣的 gamma/對比度/亮度範圍。

  • PS5520 自動曝光在強光下不再振盪;PAG7936 的 AEC/AGC 行為經過重做(合併控制、修正增益上限)。

  • 在 Portenta/Nicla 上恢復了 OV5640 自動對焦韌體上傳(MIMXRT I2C SUSPEND 修正)。

  • 修正了影格率限制與 JPEG 擷取結合時的相機擷取死結(STM32)。

  • GenX320 的 csi.IOCTL_GENX320_READ_EVENTS_RAW 讀取不再擾亂 IDE 預覽。

  • 透過 csi.CSI.ioctl() 使用 FLIR Lepton 的 csi.IOCTL_LEPTON_SET_MODE 現在以單一引數呼叫時可正常運作。

影像處理:

  • 修正了提供遮罩時 draw_image() / blend() 的 alpha 混合。

  • 修正了 1 位元(BINARY)PNG 編碼/解碼的位元順序,以及從 1 位元解碼為灰階。

  • 修正了 mjpeg.Mjpeg 錄製的時長/FPS 中介資料。

  • 修正了小堆疊板卡(OpenMV M7)上的軟體 JPEG 解碼堆疊溢位。

  • 修正了非 ARM 主機(模擬器)上的 JPEG/PNG 檔案格式自動偵測。

飛行時間(Time-of-Flight):

ML 與系統:

  • 在 N6 上中斷推論時,NPU 現在會被正確清理。

  • 在 N6 上恢復了深度睡眠/待機喚醒;修正了 AE3 跳轉至開機載入程式的當機問題。

  • 修正了軟重置時的記憶體洩漏(STM32 Nema GPU),以及過早被回收的輔助影格緩衝區。

  • 自訂 Python 協定通道現在能在軟重新開機後存續,USB 傳輸能自匯流排重置/停滯的端點恢復,並修正了 USB SOF 中斷氾濫。

硬體與板卡支援

  • OpenMV N6 —— 啟用乙太網路(有線網路);NPU AXI SRAM(1.75 MB)併入共享的暫態記憶體池,使推論之間有更多 RAM 可用;深度睡眠/待機喚醒;在 ROMFS 中隨附 TFLite 模型與 Haar 級聯。

  • OpenMV AE3 —— 在 ROMFS 中隨附模型與級聯;cbor2 凍結進韌體中。

  • Alif(AE3、N6) —— 低功耗 machine.RTC 喚醒。

  • 高解析度 AprilTag —— 在 AE3、Arduino Giga 與 Arduino Portenta H7 上以全感測器解析度執行 find_apriltags()

  • Simulator 目標 —— MPS2_AN500 / MPS3_AN547(Arm FVP / QEMU),具備 NPU、ROMFS 與 PSRAM 模擬。

破壞性 API 變更

v4.8.1 與 v5.0.0 之間使用者可見的 API 破壞。範圍:modules/ 中的 Python C 模組與 scripts/libraries/ 中的 Python 函式庫。

每項變更都標註了其影響程度:

  • major(重大)—— 大多數指令碼需要修改。

  • minor(次要)—— 範圍狹窄的 API;僅影響用到它的指令碼。

  • behavior(行為)—— 相同的 API、不同的結果;請重新檢查已調校的指令碼。

  • tooling(工具鏈)—— 僅影響從原始碼建置/下游分支。

變更依影響程度依序分組——先 major,接著 minorbehaviortooling。若您只想移植程式碼,可跳至文末的 遷移檢查清單,那是一份精簡的待辦清單。每個提交雜湊都連結到其在 GitHub 上的差異。

sensorcsi 取代 (major)

每個官方範例都已重寫,捨棄 import sensor 而改用 import csi。舊有的模組層級函式式 API(sensor.reset()sensor.set_pixformat()、……)已由類別式 csi.CSI API 取代,後者能自然擴充至具備多台相機的板卡(csi0csi1、……),並且是所有新功能(stream= 關鍵字引數、多感測器串流、……)的必要條件。

為了向後相容的韌體建置,sensor qstr 在 modules/py_csi.c 中仍有接線,但它不會獲得新功能,而所有範例、文件與函式庫程式碼現在都假設使用 csi

提交: 945c5853c61f835b7e

模組轉為類別

之前(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() —— skip-frames 已透過其 time= / frames= 引數併入 snapshot

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 後續調整)。

New on csi.CSI

  • csi.CSI(stream=True|False) —— 一個建構時的選擇器,用以選擇哪一個 CSI 提供預覽影格緩衝區(取代每次快照的 update= 關鍵字引數,請參閱 csi 後續調整)。

  • csi.CSI(cid=N) / csi.devices() —— 為具備多於一個影像感測器的板卡提供多 CSI 支援。

image 模組 —— 簽章全面翻修 (major)

csi 之後,image 模組是變動最廣的 API ——繪製簽章、結果物件與多個偵測器全都有所變更。

座標引數必須是元組(tuple)

modules/py_image.cmp_arg_parse_all 之上重寫。所有先前接受個別 x, y, ... 位置引數的繪製/像素方法,現在都要求將那些座標封裝進單一元組中。

提交: d18bbc4720c60c94b9PR #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 物件:similaritystatisticspercentilethresholdlinecirclerectqrcodeapriltagdatamatrixbarcodedisplacementkptmatch。不帶括號的屬性存取現在是標準寫法。

提交: 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)

blobhistogram 維持不變——它們保留既有的型別與 () 存取器(attrtuple 無法表達色塊延遲計算的值,也無法表達直方圖需要引數的存取器)。

find_features 的 haar 參數更名

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))會在進行 O(N^2) 的 Theil-Sen 擬合前依面積將 ROI 縮小,使其始終在合理的影像尺寸上執行;擬合出的線段端點會映射回原始座標。linear_regression_robust.py 範例已刪除,linear_regression_fast.py 已更名為 linear_regression.py

提交: c7c2e69a00ff2afa72

find_line_segments —— 新演算法

image.Image.find_line_segments() —— 舊的 LSD 偵測器已被 ED-Lines 取代,並新增了 threshold=50 關鍵字引數。先前已調校過的指令碼輸出將有所不同。

提交: 87da2a7b72c47b5735

AprilTag 函式庫已替換

image.Image.find_apriltags() —— AprilTag 偵測器已替換為新實作。標籤族集合有所變更:

提交: e813bada7

csi 模組後續調整 (minor)

csi 遷移 之上的較小 csi 後續調整。

snapshot(update=...) 已移除

csi.CSI.snapshot() 上的 update 關鍵字引數已消失。若要讓某個 CSI 裝置不提供預覽影格緩衝區,請在建構時選擇退出:

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

提交: 9a807782726b79a2c5

framebuffers() 的 expand 引數已移除

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

提交: 8a0635e8c95a290607

protocol.poll() 已移除

協定工作現在會在內部排程。呼叫 protocol.poll() 將拋出 AttributeError

提交: 8a0635e8c

soft_reboot 設定引數已移除

protocol.init() —— soft_reboot 引數已消失。目前所有傳輸都能容忍軟重新開機,因此此行為現在是無條件的。

提交: 0bf766aa2

display 模組 (minor)

電視輸出現在透過 display.TVDisplay 物件進行,而非獨立的 tv 模組。display 也新增了通用的 ioctl()

提交: f0accb3891a5a87121920c097a09eac55098

tof 模組 (behavior)

API 與之前相同;預設值與錯誤處理已變更。請參閱 tof

預設逾時已變更

tof.read_depth()tof.snapshot()(以 timeout=-1 呼叫時)現在預設為 100 ms,而非無限期等待。若需要舊行為,請傳入明確的較大值。

提交: b6772b80d

自動恢復

驅動程式現在會在測距/逾時錯誤時硬重置 I2C 匯流排與感測器。範例不再於其例外處理常式中呼叫 tof.reset() ——進行手動恢復的使用者程式碼應移除它(否則會與新的自動恢復機制相衝突)。

提交: b6772b80d80ffaa5c3

ML 函式庫 (behavior)

API 相同、數字不同——請重新檢查任何已調校的 ML 管線。

預處理現在會拉伸而非加上信箱黑邊

Normalization 現在使用 image.SCALE_ASPECT_IGNORE(拉伸)而非 image.SCALE_ASPECT_EXPAND(信箱黑邊)。NMS 後處理也改為使用獨立的 x/y 縮放。

備註

影響。 YOLO 式偵測器與關鍵點迴歸器通常會獲得改善。BlazeFaceBlazePalmFaceLandmarksHandLandmarks 範例現在需要對輸入 ROI 進行手動方形裁切——範例指令碼已更新;自訂的使用者程式碼必須照做。

提交: 68dc29a33

ml.utils.mod() 輔助函式已移除

ulab 6.12.0 原生支援 ndarray 上的 %。從 ml.utils 匯入 mod 的程式碼必須改用 a % b

提交: 35ece572882fbd858c

建置/工具鏈 (tooling)

這些都不影響 MicroPython 指令碼。從原始碼建置韌體現在需要外部的 OpenMV SDK(1.6.0,先前在原始碼樹內)。數個樹內建置工具已移除,N6 移至 TinyUSB 堆疊;下游分支應檢視 韌體儲存庫 的歷史——尤其是 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 結果存取器中去掉 (),或保留舊式寫法不動,因為 attrtuple 仍支援可呼叫的存取器(image 模組變更)。

  4. 稽核 find_line_segments()get_regression(),以及任何 find_apriltags() 標籤族的選擇(image 模組變更)。

  5. protocol.init() 呼叫中將 timer_mspoll_ms 更名;移除 protocol.poll()soft_reboot=protocol 模組變更)。

  6. 對於 ML 工作流程:重新檢視任何需要信箱黑邊輸入的模型(ML 函式庫變更)。