パスコンパスの日記

何か色々作るのが好きです

【キョロキョロV④】m5StickV サーボ2軸マシンでまずは色検出をしてみました

 今までの記事ではメカの組み方、サーボの繋ぎ方、サーボの動かし方をお伝えしてきました。
 記事自体は楽しみながら頑張って書いていますが、正直ここまではmicro pythonが使えるマイコンであればどれでも可能な内容だったと思います。
 そこでいよいよ今回からm5StickVについているカメラと今回組んだサーボを生かして緑色の物体等を追従する動作をさせていきたいと思います。緑色の物体とした理由は以下サイトにサンプル*1があったためです。

Image · MaixPy DOC

長くなったため2回に分けます。今回は色の設定の仕方を中心に関してお伝えします。
また、プログラムは本職でないため冗長な処理や見づらいところがありましたらやんわりご指摘いただければ幸いです。

目次

しきい値の意味に関して

 今回のサンプルでは機械学習は使っていません。m5StickVで使用可能なopenmvのAPIを利用している様です。
 最初にサンプルのimage.find_blobsという関数の以下の引数がどうしてgreenを表しているのか分からなかったので検索してみました。

green_threshold   = (0,   80,  -70,   -10,   -0,   30)
# ~中略~ 
blobs = img.find_blobs([green_threshold])

For RGB565 images each tuple needs to have six values (l_lo, l_hi, a_lo, a_hi, b_lo, b_hi) - which are minimums and maximums for the LAB L, A, and B channels respectively. (https://docs.openmv.io/library/omv.image.html より)

 調べたところ、RGB565とはRED:5bit(0~31)、GREEN:6bit(0~63)、BLUE:5bit(0~31)でのRGB値の表現方法を表している様です。 ただ今回はどちらかというと後半が大事でしょうか。Lab色空間という補色空間の一種だそうです。

Lab色空間に関して

 Lab色空間は以下の軸で色を表す方式とのことです。初めて知りました。面白いですね。

  • L:明度 -(暗い) ↔ +(明るい)
  • a:色相 -(緑)+(赤)
  • b:色相 -(青)+(黄)

こちらのサイトの図が分かりやすいです。

色の数値化には、表色系を使用します。1-楽しく学べる知恵袋 | コニカミノルタ

引数では(明るさL最小値, 明るさL最大値, 色相a最小値, 色相a最大値, 色相b最小値, 色相b最大値 )というタプルで色のしきい値を決めているということが分かりました。

Maix Py IDEでのしきい値の設定

 ここまで分かったところでMaix Py IDE*2を使ってみます。 今回この記事で使用しているMaixPy IDEのバージョンは 0.2.4です。

ヒストグラムでのしきい値設定

  1. [ツール]→[Select board]→[m5StickV]を選択しTypeCケーブルでPCとm5StickVを接続後、左下の接続ボタンを押します。
  2. Maix Py IDEで新規作成した時にデフォルトで入るプログラムを実行して緑色の物体をカメラに映してみます。
  3. IDEの右側のカラースペースを切り替えて観察してみます。
    下側にLABのグラフが表示されているのでこれの値をメモすることでも設定できそうです。

f:id:yoichi_41:20190915032423p:plain

しきい値エディタでのしきい値設定

 ただ上記の方法では背景色の成分も入ってしまいます。他に方法がないかと探していたら以下の場所に[しきい値エディタ]というものを見つけました。

  1. 上記の1,2を行います。
  2. この状態で[ツール]→[マシンビジョン]→[しきい値エディタ]をクリックするとフレームバッファを選択できます。
  3. 右の[反転]のチェックマークを入力解除します。*3
  4. バーをずらしてしきい値を設定します。 上述の緑色のしきい値に値を合わせてみました。

f:id:yoichi_41:20190915183242p:plain

 右の黒白のみの画面の方の白色のピクセルがトラッキングされたピクセルということで、確かに緑色の部分が白くなっています。
違う色を設定したい場合は下のバーをずらして一番下に表示されている[LABしきい値]を変更すれば良さそうです*4。便利ですね。以下の様に上記のサイトの図を参考に自分で黄色にセッティングしてみました。

f:id:yoichi_41:20190915185742p:plain

おおよそ黄色の領域が白くなっています*5。これで任意の色を設定できそうです。

緑色と黄色を検出するプログラム

 せっかくなのでサンプルに追記して黄色も検出できるようにしてみました。

import sensor
import image
import lcd
import time
lcd.init()
lcd.rotation(2) # m5stickVでは2回ほど回すと向きが合います。
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.run(1)
green_threshold   = (30,   80,  -70,   -10,   -0,   30)
yellow_threshold   = (74, 100, -20, 20, 52, 127) # しきい値を追加してみました。
while True:
    img=sensor.snapshot()
    blobs = img.find_blobs([green_threshold])
    blobs2 = img.find_blobs([yellow_threshold]) # 追加してみました。
    if blobs:
        for b in blobs:
            tmp=img.draw_rectangle(b[0:4],color=(0,128,0)) # 文字色を緑に変更しています。
            tmp=img.draw_cross(b[5], b[6],color=(0,128,0)) # 文字色を緑に変更しています。
            c=img.get_pixel(b[5], b[6]) # 文字色を緑に変更しています。
            img.draw_string(60, 100, "green",color=(0,128,0), scale=2) # 色の表示を追記しました。
    # 以下、コピペした黄色の検出です。(文字色は黄色にしています。)
    if blobs2:
        for b in blobs2:
            tmp=img.draw_rectangle(b[0:4],color=(255,255,0))
            tmp=img.draw_cross(b[5], b[6],color=(255,255,0))
            c=img.get_pixel(b[5], b[6])
            img.draw_string(60, 150, "yellow",color=(255,255,0), scale=2)
 # この上まで追加しています。
    lcd.display(img)

動作の様子

少し緑を誤検出していますが、ある程度両方の色を識別できている様です。

今回はかなり長文でしたが、読んでくださりありがとうございました。 次はサーボと連携します。

関連記事

他のキョロキョロV(m5StickV)関連の記事のまとめは以下にあります。DL可能な3Dデータも公開しています。
読んでいただけたらとても嬉しいです。

yoichi-41.hatenablog.com

*1:1.1. Routine 1: Find greenです。

*2:こちらからDLできます。 http://dl.sipeed.com/MAIX/MaixPy/ide/

*3:なぜか最初のみ右の画面全域ではなかったのですがこちらの動作をしたところ全体の画像を取得できました。

*4:max「最大」に対してのminが「分」と訳されてしまっています。ご注意ください。

*5:この後しきい値を再度調整したので上記画像の値と異なっています。