v5.0.1#

v5.0.1 は v5.0.0 の上に積み重ねられたメンテナンスリリースです — レガシーの sensor モジュールは csi 上の Python 互換レイヤーになり、フレームバッファに読み込まれた画像はカメラフレームと同じようにプレビューされるようになり、JPEG エンコーダーは 1 MB の出力上限がなくなってオーバーフローを正しく処理するようになったほか、カメラ・プロトコル・ネットワーク・ML ライブラリに関する多数の修正が含まれています。csi 向けに書かれたスクリプトに対する 破壊的なAPI変更はありません。少数の動作変更は 破壊的なAPI変更 の下に列挙しています。

ハイライト#

  • レガシーの sensor モジュールは、 csi 上に構築されたフローズン Python モジュールになりました。 インポート時に非推奨警告を出力し、csi モジュールがサポートできない少数の関数は OSError を発生させるようになりました。sensor モジュールの変更 を参照してください。

  • 読み込んだ画像がカメラフレームと同じようにプレビューされます。 copy_to_fb=True でフレームバッファに置かれた画像(image.Image、image.ImageIO.read()、fir.snapshot()、tof.snapshot())は、直ちにではなく、次の画像がフレームバッファを上書きする時点で — その上に描画された内容とともに — IDE にフラッシュされます。プレビューの変更 を参照してください。

  • JPEG エンコーダーの全面見直し。 1 MB の出力バッファ上限が撤廃され(バッファのサイズは空きメモリから決まります)、ソフトウェアとハードウェアの両方の経路でオーバーフローが、切り詰められたファイルを書き出す代わりに正しく処理されるようになり、圧縮画像をもう一方の圧縮拡張子で保存するとゴミデータを書き出す代わりに例外が発生するようになりました。

  • 新しい protocol.poll() と、protocol.CBORChannel 向けの 6 つの新しい CBOR ウィジェット(text、lineedit、pushbutton、spinbox、radio、waveform)。

  • YOLO Pro ポストプロセッサ、FLIR Lepton 3.1R / UW のサポート、IMU バースト読み出し、OpenMV N6 での CAN、そして ネットワーク対応のシミュレーター ターゲット。

新機能#

  • YoloPro — Edge Impulse YOLO Pro 物体検出モデル向けの新しいポストプロセッサと、yolo_pro_detector.py サンプル。(f3f150ebd, ea7bbb398)

  • protocol.poll() — USB 割り込みや poll_ms タイマーから駆動されないカスタムトランスポート向けに、プロトコルタスクを必要に応じて 1 回分実行します。protocol.init() を再度呼び出してスタックを再初期化することもできます。(c00c215f9, f849ffb1b)

  • CBOR チャネルウィジェットの追加 — protocol.CBORChannel.add() に text(静的な文字列)、lineedit(書き込み可能な文字列)、pushbutton(瞬時的なアクション)、spinbox(ステップ単位の数値入力)、radio(選択肢グループ)、waveform(sample_rate、series、typecode 引数を持つ 1D 時系列。インターリーブされたサンプルのバイト列を代入してストリーミングします)が追加されました。(8016d29ba)

  • csi.CUSTOM — csi.CSI.framesize() は、カスタムの (w, h) 解像度が設定された後、無名の整数ではなく利用可能な定数を返すようになりました。(af8841654)

  • IMU バースト読み出し — imu.__read_reg() は省略可能な書き込み可能バッファを受け取り、1 回のトランザクションで連続するレジスタからそれを埋めます。(244ca480a)

  • FLIR Lepton 3.1R と Lepton UW が、ラジオメトリックゲインモードも含めて Lepton ドライバで認識されるようになりました。(0fc356632)

  • シミュレーターのネットワーク対応 — MPS2_AN500 QEMU ターゲットに lwIP とユーザーモード NIC が追加され、requests、mqtt、sensor がフローズンで組み込まれ、ネットワークのユニットテストも加わりました。(23546dfb1, 61d187305, 15096c3a2)

  • OpenAI 互換 API のサンプル — openai_compatible.py は JPEG をスナップショットし、シーン説明のために chat-completions エンドポイントへ POST します。(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 の出力はしきい値処理の後に転置されて、他のモデルと同様に検出ごとに 1 行で格納されるようになりました。(b5c7853f2, c45f99cad)

  • PAG7936 の安全なシャットダウン — 新しいセンサー停止フラグにより、RESET/PWDN の切り替え前に PAG7936 をスリープさせるようになり、センサーを延長ケーブルで使用した際のロックアップが修正されました。またドライバは、MIPI CSI-2 用かパラレル用かのレジスタセットを、ビルド時ではなく実行時にセンサーの I2C アドレスから選択するようになりました。(10026530c, f6acf14ec, 5f0251c74)

  • ImageIO の再生ペーシングは、フレーム間隔を待つ間 WFI でスリープする代わりに、保留中のイベントを処理するようになりました。(a54790193)

  • MicroPython サブモジュールの更新 — QEMU ポートでの完全なネットワークサポート、バックアップ SRAM/BKP レジスタを介した STM32 での machine.mem_backup、STM32F4 での SDIO ハードウェアフロー制御の無効化維持、非キャッシュ領域向けの MPU 属性の再利用。(31ada5626, ab61d27a6, 06bddf13a)

  • differential-translation.py は非推奨の sensor モジュールではなく csi.CSI オブジェクトを通じてキャプチャするようになり、サンプルの import 周りの空行が統一されました。(68c866e7f, 9ceff4513)

バグ修正#

カメラとセンサー:

  • カスタムの (w, h) 解像度を 2 回続けて設定すると、センサーは最初のサイズのままなのに csi.CSI.width() / height() は 2 番目のサイズを報告していました。「変更なし」の高速パスはカスタムサイズを除外するようになりました。(cfbb70156)

  • csi.CSI.lens_correction() は radi と coef をブール値として解析していたため、ドライバに渡される値が指定したものと異なっていました。(ab44b3a77)

  • PAG7936: 露出とゲインを続けて設定すると互いに上書きし合っていました(両者は 1 つのマニュアルモードを共有し、読み戻しレジスタは 1 フレーム遅れるため)。ドライバはマニュアルモードに入るときだけマニュアルレジスタを初期化し、設定対象のコントロールのみを書き込むようになりました。(e7a18c0a0)

  • OpenMV N6 での PAG7936 および PS5520 の BAYER キャプチャは、N6 の ISP が生の Bayer をリスケールできないため、フル解像度以外のサイズでは「Failed to initialize the CSI interface」で失敗していました。これらのセンサーは 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)

image モジュール:

  • 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 ソケット向けに sdcard SPI ドライバがフローズンで組み込まれました。(a258f4814)

  • OpenMV RT1062 — lora-sx126x / lora-sync / lora-async をフローズンで組み込み(新機能を参照)。

  • FLIR Lepton 3.1R / UW — Lepton 対応のすべてのボードで Lepton ドライバに認識されます。

  • PAG7936 — 安全なシャットダウンのための停止処理、実行時のインターフェース選択、露出/ゲインの修正、N6 での BAYER キャプチャ。

  • PS5520 — N6 でのネイティブサイズによる BAYER キャプチャ。

  • シミュレーター (MPS2_AN500) — ネットワーク対応。

  • すべてのボード — sensor 互換モジュールがすべてのボードのマニフェストにフローズンで組み込まれています。

破壊的なAPI変更#

v5.0.1 では csi および image API に破壊的な変更はありません。v5.0.0 で動作していたスクリプトは変更なしで動作しますが、以下の動作変更があります。

sensor モジュール (behavior)#

ネイティブの sensor モジュール(modules/py_csi.c)は削除され、csi の上で同じ API を実装するフローズン Python モジュールに置き換えられました。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 オブジェクトはインポート時に作成されるため、カメラが見つからない場合は sensor.reset() ではなく import sensor の時点で例外が発生するようになりました。

  • csi に相当するものがないため、次の関数は OSError を発生させるようになりました: get_fb()、alloc_extra_fb()、dealloc_extra_fb()、set_auto_rotation()、get_auto_rotation()、disable_delays()、disable_full_flush()。(2 つの *_extra_fb 関数は v5.0.0 の時点ですでに例外を発生させていました。)最後の 2 つについては 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() はリクエストの後の引数を最大 4 つまで転送します。

  • 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

画像のストリームを読み込むループは変更不要で、描画内容が表示されるようになります。1 枚 の画像を読み込んで終了するスクリプトでは、明示的にフラッシュする必要があります:

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 は、しきい値処理の後にモデル出力を転置するようになり、残った検出はボックスごとに 1 列(bb[4:, :])ではなく、Darknet および Edge Impulse のポストプロセッサと同様にボックスごとに 1 行(bb[:, 4:])で格納されます。公開されている ((x, y, w, h), score) の結果は変わりません。

コミット: c45f99cad、b5c7853f2

protocol モジュール (minor)#

protocol.poll() が復活しました。v5.0.0 ではプロトコルタスクがタイマーに移った際に削除されましたが、カスタムトランスポート向けにタスクを明示的に駆動する手段として戻ってきました。それ以外は変更ありません — これを呼び出していなかったスクリプトには影響しません。

コミット: c00c215f9

ビルド/ツール (tooling)#

これらはいずれも MicroPython スクリプトに影響しません。py_image.c は分割され、ディスクリプタオブジェクト(cascade、keypoints、LBP、keypoint match)は py_image_descriptor.c へ、統計オブジェクト(similarity、statistics、percentile、threshold、histogram)は py_image_stats.c へ移動しました。imlib のエンコーダー API は imlib の他の部分と揃えられました。jpeg_compress / png_compress は成功時に 0、エラー時に -1 を返し、jpeg_compress から realloc 引数が削除されました(リサイズはバッファの所有権に基づいて制御されます)。omv_protocol_channel.h の OMV_PROTOCOL_MAX_CHANNELS は OMV_PROTOCOL_CHANNEL_MAX になり、各ポートは初期化時に py_protocol_init0() を呼び出すようになりました。OMV_PAG7936_MIPI_CSI2 ボード定義は廃止されました(インターフェースは実行時に選択されます)。CI 依存関係の更新と、空のリリース changelog の修正で締めくくられています。フォークに関連する詳細については、ファームウェアリポジトリ の履歴を参照してください。

移行チェックリスト#

  • まだ import sensor を使っていますか? 警告付きで動作します。csi へ移行し(v5.0.0 の移行)、disable_delays / disable_full_flush を csi.CSI() コンストラクタ引数に置き換え、get_fb および自動回転の呼び出しを削除してください。

  • 1 枚の画像を copy_to_fb=True で読み込んで、それが表示されることを期待していますか? 読み込み後に img.flush() を追加してください。

  • YOLOv8 ポストプロセッサをコピーしましたか? しきい値処理後の出力は、列ではなく行でインデックスしてください(bb[:, 4:])。

  • タプルを設定した後に csi0.framesize() を比較していますか? 現在は csi.CUSTOM を返します。

  • それ以外: 再フラッシュして実行するだけです。