Take’s diary

Macとマイコンに関すること--ワクワクの製作日記

Jetson Xavier を動かしてみた。

JETSON XAVIER(ザビエル)が来た

今回は発売間もないザビエルを手に入れたので、簡単なテストやインストール結果などを書くことにします。若くは無いので開封の儀は、止めておきます。

 本体は、プレゼン写真で見る限りエンジニアリングプラスチックかと思っていましたが、アルミダイキャスト製でずっしりと重い立派なものでした(ノートパソコン1個分ですからトーゼン)。性能に関してはメーカーの資料を見て下さい。内部eMMC容量以外は現状不満の無い内容です。CPUは最大8個すべて2.2Gで動きます。

f:id:TAKEsan:20180913141710j:plain

f:id:TAKEsan:20180913141710j:plain   f:id:TAKEsan:20180913141759j:plain

 USBCが2カ所付いているのでいろいろなものが接続できそうです。TX2と違ってWIFIが付いていないのですがUSBドングルでなんとかなりそう。

 直ぐに始められるというキャッチが頭に入ってたので、ケーブル類をつないで、パワースイッチを入ればなんとかなると思ってました。しばらくすると何やらコマンド画面が出てきて、インストーラを実行しないとダメとか....。表示通りコマンドを入力して、

f:id:TAKEsan:20180913142257j:plain

 

少し待つと、UBUNTU18.04画面が現れます。反応が異様に鈍い...。

 中をよく調べると、初期状態ではCUDAも何もかも入っていない。スイッチオンではUbuntu18.04が動くだけでした。やっぱり...と思いながら、気持ちを入れ直して、いつものJetpacインストールを行います。経験上、OSもすべて上乗せし直したした方が良いようです。jetpacのバージョンは4です。

Jetson Download Center | NVIDIA Developer

 ここからJetpack4.0とインストールガイドをダウンロードしますが、NVIDIAのユーザー登録が必要です。

 基本は今まで書いたのとほぼ同じ。

NVIDIA JETSON TX1 を動かしてみた!! - Take’s diary

 インストール用には、母艦接続用USBケーブルを差して(一番上の写真が接続場所です)母艦Ubuntu(今回はIntel i7 6700k+GTX1080ti)と接続します。母艦は16.04でもOKでしたが、OpenCV3.3.1でないとエラーになります。3.4の方はダウングレードする必要があります(他に方法があると思いますが)。フォースリカバリーモードにする方法も前と同じです。

.............30分前後時間が必要。

Jetpacインストールが終わったらまず最初にやっておくこと。

 ザビエルもTX2も、省エネ型とかMAXパワーとかいろいろなCPUモードで動きます。モード切替方法は大切だと思うのですが、マニュアルには詳細な説明が無いようです。最強モードにするにもこつが必要。

まずCPUとGPUのクロックを最大にします。

home へ行き

sudo nvpmodel -m 0

sudo ./jetson_clocks.sh

sudo ./jetson_clocks.sh -show    で変更内容が確認できます。

--showは別ですが、前2行を続けて実行しないとダメみたいでした。続けないと上手く変更できません。マニュアルに書いてあるjetson_clocksを実行しただけでは、最大になりません。

 sudo nvpmodel コマンドは -m 0 ~ -m 6 まで指定できて、クロックの最大設定やコアの優先が決まります。./jetson_clocks.sh -showで「自分の目で」現在の設定内容を確認しましょう。表示内容を見れば納得です。

 jetson_clocks.shを実行した後はファンが比較的大きな音で強力に回り出します。静音化対策はしていないよう....。

CPUはあまり早くない。

 早速いつものメインCPUの体感速度がわかるPythonを実施すると、6秒程度。これはTX2から30%程度のアップにとどまっています。ちなみに母艦Intel i7+GTX1080tiでは3.2秒前後なので、私の母艦の半分程度のスピードです。まーTX2のクロックアップ分と考えた方が良さそうです。それにしてもUnuntu18.04はとろい。まだ公開したてだからしょうがないっちゃーしょうが無い。みんなで寄付が必要ですねー。

 経験上以下のソースだけでCPUメインコアの速度が分かります(私には...。OSの体感スピードが、出てきた数値とほぼ比例。)。test.pyかなんかで以下のソースを保存して下さい。その場合実行はpython test.pyです。

************************************************************************************************

def fib(n):

    if n <= 1: return n

    else: return fib(n-2) + fib(n-1)

 

def entry_point(argv):

    a = time.time()

 

    result = fib(36)

    timespan = time.time() - a

    print (result)

    print (timespan)

 

    return 0

 

def target(*args):

    return entry_point, None

 

if __name__ == "__main__":

    import sys

    entry_point(sys.argv)

*************************************************************************************************

ザビエルの売りはGPU

 16ビット浮動小数点と、整数演算が小型の割にとても早いとのことですが、発表している数値は理論値に近いと思われます。これを直感的に体感するにはどうしたら良いか?。ありました。Darknetです。ただしこの方の公開しているものです。

github.com

 ここでインストールするDarknetは以前のV2.0も最新のV3.0も簡単に変更できる上に、ザビエルの売りである16ビット浮動小数点演算の指定や、soファイルの作成も可能で、標準のDarknetより早くなるようです。

 キモはMakefileの変更で、以下のようにします。CPU、CUDNN、CUDNN_HALF、

OPENCV、LIBSOはすべて1、CUDAアーキテクチャはsm62に変更します。で、普通にmake -j8であっという間にコンパイル完了。ザビエルはCPUコアが8つなので、-j8が指定できます。

f:id:TAKEsan:20180913202530p:plain

    上の画像では ARCH= の部分コメントの#マークを外してませんが、外すことを忘れずに!!

 でスピードはどうなの?

 以下のDarknet設定は、すべて16bit浮動小数点です。つまりCUDNN_HALF=1。

yoloは入力画像の大きさ設定で、認識スピードや認識率が大きく変化します。設定はyolov2.cfg又はyolov3.cfgの最初の方を変更します。

f:id:TAKEsan:20180913202023p:plain

上図で(この場合はyolov3.weight)widthとheightの数値を変えます。この数値は32の倍数ならなんとかなるようですが、自分のWEBカメラの設定以下である必要ありです。

コマンドは、

./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights -c 0

です。yolov2の場合は3を2に変更するだけでした。yolov2.weightsとyolov3.weightsファイルが必要ですが、ファイルダウンロード方法は

YOLO: Real-Time Object Detection

を参考にして下さい。ちなみにcoco.dataとcfgファイルはDarknetに入ってます。

まず母艦でyoloV3から。

 私の母艦環境はIntel i7 6700k+GTX1080ti+Ubuntu16.04です。yolov3.cfgの入力画像の面大きさ設定が416x416、608x608の場合は、どちらも30fps出てます。やっぱ早いですね。ちなみに608x608の方は認識率がかなり高くなります。以下左416x416が、右が608x608です。

f:id:TAKEsan:20180913151037p:plain   f:id:TAKEsan:20180913151111p:plain

        608x608の認識が良いことが分かると思います。

次にザビエル

f:id:TAKEsan:20180913152016p:plain f:id:TAKEsan:20180913152940p:plain

 ザビエルではyolov3.weightを使って入力画像416x416が16.1fps、608x608が9.1fpsでした。ちなみにTX2では4.4fpsと2.3fpsだったので、ザビエルはTX2の3倍以上早いことになります。右上のターミナル画面はCPUとGPUの現在設定画像です(sudo ./jetson_clock.sh --show)。

 ザビエルはここでも私の母艦の丁度半分くらいのスピードになってます。

ソフト起動時は認識画像が最大になり、ザビエルやTX2は、表示スピードがかなり鈍ります。一旦画像を消すと上写真の様な小さな画像に切り替わり、本来のスピードで表示するようになります。表示ルーチンの改良が必要のようです。

調子に乗ってyolov2ではどうなのかですが....。

f:id:TAKEsan:20180913152728p:plain  f:id:TAKEsan:20180913152754p:plain

 なんとザビエルは416x416の方は29.5fps 、608x608で15.5 fpsでした。TX2ではおのおの9.5fps、 5.2fps なのでここでも約3倍速くなりました。入力画像を608x608にするとYolo2でも認識しているものはyolo3とあまり変わらなくなるのが上画像で分かると思います。ただし細かい部分はやはりyolo3でしょうか。でもyolo3の15fps前後っていうのは魅力的ですねー。以下の動画でも確認出来ると思いますがほぼパーフェクト!!。実際ザビエルでリアルタイム画像認識している様子です。(HARF_CUDNN,yolov3,入力画像412x412)

               www.youtube.com

 AI画像認識は、いままで試して見て、デカいコンピューターを使っても現実的ではありません。気軽に持ち運びできないからです。適度に小さいものはそれなりに遅くなる。TX2がそうでした。これは新しい時代が来たって感じです。

さらにダメ押し

 CUDAのサンプルでsmoke paticlesってのがあるんですが、驚くなかれザビエルでは60fps!! 母艦でも60fps。TX2では30FPSでした。以下ザビエルの動画です。左上の60fpsって表示見えます?

           youtu.be

openFrameworksは動くか?

 ザビエルはROSに焦点を絞ってる気配がありますが、私の場合はいつもここから始まります。openFremeworks0.10.0が動きました!!。インストール方法は前の記事と同じ

takesan.hatenablog.com

 

ですが、Tessだけは再コンパイルが必要でした。tess2.aのダウンロードは以下のアドレス、

Takesan - Google ドライブ 

 この中でkiss&tess.zipを選択して下さい。openFramworks/libの中のkisstessを入れ替えます。openFrameworksでビルドしたものは60fpsが最大ですが、特に負荷の高いものなどは確実に早くなりましたし、マルチで動かしてもスピードが落ちません。ネッ。

    youtu.be

結論

 問題はGPUの使い方に尽きると思います。なので一般向けではありません。つまり普通にUbuntuマシンとして使ったら、TX2と変化があまり感じられないと言うこと。ザビエルのGPUを使った今回のAI体感では、i7+GTX1080tiよりは50%スピードダウンするがTX2の3倍速いってことが結論。いろいろなデータを調べるとGTX1060クラスメモリー容量の多いグラフィックボードを積んだ消費電力の小さなパソコンが、手のひらに乗ったというような事になるのですが、そうするとTX2では最初から諦めていた学習も可能なわけで....。

 今回は、あくまでも他人様のソフトで検証してます。これからさらに最適化すればすごいことになりそう....!!。あとはopenFrameworksにDarknetを入れるだけですが、これがなかなかできない。

 

                          では、また.....。

 

 

 

 

JETSON TX2 に OpenFrameworks 0.10.0 をインストール

TX2にJETPACK3.3をインストールしたので、最新のOF(Openframeworks0.10.0)をインストールしてみました。前にも書きましたがTX2には簡単にOFがインストールできません。OFを動かすには内部の変更作業が必要です。今回はソース変更等大きく分けて3つの作業だけで済みました。今回のOFバージョンアップはかなりTX2に向いているようで、0.9.8のようなキーボード入力時の不具合などは解消されています。またサンプルプログラムについてはgles(Pi専用のサンプル)以外は、高負荷のものでも問題なく動くようです。

f:id:TAKEsan:20180827130658p:plain

OFのダウンロード

ここからlinux armv7 をダウンロードします。

https://openframeworks.cc/download/

解凍してフォルダ名をof_10.0に変更したとします。

次に必要ライブラリをインストールします。

sudo apt install cmake

of_10.0/scripts/linux/ubuntu   に行き

sudo ./install_dependencies.sh 

を実行します。前処理が必要だったのですが、10.0の場合はすんなりインストールスクリプトが実行できました。

修正点1

of_10.0/libs/openFrameworksCompiled/project/makefileCommon/config.shared.mk

を開き79行目

else ifeq ($(PLATFORM_ARCH),armv7l)

else ifeq ($(PLATFORM_ARCH),aarch64)

に変更。

修正点2

of_10.0/libs/openFrameworksCompiled/project/linuxarmv7l/config.linuxarmv7l.default.mk

を開き41〜48行目付近

#PLATFORM_CFLAGS += -march=armv7

#PLATFORM_CFLAGS += -mtune=cortex-a8

#PLATFORM_CFLAGS += -mfpu=neon

#PLATFORM_CFLAGS += -mfloat-abi=hard

PLATFORM_CFLAGS += -fPIC

PLATFORM_CFLAGS += -ftree-vectorize

PLATFORM_CFLAGS += -Wno-psabi

PLATFORM_CFLAGS += -pipe

4行にコメント記号を入れ(上記#)、

さらに69〜71行目付近

#PLATFORM_PKG_CONFIG_LIBRARIES += glesv1_cm

#PLATFORM_PKG_CONFIG_LIBRARIES += glesv2

#PLATFORM_PKG_CONFIG_LIBRARIES += eg

3行にコメント記号を入れて保存。

修正点3

OF0.9.8まではapothecaryというライブラリインストーラがあったのですが、最新バージョンでは入ってないので、以前TX2用のOF0.9.8用にコンパイルしたkisstess2ライブラリを所定の場所にコピーします。pocoは0.10.0から標準addonになったようです。

一応以前のものをダウンロードできるようにしておきました。この中からOF10.0lib.zipを選択して下さい。

Takesan - Google ドライブ

解凍するとフォルダの中にlibkiss.a及びlibtess2.aが入っているので

libkiss.aは

of_10.0/libs/kiss/lib/linuxarmv7l

へ重ね書きし、

libtess2.aは

of_10.0/libs/tess2/lib/linuxarmv7l

へ重ね書きします。

最終スクリプトの実行

of_10.0/scripts/linux

へ行き

./compileOF.sh -j4

でOFのコンパイルが始まります。

今回はこれだけでOF0.10.0が使えるようになりました。

f:id:TAKEsan:20180827132942p:plain

       ZEDステレオカメラを接続してVideoGrabberのサンプルソースを実行中

 

 

 

 

 

FLIR ONE Proを分解したら、簡単にLEPTON3.5が取り出せる!!

YOLO学習済みデータをiPhoneで利用する方法は次に回して、今回は最新耳寄り情報です。

FLIR ONE Proって?

 iPhoneやAndroidに取り付けてスマホをサーモグラフィー化する商品で、昨年までの同名商品(FLIR ONE)は、赤外線センサーとして同社のLEPTON3が入っていました。

         f:id:TAKEsan:20180816104920p:plain

 このカメラは、WEBカメラも取り付けてあり、2つのカメラ画像を合成して相互の弱点を補うというものです。しかし、LEPTON3は160X120画素の横長、スマホに表示される画像は縦長です。画像の比率を考慮するとLEPTON3画像のほんの1部しか使っていないことになります。ある意味つまんないですね。

 私たち(渡辺、小野)の作ったThermal Cam3はWEBカメラ未搭載ですが、無線格安、しかもLEPTON3の画像をすべて使い切っています。

 また、この記事でも紹介していますが、以前のFLIR ONEは簡単に分解できることもわかっています。

 果たして新しく、価格が高くなったFLIR ONE Proは簡単に分解できるか?、そしてセンサーは何を使っているかが疑問でした。買うといっても個人ではなかなか........。

今回

 Maker Faire Tokyoで知り合った大澤さんがFLIR ONE Proを持っていると言うことで、早々に分解して送っていただいた写真がこれです。

f:id:TAKEsan:20180816111300j:plain  f:id:TAKEsan:20180816111311j:plain

f:id:TAKEsan:20180816111412j:plain

f:id:TAKEsan:20180816115325j:plain

 本体両側のネジカバーをマイナスドライバーのようなもので外し、ネジ2本を外します。ネジを外す工具は一般的なヘックスローブドライバT5サイズだそうです。面白いことに、以前の製品より構造が簡単になっていることが分かります。LEPTONセンサーはソケットにはまっているだけですから、この段階で簡単に外すことができますし、元に戻すことも以前よりさらに簡単です。

 以下渡辺さん情報。Andoroid版はGPDでも使えるそうです。(FLIR ONEアプリをネットからapk fileダウンロードして入れ替えるとのこと)

f:id:TAKEsan:20180816120247j:plain

f:id:TAKEsan:20180816115523j:plain f:id:TAKEsan:20180816115542j:plain

f:id:TAKEsan:20180816115600j:plain f:id:TAKEsan:20180816115624j:plain

中に入っていたのはLEPTON3.5!!

 いろいろ試していただいた結果、中に入っている赤外線センサーはLEPTON3.5である事がわかりました。この部品はDegiKeyで購入することができて価格は30,631円。

 FLIR ONE Proを持っていて、私たちのThermal Camに興味を持っている方なら、バラさない手はありませんぞ!!

LEPTON3と3.5の違い

 両者とも画素に変化は無く160X120ドットのままですが、出力されたデータから簡単にすべての画素の測定温度を計算できるところが大きく違います。今までのLEPTON3は温度を計算するために、i2cを使ってチップ温度を取得する必要がありました。しかも温度計算方法についてメーカーは非公開。

 LEPTON3.5は通常の使い方をする限りi2cが必要なくなります。i2cのライブラリや余計な計算が必要ないので、私たちの使っているメモリの少ないESP8266には断然有利になります。

 LEPTON3.5用のARDUINO IDEソースも上記記事でダウンロード可能です。

 

 

YOLOオリジナルデータの学習

今回は今年のMaker faire tokyoで使ったAIジャンケンのデータ作成方法を書くことにします。AIの専門家では無いので、固有名詞の間違いはご容赦願います。

         

       今回のデータを使ってジャンケンの手をリアルタイム認識させています。

 YOLOを使った画像認識が早いのは分かりました。ただし練習でおおーっと思った画像認識に使うデータは、他人が用意したものです。自分の必要なデータをどんな用途で使うかで価値が決まって来ますよね。

 用意する学習データは1クラス数千枚単位ですから、アマチュアではチョットって感じです。せっかく苦労して用意しても、使えなかったら何にもならないわけで、今回は「データー作成はそれほどでもなかった」的な記事です。メイカーフェア出展に向けて、サーモグラフィーを利用したジャンケン認識用画像の種類は3クラスとなりますが、これ以上のクラス数でも作成方法の基本は同じです。

 次回は学習済みデータをiPhoneへ移植するまでを取り上げますが、今回の学習済みデータはYOLOが動く環境なら問題なく動作することを確認しています。作成時疑問に思っていたことについても、併せて説明して行きます。

参考資料は1つだけ

 Yoloを使った学習方法の説明は、ネット上でいろいろ見つけることができますが、基本は How to train YOLOv2 to detect custom objects

のようです。疑問に思ったときのヒントは、この記事のどこかに書いてありますので、あまり日本語の記事に惑わされず熟読することが大切。今回は動画から必要画像を取り出して、ただひたすらにクラス分け作業を行う、という方法です。

必要機器

 Mac      : iMacでもMacBookでも何でもOK

 Ubuntuマシン  :必ずNVIDIAのGPUが付いているマシン(今回は1080 Ti 1個)

 iPhone    :  iPhone7以上 (認識に今回はiPhoneを使ったのでUbuntuマシン

         でもOK)

 ソフト    :特に購入ソフトは無し

1.動画を用意

 今回はジャンケンですから、iPhoneで録画したこんな感じの動画を用意します。

f:id:TAKEsan:20180815114234p:plain

 赤外線カメラ画像なのでグレースケールデータだけです。後で説明しますが、クラス分けが大変なので1クラスのみで、あらゆる方向から動画を撮影しました。今回はグー、チョキ、パー それぞれの動画ファイルを名前を変えて用意しています。

 YOLOは同一画像で複数のクラスを認識するので、最初は複数のクラスが写っている必要があるかと思いましたが、そんなことは関係ないようです。また、撮影画像のピクセル数はあまり問題にはなりませんでした。結果的に、720pや1080p、540pが混在しても認識への影響は感じられません。

2.MacのiMoveを使って編集

 iMoveを使いましたが動画編集ソフトなら何でもOKです。上の画像のままでは右の方に余計な部分が写っているので、トリムすることと、対象クラスが写っていない不必要な画像をある程度削除しておくことが目的です。(iMoveではトリムでは無くクロップという単語を使います)最終的に720p、MP4で保存しました。

f:id:TAKEsan:20180815115732p:plain

3.動画を複数のjpg画像に変換

 ここからはUbuntuマシンを使います。まず画像変換ソフトをインストール。動画から画像に変換できるソフトなら何でも良いのですが、ffmpegを使いました。ffmpegはMacでもWindowsでも使えますので、特にUbuntuマシンで無くてもOKです。インストール方法は他の記事を参考にして下さい。

 新しいフォルダを作って、その中にmp4ファイルをコピーします。そのフォルダで以下のコマンドを実行。

   ffmpeg -i input.mp4 -vcodec mjpeg -r 5 image_%03d.jpg

    input.mp4:入力動画ファイル名

    image_%03d.jpg:出力ファイル名 

 image001.jpeg.....と名称の付いたファイルがたくさん作成されますが、この例で「image」部分はクラス毎に名称を変更した方が、後からデータを追加するときに便利です。今回のデータは基本8fpsくらいで、iMoveを使って30fpsで保存しています。そのままでは同じアングルの画像がたくさんできてしまうので、1/6ぐらいに間引いて作成しています。なので作った動画に合わせて-r 5部分を変更します。

 コマンドを実行すると、フォルダ内に連番の付いた大量のjpegファイルが作成されます。今回の場合はクラスが3つなので3回実行。当然ですが連番前の名称を変えていれば、同一フォルダ内に作成してもOKです

4.2回目の間引き

 できた画像を確認して、不必要な画像を削除します。よく注意しながら目標のクラスが写っていない画像や、重複があるものはドンドン削除してしまいます。重複が多い場合は、すべて削除してffmpeg の-r以下の数値を減らして再実行した方が早いかもしれません。ここでの削除作業は後の作業効率や認識結果に関わってくるので、重要です。

5.YOLOをインストール

 以下に沿ってインストール。今回はiPhoneとの連携のためV2.0を使いましたが、最新のものでOKです。

Installing Darknet

 GPUを使わなければ意味がありませんのでmakefaileの中のGPU=1 を有効にすることと、OpenCVはあらかじめインストールしておいて OPENCV=1にしておくことも忘れずに!!。OpenCVをインストールしないと、動画系のテストプログラムが実行できません。Yoloはmakeにさほど時間がかかりません。Caffeとは雲泥の差です。

6.ラベリングする(アノテーション)

 Yoloは上記で作ったイメージファイルの他に、これらに対応したTXTファイルが必要です。(イメージファイルのどの部分に対応するクラス画像があるかを示すテキストファイルで、イメージファイルの枚数分必要です)ここら辺が一番単調で、手作業では時間のかかる部分となります。今回ラベリングソフトはlabelimgを使いました。以下インストール方法ですが、すでにpython3をインストールしている場合は3,4行目は必要ありません。

labelimgと言うフォルダができるので、この中に自分の好きな名称のフォルダを作り、先ほど作成したイメージデータを全部コピーします。最初は3つのフォルダが必要かなとも思いましたが、クラス毎にimgデータのファイル郡の名称を変えていればごちゃ混ぜにしてOK。

 次にlabelimg/data の中にあるpredefined_class.txtを修正します(これが一番手っ取り早い)。最初は20クラスぐらいあらかじめ書き込んでありますが、今回は3クラスだけなので、既に書き込んであるクラス名を全部消し、自分の好きな名称でクラス名を改行して書き込みます。今回はguu、tyoki、paaにしました。これは必ず修正が必要です。

labelimgフォルダの中でプログラムを実行します。

 python3 labelimg.py

以下のような画面が表示されるので、次のような設定を行います。

f:id:TAKEsan:20180815230111p:plain

 左側 OpenDir で先ほど作ったイメージデータが入っているディレクトリを指定

    Change Save Dir で同じディレクトリを選択。イメージもアノテーション

    ファイルも同じディレクトリに入れちゃいます。

    さらにSaveの下にある PscalVOC を選択して、必ずYOLOに変更します。

    これを忘れると、最初からやり直しになるので注意

 そして上部のメニューバーからView->Single Class Modeにチェックを入れます。

Single Class Modeとはクラス名が同一の場合、連続でデータを入力できるので、1つのクラスに対応したjpeg画像がここで生きることになります。但しSingle Class Modeにすると最初だけClass名選択をする必要があります。

 今回は連番以外の名称をクラス別に変えているので途中クラス選択の必要がありますが、その場合は一時的にSingle Class Modeを外して違うクラスを選択後、またSingle Class Modeにします。とにかく少ないデータで一度使ってみて、コツをつかんで下さい。操作は直感でできちゃいます。

 画像中のクラス画像選択はE、 選択した画面を保存して次の画面に移る場合はWキーを押します。

 E-->マウスで対角指示-->W-->E-->マウスで対角指示-->W と連続してクラス指定が可能で、慣れると1枚の画像のアノテーション所要時間は2秒程度。上手く行けば1時間で1500枚以上のクラス分け(アノテーション)が可能です。但ししばらく作業をしていると、キーボードを操作している左手がしびれてしまいますのでご注意を!!。

 ここで1枚の画像に複数のクラス画像が入っている場合、いちいちクラス名を指定しなければ無いのでグンと効率が落ちます。

ってことをマスターしてしまえば、基本データ作りは一応完成です。ここで作ったデータはtiny_Yoloでも標準Yoloでも使用できます。

 Yoloのアノテーションのファイルは以下のようになっています。内容が違っている場合や、クラス番号が正常で無い場合はlabelimgの設定を疑って下さい。

f:id:TAKEsan:20180816102939p:plain

最初の数値がクラス番号で、今回は0~2の3種類。この場合は画像に存在するクラスがTyoki=1で1個のみ。その次の4つの数値はTyokiの範囲を示します(yoloは比率で表すようです)

f:id:TAKEsan:20180816103351p:plain

       この場合は1つの画像にGuu=0とPaa=2が存在していることを示します。

7. またまたダメ押しのチェック

 これで終了とも思えるのですが、必ず間違いがあるので、もう一度ダメ押しのチェックを行います。イメージとアノテションファイルをごちゃ混ぜにした成果がここに出ます。以下のように同一名のjpgとtxtファイルができますが、たまにjpgファイルに対応しているtxtファイルが作られていない場合があるので、それを見つけ出してダブっているjpgファイルを消してしまいます。例えば普通は以下のようにjpgとtxtが交互に並びますが、txtファイルが作成されていないと、jpgファイルが続くことになります。

f:id:TAKEsan:20180816002346p:plain

8.yoloの下準備

 Darknetをインストールするとdarknetディレクトリができます。

darknet/data の中に先ほど作ったjpgとtxtの入ったごちゃ混ぜデータをディレクトリごと移動またはコピー。

 その中にprocess.pyの名称で、以下の内容のファイルを作成

import glob, os

# Current directory
current_dir = os.path.dirname(os.path.abspath(__file__))

# Directory where the data will reside, relative to 'darknet.exe'
path_data = 'data/obj/'

# Percentage of images to be used for the test set
percentage_test = 10;

# Create and/or truncate train.txt and test.txt
file_train = open('train.txt', 'w')  
file_test = open('test.txt', 'w')

# Populate train.txt and test.txt
counter = 1  
index_test = round(100 / percentage_test)  
for pathAndFilename in glob.iglob(os.path.join(current_dir, "*.jpg")):  
    title, ext = os.path.splitext(os.path.basename(pathAndFilename))

    if counter == index_test:
        counter = 1
        file_test.write(path_data + title + '.jpg' + "\n")
    else:
        file_train.write(path_data + title + '.jpg' + "\n")
        counter = counter + 1

これは

How to train YOLOv2 to detect custom objects

に掲載されてます。何をするのかというと、ディレクトリの中のデータを教師ファイルと学習用ファイルに分けてそれぞれリストファイルを作ります(train.txtとtest.txt)標準では教師ファイルは全体の10%ですが、これを変える場合はpercentage_test = 10 のところを15とか30とかにします。この数字の変更はかなりシビアで、最終的にできた学習済みファイルの結果を試して最適値を探します。最終的にと簡単には言いますがGTX1080 Tiで学習させても数時間必要ですので、容易ではありません。今回の場合30%で一番良い結果が得られました。実行方法は、

   python process.py

 実行環境はPython2である事に注意です。画像が不足していると感じた場合は、追加画像群を他の場所でアノテーションして、すべてこの場所に放り込み、再度python process.pyを実行するだけです(その場合は画像名称を変えることを忘れずに!!)。

9.cfgファイルを変更

 tinyYOLO標準YOLOでは変更内容が違うことに注意して下さい。変更ファイルは、darknet/cfgの中に入っています。

tinyYOLOの場合(今回のiPhoneを使う場合)  

  tiny-yolo-voc.cfgを変更します

   2行目 batchを64に変更(初めから書いてあったと思う)

   3行目 subdivisions=8に変更(これも初めから書いてあったと思う)

  120行目 classes=20を3に変更 (クラスの数です)

  114行目 filters=512 を 40に変更 (class+1)*5の計算値 (3+1)*5=40

                クラスの数が変わればfiltersの数値も変わることに注意!!

標準yoloの場合

    How to train YOLOv2 to detect custom objects

  に沿って、yolo-voc.cfg内容を変更します

10.あらかじめトレーニングされたデータをダウンロード

 一応 darknet/ 内に必要ファイルをダウンロードします。このファイルは学習を収束させるために必要なファイルだそうです。  

YOLO V2とV3とではデータが違います。

  YOLO V2.0の場合は

     downloaded

    darknet19_448.conv.23がダウンロードされます。

  YOLO V3.0の場合は

    wget https://pjreddie.com/media/files/darknet53.conv.74

    darknet53.conv.74がダウンロードされます。

11.さらに2つのファイルを作ります

  darknet/cfgの中にobj.namesファイルを作成

  obj.names :先ほどのpredefined_class.txtと内容が同じファイル。

        クラス名を改行しながら書きます。今回はGoo、Tyoki、Paa

f:id:TAKEsan:20180815230202p:plain

  obj.data    :必要ファイルのリンクを書き込んだファイル。以下のような感じ。

      class   必ず指定。今回の場合3

      train ディレクトリとファイル名を指定 先ほどのtrain.txt

      valid ディレクトリとファイル名を指定 先ほどのtest.txt

      names   クラスファイルの場所とファイル名 obj.names

      backup  学習済みデータの保存先 このままでOK

f:id:TAKEsan:20180815230221p:plain

12.いよいよ学習

darknet/  ディレクトリ内で以下を実行。今までの作業はこのコマンドを実行させるために必要なことだったと言うことですね。

 tiny Yoloでyolo v2.0の場合

./darknet detector train cfg/obj.data cfg/tiny-yolo-voc.cfg darknet19_448.conv.23

 

 標準YoloでYolo v3.0の場合は

./darknet detector train cfg/obj.data cfg/yolo-voc.cfg darknet53.conv.74

となります。

 今までのリンク先などの設定で、データの置き場所などが変更可能だと言うことが分かると思います。ある程度慣れてきたら自分の環境に合わせて変更してしまえば、もっと使い安くなります。

13.すんなり行けば良いのですが

 ここまでの過程が複雑でデータ量が多いことから、普通は簡単には動いてくれません!!

 実行してから、まず最初の1〜2分の段階でjpegに対応したtxtファイルがありませんのようなエラーメッセージが出たら、アノテーションが上手くいってません。上記7.をもう一度確認してjpegファイルがダブってないかチェック後、必ず 

python proxess.pyを再実行。同様のエラーが無くなるまで同じことを繰り返します。上手くいくと以下のような画像になります。

f:id:TAKEsan:20180815230846p:plain

 この場合はtiny-yolo-voc.cfgを使ってsubdivisions=8にした場合で、これを40,000回繰り返し(tiny-yolo-voc.cfgの15行目 max_batchの最後の数値を40,000にした)、100回毎にでデータがdarknet/dataの中に自動保存されます。つまりこの例では400回上書き保存されます。  

 subdivisionsの値を少なくすると計算がメモリー上に展開されるようで、全体のスピードが多少速くなりますが、GPUメモリーが不足してエラーになる可能性があります。

 上の画像のように、8回毎に平均値が出ます。avgの手前の数値が0に近づくほど良好とのこと。今回のデータでは1.455029になっていますが、これ以上続けてもほとんど変わらないことと、次で説明する認識テストもほぼ良好なので。ここで打ち切っています。

 ただし標準Yoloでの学習は確実にゼロに近づきます。また白黒で学習させているのにカラー画像でも認識するのには驚いてしまいました。Tiny Yoloではそうはいきません。

 このほか、Classがゼロだったり他の数値が表示されていない場合は、クラス分けやクラスの数の指定が各段階で上手くいっていない可能性があります。再度確認となりますが、「6.クラス分けをする」だけは慎重に作業する必要があります。ここで設定を間違うとアノテーションを最初からやり直ししなければなりません。

 今回約4,500枚のデータを使い4万回の繰り返しで、大体6時間(GTX 1080 Ti)ぐらい必要でした。学習時間はGPU性能に依存します。

14.学習結果の確認

 学習結果は、darknet/backupに保存されます。tiny-yolo-voc.backup又はyolo-voc.backupがそのデータで、

./darknet detector test cfg/obj.data cfg/yolo-voc.cfg backup/tiny-yolo-voc.backup test.jpg

(標準学習の場合はtiny-を消します)

と打ち込み認識したいサンプル写真を指定(test.jpg)すると現在の学習状況が確認できます。満足できる認識内容なら、どの段階でもCtrl+Cで打ち切り可能。その場合は.backupが学習済みデータになります。その他に各段階でデータが作成されていますので、それらを利用することも可能です。

 学習実行内容をよく見ていると、数値にかなり波があるので、avgの手前の数値が0に近付いたとしても、少なくとも1万回以上は繰り返さないと満足な結果は得られないようです。 ここら辺はデータ量や質によりなんとも言えないので、ヒーター付き集塵機(GPUの付いたUbuntuマシンを私はこう呼びます。夏場はさらに冷却用の扇風機が必要...)の電気料金が許す限り自分で試して見るしかありません。

f:id:TAKEsan:20180815235143p:plain

以上の作業は慣れるとスイスイなのですが、伝わったかなー、伝わんねーだろーなー。

 2ヶ月前の作業を思い出しながら書いたので、結構疲れた....。

 

                             では、また。

 

今年もMaker Faire Tokyo 2018に出ます!!

 今年もメイカーフェア東京(Maker Faire Tokyo 2018)に出展することになりました。

    This year we will also exhibit at Maker Faire Tokyo (Maker Faire Tokyo 2018).

f:id:TAKEsan:20180704201130j:plain

 今まで、格安WIFI付きプロセッサ(ESP8266)とFLIR LEPTON赤外線センサーで、どれだけ本格的・実用的なiPhoneアプリが作れるかどうか追求してきました。

  Until now, We have been trying more practical iPhone apps with cheap WIFI core (ESP 8266) and a FLIR LEPTON infrared sensor.

f:id:TAKEsan:20180705100857p:plain

 昨年に引き続き今年も赤外線カメラ(FLIR LEPTON1,3,3.5)を使います。もちろん小型ドローンへの搭載も着々とバージョンアップが進んでいます。

 今年は大きく分けて3つの内容になります。今までは、開発時間に追われてブログ更新をしてませんでしたが、公開できる面白い材料がずいぶんそろってきましたので、頑張って今後紹介して行きたいと思ってます。

  We are still using FLIR LEPTON 1, 3, 3.5 this year as well. Of course small drone test has steadily been upgraded.

  This year we expanded three main items. Until now, we are too busy to update our blogs, but a lot of awesome idea we will introduce you, so we will do our best and we want to introduce it in the future.

今年はメンバーが3人になりました    This year three members have become

 東北と関西の共同作品です。こんな感じのロゴにしました。WT&Dに名称変更。

  It is a collaboration work between Miyagi, Hyogo and Kyoto. We made it as a logo like this. Changed name into WT & D this time.

              f:id:TAKEsan:20180705101320p:plain

 

1.小型ドローンへのLEPTON搭載?    LEPTON installed in a small drone?

 確実に進化しています。成果のお話は会場で!!

 It evolves reliably. Talk about achievements at the venue! !

f:id:TAKEsan:20180705102508p:plain          えっドビー軽量化?       weight reduction?

2.小型サーモグラフィ画像2個で立体表示可能か?   Can 3D display be possible with two small thermographic images?

 前回の記事で最後の方に動画を付けましたが、こんな感じです。

  We attached a movie in the last article. it is like this.

           www.youtube.com

 ステレオメガネやスマホゴーグルで立体画像が確認できます。サーモグラフィー画像2画面同時表示、しかもWIFIでリアルタイムってのはありそうで無かった未知の領域です。これはコンピューターで遠近を認識できることを意味しますが、この動画のDepth画像や3Dメッシュ画像で確実に距離を認識していることが分かると思います。

  You can check stereoscopic images with stereo glasses or smartphone goggles. It is an unknown area which was not likely to be real-time with WIFI simultaneous display of thermographic picture 2 screens at the same time. This means that you can recognize the perspective in the computer, but you can see that the distance is definitely recognized by Depth image and 3D mesh image of this movie.

f:id:TAKEsan:20180705104206p:plain

3.小型サーモグラフィ画像で画像認識は可能か?    Can image recognition be possible with a small thermographic image?

 画素の少ないサーモグラフィで、ジャンケンの手の形がどれだけ正確に認識できるかどうかトライしてみました。初めはLEPTON3.5で作ったデータで学習させた結果をLEPTON3.5で認識させていましたが、試しに画素の荒いLEPTON1(たった80x60画素)で認識させたところ、まともに動くことが分かりました。会場ではWIFIの混線が予想されるので、妨害電波に強いLEPTON1系のアプリを使う予定です。日本国内でもこのセンサーをお持ちの方が多いと思いますので、今後ブログ上で学習データの作成方法やソースを公開して行こうと思っています。

 今回のソフトは、熱を発する人間の手のひらだけを画像認識できます。一種の温度フィルターですね。これができたってことは応用が無限に広がります。それもTX2じゃなくてiPhoneで!!(画像はiPhone7 plusです)どう思います?

 With a thermography with few pixels, I tried to see how accurately the hand shape of Rock-paper-scissors could be recognized. Initially we was letting LEPTON 3.5 recognize the result of learning with data created with LEPTON 3.5, but when I tried to recognize it with a rough LEPTON 1 (only 80 × 60 pixels), we found it to work properly It was. At the venue, it seems that WIFI 's crosstalk is expected, so we plan to use LEPTON 1 series applications that are stronger against jamming waves. We think that there are many people who have this sensor even in Japan, so I'm thinking about going to introduce how to create learning data and sources on our blog in the future.
 The software of this time can recognize only the palm of the human's fingers image. Is it a kind of temperature filter? The fact that this can be done spreads the application infinitely. It's not TX 2 but on the iPhone! ! (The image is iPhone 7 plus) What do you think?

    

  f:id:TAKEsan:20180705105004p:plain

 そして、応用。2種類のジャンケン画像を読み取ってf:id:TAKEsan:20180524102209j:plain (Juneチャン)が、歌います(簡単な手話の解読)。高齢者の脳トレに最適!!。

 And application. two kinds of Rock-paper-scissors images (June Chan), but my dog sings (easy decoding of sign language). Ideal for the brain train of elderly people! ! .

    

今回のアプリは、    This time,

  すべてアプリ登録しているThermal Cam3、1を利用して作りましたが、マルチスレッド化しているので申請条件に合わないため、アプリストアから配布ができません。ただしテストフライトという形なら配布が可能ですので、希望する方はコメントして下さい。

 I made it using Thermal Cam 3 & 1 which all the applications are registered, but because it is multi-threaded, it can not be distributed from the apps store because it does not meet the apple application requirements. However, since distribution is possible in the form of Test Flight, please comment if you wish.

      f:id:TAKEsan:20180704191549j:plain

Thermal Cam、Thermal Cam3のインストール方法は、       How to install Thermal Cam, Thermal Cam 3,

 この記事をご覧下さい。性能を上げるため来月中を目標にバージョンアップする予定です。
 Please see this article. We plan to upgrade to the target next month to improve performance.

takesan.hatenablog.com

 

 

 

 

 

 

ジュンちゃん手術をする!!

 我が家のアイドルトイプードルのJUNEですが、1才にも満たない頃フローリングですってんころりん。右後ろ足の膝のお皿が外れ安くなりました。グルコサミンを飲ませたりしてだましだまし散歩を続けましたが、今年獣医さんに連れて行ったら、外れた膝のお皿がずれたままくっついてしまったとか....。膝蓋骨脱臼のグレード4だそうです。道理で散歩の途中で座り込んでしまうことが多くなったわけだ。

 このままでは左足もおかしくなってしまうと言うことで即手術命令!!。最悪歩けなくなるかもしれないと思い。いくらか歩けているうちに毎日少しずつお散歩をさせ(今から思えば考えすぎでした)、

f:id:TAKEsan:20180524143650j:plain

 我が家から車で2.5時間。盛岡の岩手大学動物病院を紹介してもらって連れて行くことに..。

 前日は心配して友人から送ってもらったお守りを付けて、夕ご飯以降絶食絶水。僕の作ったご飯しか食べないというような悪いしつけをしたので、冷凍にして持参。ついでに事前にトリミングして、狂犬病やワクチンの注射をしてから手術に挑ませることにしました。

f:id:TAKEsan:20180524102209j:plain

岩手山がとても素晴らしかった!!

f:id:TAKEsan:20180524102350j:plain

後ろ姿が泣ける。

f:id:TAKEsan:20180524102430j:plain

 手術内容は、右膝の皮膚をタテに5cmくらい切って、お皿がずれないように足膝部分の骨を削る。横にくっついてしまった膝のお皿を外し、所定の部分まで引っ張ってピンで固定。なんていう飼い主としては身の毛もよだつような内容。

 5/8入院、5/9夕方手術、5/10病院で安静、5/11退院という強行スケジュールでした。5/9の手術後、先生から無事終了の連絡が来て一安心して見たものの、こんなに早く退院して良いのと思いながら迎えに行きました。

 うちのワンコは病院が大嫌いなのですが、岩手大学動物病院では先生を初め皆さんに優しくしていただいたようで、別れ際に先生へお礼(ペロペロ)をしてました。でも帰ってきたときは、こんな痛々しい姿に....。 飼い主としては不安です。

f:id:TAKEsan:20180524103914j:plain

  家の中では飛び跳ねないようにケージ入り命令が出たのですが、なにせしつけが悪く野放し状態で育てたので、ケージに入る訳もなく、

f:id:TAKEsan:20180524103308j:plain

 入れると暴れるだけなので、かえって悪くなると思って、部屋を小さく仕切り様子を見ることにしました。寝るときも一緒でないと本人は気が済まないので、ベッドから飛び降りないようリードを付けて一緒にご就寝することに..。

 1週間目でこちらのお医者さんに行って包帯を取っ替えて、2週間目で再びこちらのお医者さんで抜糸。

f:id:TAKEsan:20180524105221j:plain

 平気で歩いてます。まだ、かさぶたを噛む可能性があるので、エリザベスカラーを付けたままです。術後1ヶ月でCTを撮りに又岩手大学へ行くことになりますが、飛び跳ねないような環境を作れば、なんとか大丈夫そうです。やれやれ。

 

iPhone とOFとOpenCV3.4でcontribが実行できないのか?

ご存じの通り

 OpenCVのiOS版にはcontribが付いていません!!。このライブラリは面白そうなものがたくさんあって、どうしても実行したくなるわけです。でも、iPhoneのカメラを使うだけでもテクニックが必要なSwiftやオブジェクティブCから利用するんじゃなかなか難しいのが私の課題。OF(めんどくさいから今後Openframeworksの略)だったら全然問題ないところから、発想が展開していくことになります。

 まず、iOS用の最新OpenCVが存在するって事を知りませんでした。XcodeでのiOS開発はちまたで言うところのクロスコンパイルなんですね。iPhoneじゃ開発能力不足だから母艦iMacでコンパイルしてバイナルファイルをiPhoneに転送するって発想です。これが大きな障害になるポイント。はたして無事インストールできて、OFで使えるのか?でした。

f:id:TAKEsan:20180417212245j:plain

今回はLEPTON3の立体画像をiPhoneで楽しめる上にOpenCVで距離深度を確認、そしてメッシュ変換までです。こんなことやってる方はいないと思うので結構ワクワクでした。なんつったって無線がキクー!!

で、OpenCV for iOSをインストールして見ると

 終わってみるとほんとに簡単でした。標準インストールするだけです。以下はMacでの場合だけなのであしからず。まず標準OpenCV3.4.1のソースコードを

GitHub - opencv/opencv: Open Source Computer Vision Library

そしてこっちのiOS版3.4.1 contribのソースコードを

Releases · opencv/opencv_contrib · GitHub

つまりiOS版の同じバージョンのソースコードをダウンロードします。

 この2つのファイルをダウンロードして解凍した後、自分のMacの作業フォルダにコピーします。まずは、OpenCV iOS版のコンパイルから。これはOpenCV iOS版の標準インストールドキュメント通りです。

  cd /

  sudo ln -s /Applications/Xcode.app/Contents/Developer Developer

  cd ~/<my_working_directory>

  python opencv/platforms/ios/build_framework.py ios

 iOS版の特定ソースはなくて、OpenCV標準ソースファイルでインストールできます。

インストールに使用するpython は2.7.12で、brewCmakeなど私の環境ではインストール済み。つまずいた場合は、自分でなんとかして下さい。コンパイルは私のiMacで30分以上必要でした。

 結果的に自分の作業フォルダにiosってディレクトリができるので、フォルダの中に以下のようにopencv2.frameworkってディレクトリができれば一応完成です。

f:id:TAKEsan:20180319204754p:plain

OFで普通に使えるようにするには

OFは0.9.8です。うまくいけば2ステップで完了。

 まずこんな感じで作ろうとしてプロジェクトに、ビルドしたopencv2.frameworkを追加します。さっきどこにopencv2.frameworkを作ったかを忘れずに!!

f:id:TAKEsan:20180319210148p:plain

で、ofxiOS_Prefix.pch にopencv.hppをインクルード文他を追加します。使いやすいようにこの段階でnamespaceを追加します。#import <Foundation/Foundation>の前に挿入することが重要だったような...。

f:id:TAKEsan:20180319210207p:plain

 試しにこのままビルドしてみてエラーがなければ成功ですが、もしエラーが出ればダメ押しで、以下のようにHeader Search Pathsにopencv2.frameworkの存在する場所を指定してみます。大概この段階で実行可能環境ができてしまいます。

f:id:TAKEsan:20180319210223p:plain

 ビルドエラー無しでここまでできれば、問題はofImageとMatとの変換だけになります。OpenCVとOpenFrameworks間のデータで問題になるのはimgeとMatの相互変換だけで、例えばL_image っていうofImageをOpenCVのimgRっていうMatに変換する場合は、

  cv::Mat imgR = cv::Mat(L_img1.getHeight(),L_img1.getWidth(), CV_8UC3, L_img1.getPixels().getData());

 Matを使ってOpenCVで画像処理を加えた後、ここではtakeっていうofImageに変換すればすぐDrawできちゃいます。

 

   take.setFromPixels( imgR.ptr(),  imgR.cols,  imgR.rows, OF_IMAGE_COLOR, false);

 両者にはRGB BGR変換とかいろいろ中間処理の必要な場合がありますが、基本ポインタ+αなので、実行時は高速変換できてしまいます。(forの二重ループを使うよりはです)

 キーポイントはCV_8UC3 OF_IMAGE_COLORでした。内容は私が説明するより先人がたくさん書いていますので、そちらを参考にして下さい。

じゃーofxOpencvやofxCVはどうなるんだろー

 はっきり言って必要性は感じない。データの変換作業だけが一見やっかいなだけでこつを飲み込めばこっちの物です。なんつったってこっちは最新のOpenCVでーす。

今回の目玉contribはどのようにして実行できるようになるのか?

 肝心のcontrib導入方法です。またまた時間がかかっちゃいますが、今までの処理が無事終わっていれば、再コンパイルするだけで済みます。

 バージョンを合わせたmoduilesの必要なcontribのモジュールフォルダをopencvフォルダにコピーして再度コンパイルし直すだけ!!。私の場合ximgprocが必要だったのでximgprocフォルダをコピーして、OpenCVを再コンパイルするだけでした。少し前はインストールがかなりめんどくさかったようですが、今はぜーんぜん。

f:id:TAKEsan:20180417203036p:plain

                           contribのなかのmoduilesフォルダの中の各ライブラリフォルダを......

f:id:TAKEsan:20180417203006p:plain

                              OpenCVのなかのmoduilesにコピーして再コンパイルするだけ!!

じゃー何ができるの? 

  iOSの場合、C++の方がSwiftより実行スピードが速いって事が経験的に分かってたのですが、OF+Opencv+contribで去年の今頃は、こんなのできるとは思ってませんでした。

              www.youtube.com

今までの集大成です。Swiftなし。OFだけです。Appleのアプリ審査が通れば皆さん簡単に実行できると思うんですが、無料で申請すれば簡単に通ったりして......。

 

 

                           では、また。