編集履歴一覧に戻る
CDH29のアイコン画像

CDH29 が 2022年09月24日23時30分34秒 に編集

コメント無し

本文の変更

# 概要 自宅庭に野良猫がしばしば訪れます。 その生態を捉えるため、猫を認識したら撮影するシステムを構築しようと思い立ちました。 Spresenseで監視 ↓ AIで猫を認識し ↓ その画像を記録し ↓ SDcardに保存する 私はお気軽に趣味でarduinoを用いた電子工作をする程度の知識しか持ち合わせておらず、 AIに興味を持ちながらもpythonの敷居を高く感じておりました。 NNCであればGUIで初心者でも何とかなるのではないかと思い、今回のコンテストを機会に挑戦してみることにしました。 # 部品

+

1.

- spresens メインボード - spresens 拡張ボード - spresens カメラボード - Transend 1GB micro SD

+

2. - モバイルUSBバッテリー - タッパー

![キャプションを入力できます](https://camo.elchika.com/307610308d45747217a3e1f04eb822e5a75b9dbc/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f36343266336361302d643861392d343535392d396339372d353539333034623838663862/) # NNCをはじめる 「sony NNC」で検索すると公式チュートリアルなど出てくるので概要をつかむことができましたが、 AIについての基礎を何も持ち合わせていないので、それだけでは不十分でした。 参考図書 工学社 [はじめての「SonyNNC」改訂版](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E3%80%8CSonyNNC%E3%80%8D%E6%94%B9%E8%A8%82%E7%89%88-I-BOOKS-%E6%9F%B4%E7%94%B0-%E8%89%AF%E4%B8%80/dp/4777521397/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3NM418DQ26X9O&keywords=%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AENNC&qid=1663743277&sprefix=%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AEnnc%2Caps%2C210&sr=8-1) 柴田良一 著 これは、丁寧に練習問題を行いながらNNCの理解を深めることができ 大変参考になりました。 # NNCで猫を認識したい 参考図書の実例では NNCのサンプルプロジェクトにある、 2層Neural Networkで構成された「01_logistic_regression」で画像認識を行うよりも、多層NNのうち、畳み込みNN(CNN)で構成された「02_binary_cnn」の方が認識率が高くなることが分かりました。 今回は後者のサンプルプロジェクトを基にNNCを構成してみることにしました。 1. 画像検索で「猫」の写真を370枚集めました。対象として「犬」の画像も370枚集めた

-

1. それをもとにデータセットを作成「02_binary_cnn」から新規project作成

+

1. それをもとに、白黒・28x28サイズにしてデータセットを作成 1. 「02_binary_cnn」から新規project作成

![キャプションを入力できます](https://camo.elchika.com/d83e738e9935f5f539538c795ec2c08c500d9b57/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f62636235373733662d376634622d343730352d613161322d303666653765393335663232/) 1. しかし accuracy0.48 に留まったため対象画像を「犬」から「人間」に変更。同じく370枚とした。

-

1. 新たにデータセットを作成し直しやり直したところ、accuracy 0.9047 と好成績だった

+

1. 新たにデータセットを作成し直しやり直したところ、accuracy 0.9047 と好成績だった(と思う)

![キャプションを入力できます](https://camo.elchika.com/6e5f4e006e7060d79fa124fab96c4663c0d78c4d/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f36323232306535392d313236362d343065362d613834332d393565376134306237393165/) ![キャプションを入力できます](https://camo.elchika.com/16683e91c3f568ac4fd3742a82d466697cd6ceb4/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f36643535386533652d393363652d346662332d626661622d353732383762383464383932/)

-

1. 試しにCNNではなく2層NNで同様のデータセットを用いて検討したところ accuracy0.7333 だった 1. さらに上記④のプロジェクト「構造自動探索」を行って成績向上をめざした

+

1. 試しにCNNではなく2層NNで同様のデータセットを用いて検討した accuracy0.7333 だったため却下 1. さらに上記④のプロジェクト(猫と人間学習)で「構造自動探索」を行って成績向上をめざした

1.10件ほど検討したが成績は向上せず時間もかかるのでそれ以上は行わなかった

-

1. プロジェクトを右クリック→エクスポート→NNBを選択→できた[model.nnb]をFAT32でフォーマットしておいたmicroSDの直下に保存した

+

1. プロジェクトを右クリック→エクスポート→NNBを選択→[model.nnb]をFAT32でフォーマットしておいたmicroSDの直下に保存した

-

これで、windows版CNNでは画像認識はうまく構成されたと思います。

+

windows版CNNでは画像認識はうまく構成されたと思います。

-

# しかしArduinoIDEでスケッチが組めない 残念ながらこれは私の技術不足が原因でしかありません。

+

# スケッチ

+

参考図書 オライリー・ジャパン [SPRESENSEではじめるローパワーエッジAI](https://www.amazon.co.jp/SPRESENSE%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%AD%E3%83%BC%E3%83%91%E3%83%AF%E3%83%BC%E3%82%A8%E3%83%83%E3%82%B8AI-Make-PROJECTS-%E3%82%BD%E3%83%8B%E3%83%BC%E3%82%BB%E3%83%9F%E3%82%B3%E3%83%B3%E3%83%80%E3%82%AF%E3%82%BF%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BA%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4873119677/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3H6KCDZVNX9MN&keywords=SPRESENSE%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%AD%E3%83%BC%E3%83%91%E3%83%AF%E3%83%BC%E3%82%A8%E3%83%83%E3%82%B8AI&qid=1664028683&sprefix=spresense%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%AD%E3%83%BC%E3%83%91%E3%83%AF%E3%83%BC%E3%82%A8%E3%83%83%E3%82%B8ai%2Caps%2C185&sr=8-1) 太田 義則  著

-

arduino IDEに用意されている「camera」のサンプルスケッチをspresenseに書き込むと SDカードに写真が記録され、動作を確認することができました。

+

``` c:NCCで認識し撮影する diff_c #include <Camera.h> #include <DNNRT.h> #include <SDHCI.h> #include <stdio.h>

-

しかしこのスケッチと「number_recognition」を組み合わせて 撮影した画像から、猫を認識し、その画像をSDcardに保存する という動作まで組み上げることができません。

+

#define BAUDRATE (115200) #define TOTAL_PICTURE_COUNT (20)

-

いつ来るのかわからない野良猫の撮影は難しいので、モニターに猫の写真を表示してSpresenseのカメラを向けても 撮影も記録もされている様子はありませんでした。

+

SDClass theSD; DNNRT dnnrt;

-

web検索すると成功例が報告されており それを参考に試行錯誤してみたのですが うまくいきませんでした。

+

const int DNN_width = 28; const int DNN_height = 28; const float threshold = 0.65;

-

# 考察 引き続きspresenseの学習を継続し 完成できるよう励んでまいります

+

boolean save_flag = false; int take_picture_count = 0; DNNVariable input(DNN_width * DNN_height);

-

参考書の買い足しをして解決を図ります。 また、今後も数多くのspresenseの作例が投稿されるでしょうから 皆様から学んでいきたいと思います。

+

void printError(enum CamErr err)  // カメラ エラーコード { Serial.print("Error: "); switch (err) { case CAM_ERR_NO_MEMORY: Serial.println("No memory"); break;

+

default: break; } }

+

void CamCB(CamImage img) { if (!img.isAvailable()) return; // カメラ画像の切り抜きと縮小 CamImage small_image; CamErr err = img.clipAndResizeImageByHW(small_image, 48, 8, 271, 231, DNN_width, DNN_height);

+

// 縮小に失敗したらリターン if (!small_image.isAvailable()) return;

+

// 認識用モノクロ画像を設定 uint16_t* Imgbuf = (uint16_t*)small_image.getImgBuff(); float *dnnbuf = input.data(); for (int n = 0; n < DNN_height*DNN_width; ++n) { dnnbuf[n] = (float)(((Imgbuf[n] & 0xf000) >> 8) | ((Imgbuf[n] & 0x00f0) >> 4))/255.0; }

+

// 推論結果 dnnrt.inputVariable(input, 0); dnnrt.forward(); DNNVariable output = dnnrt.outputVariable(0);

+

if((output[0] > threshold)) { save_flag = true; Serial.println("DNNRT recognized the picture as a cat."); } else { Serial.println("dnnrt couldn't recognize."); } }

+

void setup() { CamErr err; Serial.begin(BAUDRATE); while (!Serial) { ; } // SDカードにある学習済モデルの読み込み File nnbfile = theSD.open("model.nnb"); if (!nnbfile) { Serial.print("nnb not found"); return; } // 学習済モデルでDNNRTを開始 int ret = dnnrt.begin(nnbfile); if (ret < 0) { Serial.print("Runtime initialization failure. "); Serial.print(ret); Serial.println(); return; }

+

Serial.println("Prepare camera"); err = theCamera.begin(); if (err != CAM_ERR_SUCCESS) { printError(err); } Serial.println("Prepare camera"); theCamera.begin();

+

Serial.println("Start streaming"); theCamera.startStreaming(true, CamCB);

+

Serial.println("Set Auto white balance parameter"); theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);

+

Serial.println("Set still picture format"); err = theCamera.setStillPictureImageFormat( CAM_IMGSIZE_QUADVGA_H, CAM_IMGSIZE_QUADVGA_V, CAM_IMAGE_PIX_FMT_JPG);

+

if (err != CAM_ERR_SUCCESS) { printError(err); } pinMode(LED0, OUTPUT); // LED準備 }

+

void loop() { sleep(1); if (take_picture_count < TOTAL_PICTURE_COUNT) { Serial.println("call takePicture()"); CamImage img = theCamera.takePicture();

+

if(save_flag) { if (img.isAvailable()) { char filename[16] = {0}; sprintf(filename, "CAT%03d.JPG", take_picture_count);

+

Serial.print("Save taken picture as "); Serial.print(filename); Serial.println("");

+

theSD.remove(filename); File myFile = theSD.open(filename, FILE_WRITE); myFile.write(img.getImgBuff(), img.getImgSize()); myFile.close();

+

// 撮影をLEDでも 視認できるようにする digitalWrite(LED0, HIGH); delay(1000); digitalWrite(LED0, LOW); delay(10); } else { Serial.println("Failed to take picture"); } take_picture_count++; } save_flag = false; } else { Serial.println("END."); dnnrt.end(); theCamera.end(); } }

+

``` しかし猫の画像をカメラ前においても撮影することができずうまくいきませんでした。 これが結構 ハマってしまいました。 色々変数を変えたりnnbファイルを作り直したりして原因を探りました。 はじめはCamErrを記述していませんでしたので上記スケッチのように加えたところ ”No Memory"を返しているために撮影できないことがわかりました サンプルスケッチ[camera]の記述を利用していましたが、 setStillPictureImageFormatを CAM_IMGSIZE_QVGA_H, CAM_IMGSIZE_QVGA_V, CAM_IMAGE_PIX_FMT_JPG); に修正したところ無事撮影することができました。 PCモニターに猫の写真を表示するとそれを認識して撮影します。 シリアルモニタでも確認できますが、LED点灯でも確認できるようにしました。 ## 撮影サンプル モニターに映し出した猫を撮影しました ![画面の猫を撮影](https://camo.elchika.com/5d64e39c041b0d37b7d83881b95b64f687b909ae/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f32303438643161652d616163642d343366642d613934372d643935346664663665336262/) ![画面の猫を撮影](https://camo.elchika.com/42e1db757225290ad3db3316ead51901ac9cf85e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f63323563623666612d626336632d343461382d623166352d366431613663383462303237/) 犬 の写真や、猫のぬいぐるみでは撮影してくれなかったので うまく認識しているようです。 ## ケース 100均で購入したタッパーにカメラを出す穴を開けて モバイルバッテリーと接続したSpresenseを入れることにしました ![100均タッパー](https://camo.elchika.com/bf3b7d8f2f178f2e1db17f571683afd2017ddb7e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f35383334633830352d623062332d346235312d616232382d313731346163313835326163/) ![カメラの穴を開けた](https://camo.elchika.com/b967b0ece6ac10163f334d486079364b8dc369e3/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f39633062613234302d326237342d343838322d616331392d313964366239616663663133/) ![入れて蓋をして完了](https://camo.elchika.com/96232713e6378305a98d0b8e84f1e0b80cd84102/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30616461646462622d333430322d343137302d616130322d6138343064663039663538642f30636538396130342d333933362d346439392d396631662d386365333163383264396436/) ## 今後の展望 in vitroでは撮影できていましたが、コンテスト期限直前になってしまい 実際に屋外で猫の撮影を試すことまでは間に合いませんでした。 今後は屋外放置し野良猫をうまく撮影できるかの検証と、 バッテリーの持ちなどについて検証してみたいと思います。 ## 考察 初めてAIを導入し、neural network console を用いたカメラ撮影を行いました。 全く知識がないところから始めましたが、NNCは予想していたより導入は易しく初心者においても適切な機構だと感じました。 サンプルスケッチからスケッチを組めるものだと安易に思っていたところが調整に手間取りましたが、 参考書をにらめっこしながら、目標としていたエッジAIをどうにか構築することができました。 spresenseはGPS機能も有しているので 今後はその機能を使った作品にも挑戦していきたいと思います。 spresenseは初心者にも導入しやすく、様々な用途に応用できるデバイスだと体感することができました。