OpenMVカメラですぐに始める機械学習による物体検出

著者 Jacob Beningo

DigiKeyの北米担当編集者の提供

物体の検出および分類に機械学習(ML)を応用することは、組み込みシステム業界、とりわけモノのインターネット(IoT)、セキュリティ、先進運転支援システム(ADAS)、産業用オートメーションに基づいたシステムで差し迫ったニーズになりつつあります。しかしながら、物体検出は複雑なテーマでMLは比較的新しい技術であるため、物体を検出するMLアプリケーションの開発は難しく面倒なものになる可能性があります。

たとえば、これまで物体検出を成功させるには、開発者がOpenCVのようなフレームワークを習得し、コンピュータ装置に数千ドルを費やす必要がありました。そのため、物体検出およびマシンビジョンへの従来のアプローチは、時間だけでなく費用もかかるものでした。

MLの専門家になったり、装置にひと財産を費やしたりする必要なしに、物体検出およびマシンビジョンにMLを応用することを検討している技術者にとって、PythonでプログラミングできるSparkFun Electronicsのカメラ モジュールOpenMV H7は革新的なソリューションです。このモジュールは、安価な「Arduino」タイプの画像処理および検出用モジュールとして設計されています。そのため、本モジュールおよび関連ソフトウェアは、安価なモジュールの形でMLを使用して容易に物体の検出および分類ができる、ユニークで興味深いソリューションです。

この記事では、OpenMV H7カメラモジュールを紹介し、開発者がCIFAR-10コンピュータビジョンの画像データセットを使用して物体検出へMLを応用し始める方法を紹介します。

OpenMV H7カメラモジュール

機能豊富なソフトウェアライブラリがあるOpenMV H7カメラモジュールを使うと、開発者がMLアプリケーションを迅速に作成することに大いに役立ちます。たとえば、OpenMVカメラを使用して顔と目を検出し、瞳孔を精密に追跡することもできます。球状の印やマーカーを生成して、色を追跡するのに使うことができます。MLを利用して独自の物体を検出および追跡する方法に関するサンプルもあります。

OpenMV H7カメラモジュールは、従来のマシンビジョンシステムより桁違いに低いコストで、MLを利用した物体検出および分類に必要なハードウェア部品をすべて搭載した、単一の統合開発ボードです。本モジュールは1.4 x 1.75インチと比較的小型で、以下のものを搭載しています。

  • ハイエンドマイクロコントローラ
  • 統合型で交換可能なカメラモジュール
  • 電池コネクタ
  • USBマイクロコネクタ
  • 3色LED
  • マイクロSDソケット(最大64GBのカードに対応)1基
  • 拡張入出力(I/O)

SparkFun Electronics製OpenMV H7カメラモジュールの画像図1:OpenMV H7カメラモジュールは、MLを利用したマシンビジョンアプリケーションの迅速な開発およびデプロイに必要なすべての部品が完全統合されている。(画像提供: SparkFun Electronics)

拡張I/Oにより、マイクロコントローラからさまざまな周辺機能を利用できます(図2)。そうした機能には、以下の通信インターフェースが含まれます。

  • UART
  • SPI
  • I2C
  • CAN

拡張I/Oには、サーボ駆動、D/Aコンバータ(DAC)を介した信号発生、またはA/Dコンバータ(ADC)を介したセンサ値の読み取りのための制御チャンネルおよびデータチャンネルも含まれます。これらの拡張I/OによりOpenMVモジュールは、ホームオートメーション、ロボット誘導、産業用オートメーション、物体検出および空間追跡におけるビジョンアプリケーション用にきわめて興味深いものとなっています。

SparkFun製OpenMV H7カメラモジュールのピン構成の表図2:OpenMV H7カメラ モジュールには、きわめて多くの拡張I/Oピンがある。これらのピンは、サーボモータの制御やセンサからのサンプリング、あるいはWi-Fiモジュールとの通信に使用して、IoTデバイスを構成することができる。(画像提供: SparkFun)

搭載マイクロコントローラはSTMicroelectronicsSTM32F765VIT6であり、100ピンのLQFPにArm Cortex-M7プロセッサを内蔵しています。このプロセッサは216MHzで動作し、2MBのフラッシュと512KBのRAMを備えています。倍精度浮動小数点演算ユニット(FPU)と豊富なDSP命令を備えているため、きわめて性能が高くマシンビジョンアプリケーションに適しています。このマイクロコントローラは、撮像アプリケーションを高速化できるハードウェアJPEGエンコーダも内蔵しています。STM32F765VIT6の全体ブロック図を図3に示します。

STMicroelectronicsのSTM32F765VITが2MBのフラッシュと512KBのRAMを内蔵していることを示す図図3:STM32F765VITは、2MBのフラッシュ、512KBのRAM、ハードウェアJPEGエンコーダなどの周辺モジュールとDSP命令を備えているため、マシンビジョンアプリケーションに最適。(画像提供:STMicroelectronics)

OpenMV H7カメラモジュールは、さまざまなカメラモジュールをサポートしている点でユニークです。たとえば、開発者がオンボードカメラ(解像度640 x 480)を使いたくない場合、ON SemiconductorのイメージセンサMT9V034をサポートしているモジュールに切り換えることもできます。MT9V034は、幅1/3インチのVGA方式CMOSアクティブピクセルデジタルイメージセンサで、グローバルシャッターとハイダイナミックレンジ(HDR)モードを備えています。このセンサは解像度が752 x 480で、-30˚C~+70˚Cの広い温度範囲で動作するように設計されています。ON Semiconductorは、このイメージセンサ用に開発ボードMT9V034C12STCH-GEVBを提供しています(図4)。

ON SemiconductorのMT9V034C12STCH-GEVB開発ボードの画像図4:MT9V034C12STCH-GEVBは内蔵レンズを備えたMT9V034イメージセンサ用の開発ボードで、開発およびテストを迅速化できる。(画像提供:ON Semiconductor)

最初の物体検出アプリケーションの開発

OpenMV H7カメラモジュールのアプリケーション開発は、OpenMV IDEを通してすべて行います。このIDEは、アプリケーション開発用Pythonインターフェースを備えています(図5)。Pythonがあるため、低級プログラミング言語を知っている必要はありません。実際、スクリプトをPythonで記述できるだけでなく、OpenMV H7カメラモジュールはネイティブでMicroPythonを実行します。このため、開発者はきわめて容易にマシンビジョンアプリケーションを記述し始め、ML推論を最小限の労力で実行することができます。

OpenMV IDEのPythonベースのインターフェースの画像(クリックして拡大)図5:OpenMV IDEは、OpenMV H7カメラモジュールのアプリケーションコード開発のためにPythonベースのインターフェースを提供する。そしてアプリケーションは、MicroPythonを実行しているカメラモジュールにスクリプトとして送られる。(画像提供: Beningo Embedded Group)

セットアップを完了した開発者がはじめにすることの1つは、最小限のhello_world.pyを実行することです。このスクリプトにはリスト1のコードが記述されています。このPythonスクリプトは、OpenMVカメラを有効にして連続的にスナップ写真を撮る方法を示しています。これを使うと、ライブ動画を撮ってフレームレートを測定できます。フレームレートは、PCに接続している間は最低25fps(フレーム毎秒)から約60fpsまでになる場合があります。このアプリケーションは、画面左下隅の接続ボタンでOpenMVカメラをOpenMV IDEに接続してから緑色の実行ボタンをクリックするだけで実行されます。

コピー
# Hello World Example
#
# Welcome to the OpenMV IDE!Click on the green run arrow button below to run the script! 
import sensor, image, time
 
sensor.reset()                      # Reset and initialize the sensor.sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)   # Set frame size to QVGA (320x240)
sensor.skip_frames(time = 2000)     # Wait for settings take effect.clock = time.clock()                # Create a clock object to track the FPS. 
while(True):
    clock.tick()                    # Update the FPS clock.    img = sensor.snapshot()         # Take a picture and return the image.    print(clock.fps())              # Note: OpenMV Cam runs about half as fast when connected
                                                                        # to the IDE.The FPS should increase once disconnected.

リスト1:OpenMV IDEのhello_world.pyアプリケーションは、OpenMVカメラモジュールを有効にしてライブ動画を提供する。(コード提供:OpenMV)

初めての物体検出および分類のテストを実行するためには、目的とする物体認識クラスでMLネットワークをトレーニングする必要があります。物体検出モデルのトレーニングとモデルがどの程度うまく働いているかのテストによく使われる画像データセットは、CIFAR-10です。CIFAR-10データセットは60,000個の画像から成り、以下10種類の画像クラスのカラー画像(32 x 32)が含まれています。

  • 飛行機
  • 自動車
  • 鹿
  • トラック

モデルをトレーニングしてOpenMVカメラで実行できる推論に変換するために使われる方法を説明することは、この記事の範囲を超えます。しかし、モデルの開発を経ずに、CIFAR-10でトレーニングしたネットワークを実行することは可能です。つまり、OpenMV IDEには、カメラにロードするだけでよいCIFAR-10用にトレーニングされたモデルが既に含まれているのです。

このモデルを使うには、OpenMVカメラをPCおよびOpenMV IDEに接続します。OpenMV IDEの中で、[ツール] -> [機械学習] -> [CNNネットワークライブラリ]をクリックします。ウィンドウが開いて、OpenMVのqtcreator配下のmodelsフォルダを表示します。以下の2つの選択肢があります。

  • cmsisnn
  • tensorflow

cmsisnn配下で、cifar10フォルダに移動し、cifar10.networkをクリックして開きます。その後、もう1つのウィンドウが開きます。このウィンドウは、トレーニング済みネットワークのファイルをOpenMVカメラに保存するためのものです。ここでカメラ付きで表示されるマスストレージドライブを選択して、ネットワークを保存することができます。

ネットワークを保存したら、[ファイル] -> [例] -> [25-Machine-Learning] -> [nn_cifar10_search_whole_window.py]を選択して、機械学習サンプルのCIFAR-10をロードします。これで、下に示すサンプルスクリプトがロードされます(リスト2)。

コピー
# CIFAR-10 Search Whole Window Example
#
# CIFAR is a convolutional neural network designed to classify its field of view into several
# different object types and works on RGB video data.#
# In this example we slide the LeNet detector window over the image and get a list of activations
# where there might be an object.Note that use a CNN with a sliding window is extremely compute
# expensive so for an exhaustive search do not expect the CNN to be real-time. 
import sensor, image, time, os, nn
 
sensor.reset()                         # Reset and initialize the sensor.sensor.set_pixformat(sensor.RGB565)    # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)      # Set frame size to QVGA (320x240)
sensor.set_windowing((128, 128))       # Set 128x128 window.sensor.skip_frames(time=750)           # Don't let autogain run very long.sensor.set_auto_gain(False)            # Turn off autogain.sensor.set_auto_exposure(False)        # Turn off whitebalance. 
# Load cifar10 network (You can get the network from OpenMV IDE).net = nn.load('/cifar10.network')
# Faster, smaller and less accurate.# net = nn.load('/cifar10_fast.network')
labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
 
clock = time.clock()
while(True):
    clock.tick()
 
    img = sensor.snapshot()
 
    # net.search() will search an roi in the image for the network (or the whole image if the roi is not
    # specified).At each location to look in the image if one of the classifier outputs is larger than
    # threshold the location and label will be stored in an object list and returned.At each scale the
    # detection window is moved around in the ROI using x_overlap (0-1) and y_overlap (0-1) as a guide.    # If you set the overlap to 0.5 then each detection window will overlap the previous one by 50%.Note
    # the computational work load goes WAY up the more overlap.Finally, for mult-scale matching after
    # sliding the network around in the x/y dimensions the detection window will shrink by scale_mul (0-1)
    # down to min_scale (0-1).For example, if scale_mul is 0.5 the detection window will shrink by 50%.    # Note that at a lower scale there's even more area to search if x_overlap and y_overlap are small...    # contrast_threshold skips running the CNN in areas that are flat. 
    for obj in net.search(img, threshold=0.6, min_scale=0.5, scale_mul=0.5, \
            x_overlap=0.5, y_overlap=0.5, contrast_threshold=0.5):
        print("Detected %s - Confidence %f%%" % (labels[obj.index()], obj.value()))
        img.draw_rectangle(obj.rect(), color=(255, 0, 0))
    print(clock.fps())

リスト2:OpenMV IDEのサンプルアプリケーションnn_cifar10_search_whole_window.pyは画像の分類に使われ、分類の信頼度測定を行う。(コード提供:OpenMV)

このテストアプリケーションは、hello_world.pyのスクリプトと同様に実行できます。左下の[接続する]をクリックしてOpenMV IDEをモジュールに接続してから、[開始(スクリプトの実行)]をクリックします。この時点で、カメラはスクリプトを実行して、撮影中の画像を分類しようとします。ターミナルウィンドウは、画像が分類されたかどうかと信頼度を出力します。

この時点ですべきことは、CIFAR-10データセット内にあるさまざまな物体をカメラに示して、それらを分類させることだけです。この記事では、カメラに猫の画像(図6)と飛行機の画像(図7)を示しました。画像から判断するのは難しいですが、信頼度は70%程度でした。信頼度は、トレーニング画像とテスト画像の差異、照明の状況、その他の要因によって低くなる場合があります。信頼度を上げることは、トレーニングの追加とカメラ環境の厳格な制御を行えば確実に可能です。

CNNネットワークを実行しているOpenMV IDEカメラの画像(クリックして拡大)図6:猫の画像を認識用に示された状態で、CIFAR-10データセット用CNNネットワークを実行しているOpenMV IDEカメラ。(画像提供:Beningo Embedded Group)

CIFAR-10用CNNネットワークを実行しているOpenMV IDEカメラの画像(クリックして拡大)図7:飛行機の画像を認識用に示された状態で、CIFAR-10データセット用CNNネットワークを実行しているOpenMV IDEカメラ。(画像提供:Beningo Embedded Group)

OpenMV H7の機能の拡張

OpenMVモジュールを拡張して、各種カメラモジュールや無数にある外部センサと共に使用する状況は数多くあります。

OpenMVモジュールにはI/O拡張機能がありますが、追加で電源、グランド、通信信号を利用できるようにするには、外部拡張ボードを使うと便利な場合もあります。便利な拡張ボードの一例が、DFRobotのOpenMV M7モジュール用Gravity拡張シールドであるDFR0578です(図8)。この図で、Gravityモジュールにはかなりの数の電源ピンとグランドピンがあるのがわかります。追加のI2Cラインも拡張し、モジュールに電力供給する追加手段を提供しています。これにより、ブレッドボードを使用したり配線をスプライスしたりする必要なく、外部のセンサやモジュールのインターフェース接続がはるかに容易になります。

DFRobotのGravity拡張ボードの画像図8:DFRobotのOpenMV cam M7用Gravity拡張ボードは、使いやすい追加用ヘッダを複数備えており、迅速な試作が容易にできる。(画像提供:DFRobot)

Gravityボードに加えて、開発者に役立つ可能性のある興味深いもう1つの拡張ボードが、DFRobotのFireBeetleカバー – カメラ&オーディオメディアボードであるDFR0498です(図9)。 FireBeetle開発モジュールは、以下のものを備えています。

  • IISコーデック接続用インターフェース
  • カメラモジュール
  • イヤホン
  • マイクロフォン

OpenMV H7カメラモジュールに接続できる拡張ボードは、エンドアプリケーションに応じて他にも多数あります。

DFRobotのFireBeetle DFR0498の画像図9:DFRobotのFireBeetle DFR0498は、マイクロフォンなどのメディアデバイス用拡張機能を備えている。(画像提供: DFRobot)

OpenMVを使用した作業のヒントとコツ

OpenMV H7カメラモジュールの使用を開始することは難しくありませんが、初めて使用する開発者が知っておくべき微妙な事柄や判断事項が数多くあります。本モジュールを使いはじめる場合の「ヒントとコツ」をいくつか挙げておきましょう。

  • 初めて本モジュールを使う場合、必ず本モジュールの焦点をOpenMVのドキュメントで説明されている手順にしたがって調節してください。
  • メニューの[ファイル] -> [例]から、色の検出方法から顔認識までの多数の例を利用してください。
  • インターネット接続を追加するために、Wi-Fiシールドを使うことを検討してください。Wi-Fiシールドは、[ツール] -> [OpenMV Camの設定]のオプションで、OpenMV IDEの起動時に自動的に有効化できます。
  • 関心対象の物体についてMLモデルをトレーニングするため、TensorFlow Liteを使うことを検討してください。

これらの「ヒントとコツ」に従えば、初めてOpenMV H7カメラモジュールに取り組む場合に大幅に時間を節約でき、悩み事が減ることでしょう。

まとめ

既述のようにOpenMV H7カメラモジュールは、開発者が物体検出や関連アプリケーションにMLの原理を迅速に応用し始める助けとして、この上なく適しています。開発者が設計迅速化のため活用できるOpenMV H7用サンプルアプリケーションだけでなく、カメラやセンサ用の拡張オプションも多数あります。始めるために必要なのは、数行のPythonコードの記述方法を知っていることだけであり、動作するアプリケーションをその複雑さに応じて数時間以内に作成できるのです。

DigiKey logo

免責条項:このウェブサイト上で、さまざまな著者および/またはフォーラム参加者によって表明された意見、信念や視点は、DigiKeyの意見、信念および視点またはDigiKeyの公式な方針を必ずしも反映するものではありません。

著者について

Image of Jacob Beningo

Jacob Beningo

Jacob Beningo氏は組み込みソフトウェアコンサルタントで、現在、製品の品質、コスト、市場投入までの時間を改善することで、ビジネスを劇的に変革するために数十か国以上のお客様と作業しています。同氏は、組み込みソフトウェア開発技術に関する200以上の記事を発表しており、引っ張りだこのスピーカーでありテクニカルトレーナです。ミシガン大学のエンジニアリングマスターを含む3つの学位を取得しています。気楽にjacob@beningo.comにメールするか、彼のウェブサイトwww.beningo.comから連絡してみてください。そして毎月のEmbedded Bytes Newsletterにサインアップしましょう。

出版者について

DigiKeyの北米担当編集者