地味に面倒くさいアレルゲンチェック【Teachable Machineを使ってみた。】

## Teachable Machineで簡単アレルゲンチェッカー
おはこんばんにちは、2回目の投稿になります。
猛暑だったり、大雨が降ったり今日も地球は忙しそうですが、皆様いかがお過ごしでしょうか。
私は出張先でこの記事を書いております。帰りたい。
挨拶はこのぐらいにして、今回は **「商品を手に取らずにアレルゲンチェックができるアプリを作ってみたい！」** ということでチャレンジしてみました。

https://twitter.com/dx_kumagai/status/1681322043772645378

## なぜアレルゲンチェッカー？
皆様はお買い物をするときに **アレルゲンチェック** をされていますでしょうか？
私は生まれつきアレルギーがあるので、あやしいと思うものは原材料の表示を必ず確認します。特に大変なのは野菜ジュースやスムージーなどで、混ざっている種類が多ければ多いほど、自分のダメなアレルゲンが入っているかどうかを確認するのが面倒くさいです。
このアレルゲンの表示や原材料の表示は、基本的に **商品パッケージの後ろ側** に書かれていることがほとんどですよね。
だから、商品を手に取ってみないとわからないんです。
しかし、コロナが流行りだしてからというもの、 **「一度手に取った商品を棚に戻す」** という行為に抵抗を感じるようになりました。
コロナの流行はだいぶ落ち着いてきていますが、予防が必要なことは今後も変わらないと言えます。
 **「商品を手に取らずともパッケージやバーコードからアレルゲンチェックができればもっと買い物しやすくなるかも」** そんな思いで簡単なアレルゲンチェッカーを作成してみました。
## 使用したツール
- [Teachable Machine](https://teachablemachine.withgoogle.com/)
- [CodePen](https://codepen.io/features/)
## Teachable Machineの設定
 **Teachable Machine** では画像や音声をAIに認識させ、学習させたサンプルを基に判断させることができます。今回の場合は、アレルゲンチェッカーですので商品の画像を学習させます。
代表的なアレルゲン **「卵・乳・小麦を含むか、含まないか」** を判断させる2
パターンと、商品が映っていない場合の **「該当商品なし」** を含む全3パターンで作成しました。
<details><summary><font color="Green"><b>＊＊＊Teachable Machine作成の詳細はこちら＊＊＊</b></font></summary>

#### **サンプル画像の取り込み**
 サンプルとなる商品の画像を撮影していきます。この時、商品のパッケージだけでなく、商品のバーコードもサンプルに混ぜてみました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/c7e0c4b6-524a-34fd-d5a1-128106e0e0fd.png"width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/96fea748-86c2-99c3-3b83-54bbbb03e96f.png"width=20%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/fc199a35-ca5b-7df2-b511-a88c6baecc36.png"width=20%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/b0a8ff5c-7453-4ee9-537b-5392523eb77a.png"width=20%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/fb113662-fc81-401b-01a9-41e345ed81e2.png"width=20%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/6de98482-2607-04b3-9556-c3bdaa570109.png"width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/6516324f-a7df-22dd-f928-f3e001269d03.png"width=20%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/81ab25a1-6a44-9a67-ec30-cc55dc0602fd.png"width=20%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/6837ee07-d690-b9f2-6066-db278e29a1cf.png"width=20%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/ff99e846-dd09-e596-9a86-d2b9eb543dc1.png"width=20%>

最後に「該当商品なし」として背景のみを撮影しています。
これがないと、何も映っていない時でも一生懸命アレルゲンを含むか含まないか判断しようとします。
AIちゃんは頑張り屋さんですね。「何も映ってないよ」ときちんと教えてあげましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/8541bb07-812b-9188-094d-ccbe234cfc71.png"width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/a4773bdc-a4f5-3540-4a5f-f44cffab0cce.png"width=20%>
＊背景と言いつつがっつりぬいぐるみが映ってますが今回は **該当商品** が映ってなければいいので無視します。

#### **AIに学習させる** 
サンプルの撮影が終わったら、このサンプルたちをAIに学習させます。画面真ん中に **「モデルをトレーニングする」** というボタンがあるのでここを押します。
 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/0d2daa00-bc1a-6b5f-231d-d2d4921e5d60.png"width=50%>

#### **AIが学習できたかチェックをしてアップロード**
トレーニングが終わるとカメラの映像と、その下にAIが判断した結果がパーセンテージで表示されます。試しに商品をカメラに映して正しく判断できているかをチェックします。正しくない場合はサンプル数を足してあげるといいかもしれません。
チェックが終わったら、 **「モデルをエクスポートする」** を押します。
 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/879c71ea-71e6-8ae2-2c14-74c96d5911f6.png"width=50%>
するとこのような画面が出てきますので、 **「モデルをアップロード」** を押します。
 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/3615425f-ee3f-d249-2531-e1c332c22f09.png"width=50%>
共有可能なリンクが表示されたら、「モデルを使用するコードスニペット」の **「p5.js」** を選択してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/e4ccc0e1-152f-1047-d988-531f0b8e4fc4.png"width=50%>
こちらの下に書かれているコードを後で使用しますので、コピーしてどこかにメモしておくか、画面を閉じないようにしておいてください。

Teachable Machineの作成は以上です。
</details>

## CodePenの設定
 **CodePen** とはブラウザ上でコードを記述し、自分で開発ができるWebサービスになります。
今回はTeachable Machineをスマートフォンでも使用できるようにするため、CodePenを使用しました。
<details><summary><font color="Green"><b>＊＊＊CodePen作成の詳細はこちら＊＊＊</b></font></summary>

#### **Teachable Machineのコードを入力**
CodePenで作成画面を開くと3つの箱のような表示があります。使用するのは1番右にある **「HTML」** というところです。
ここに先ほどTeachable Machineの作成でコピーしたコードを貼り付けます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/a5bdbdca-1bb5-ec19-b22a-404c168fccc2.png"width=70%>
```ruby:qiita.rb
<div>Teachable Machine Image Model - p5.js and ml5.js</div>
<script src="https://cdn.jsdelivr.net/npm/p5@latest/lib/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@latest/lib/addons/p5.dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ml5@latest/dist/ml5.min.js"></script>
<script type="text/javascript">
  // Classifier Variable
  let classifier;
  // Model URL
  let imageModelURL = 'https://teachablemachine.withgoogle.com/models/-D9K0H6iQ/';
  
  // Video
  let video;
  let flippedVideo;
  // To store the classification
  let label = "";

  // Load the model first
  function preload() {
    classifier = ml5.imageClassifier(imageModelURL + 'model.json');
  }

  function setup() {
    createCanvas(320, 260);
    // Create the video
    video = createCapture(VIDEO);
    video.size(320, 240);
    video.hide();

    flippedVideo = ml5.flipImage(video);
    // Start classifying
    classifyVideo();
  }

  function draw() {
    background(0);
    // Draw the video
    image(flippedVideo, 0, 0);

    // Draw the label
    fill(255);
    textSize(16);
    textAlign(CENTER);
    text(label, width / 2, height - 4);
  }

  // Get a prediction for the current video frame
  function classifyVideo() {
    flippedVideo = ml5.flipImage(video)
    classifier.classify(flippedVideo, gotResult);
    flippedVideo.remove();

  }

  // When we get a result
  function gotResult(error, results) {
    // If there is an error
    if (error) {
      console.error(error);
      return;
    }
    // The results are in an array ordered by confidence.
    // console.log(results[0]);
    label = results[0].label;
    // Classifiy again!
    classifyVideo();
  }
</script>

```

コードを貼り付けると、画面下にTeachable Machineと同じようなカメラの映像と結果が表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/7c9c7b3c-18fd-f02a-4b1c-b872e91ffd2e.png"width=50%>

#### **画面の表示を切り替え** 
Teachable Machineの動作を確認後、画面右上にある四角いボタンを押します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/a7e29b28-4536-3791-c520-d93003e65e75.png"width=50%>
するとメニューが表示されますので、 **「Full Page View」** を押します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/fc2d2235-fa97-7393-9df8-52b720990e38.png"width=50%>
Full Page Viewにするとコード入力の画面が非表示になり、カメラの映像と結果の表示だけになります。
このページのURLをスマートフォンで検索すると、スマートフォンのカメラを使用してアレルゲンチェッカーを使用することができます。

CodePenの作成は以上です。
</details>

## 反省・まとめ
とりあえずは簡単アレルゲンチェッカー完成です。
サンプル数をどんどん追加していけばもっと活用できそうです。
ただ、 **「該当商品なし」** に関しては背景だけを映すと **"その景色＝該当商品なし"** になってしまうため、商品が **"ない"** ことを覚えさせるというのは難しいのかもと感じました。
本当のことを言うと、[前回のLINEBot作成](https://qiita.com/dx_kumagai/items/1536bc3abfc359d522ff)を活かして、 **「LINEから画像を送って認識させ、結果を返信する」** ということをやりたかったのですが、今の私ではまだまだ力不足でした…。
<details><summary><font color="Green"><b>＊＊＊LINEbot作成(Node-RED)の詳細はこちら＊＊＊</b></font></summary>

#### **Node-REDの全体図**
![Node-RED.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/7b62e207-5b81-f62e-de38-57a6531a547c.png)
上の半透明になっている部分は、まずNode-REDでLINEと連携し、メッセージのやり取りができるかを確認する為に「オウム返し」を作成しました。
メッセージのやり取りが確認できたため、無効化しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/64613250-d7e6-5ef7-b400-c09e2b001ee5.jpeg"width=50%>
問題になっているのがおそらく以下の部分です。
![Node-RED2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457665/3e3c882f-f14b-cecd-1bab-7edbe69b2719.png)
LINEで画像を送った時点で止まってしまうため、Teachable Machineが画像として認識出来ていないのだと思います。cameraと接続したときにはきちんと動いていたため、LINEとTeachable Machineの間に何かしら必要なのだと考えているのですがそれが何なのか分かりませんでした…。難しい…。
LINEBot作成(Node-RED)については以上です。
</details>

また、画像認識で解決できそうな課題で他に思い付いたのが、食料品の限度日検討日チェックです。
お店に並んでいる食料品には、限度日・検討日というものが設定されており、定期的にチェックを行います。が、これが本当に大変な作業なのです。人員不足時の応援で何度か経験しましたが、商品によって期限が違うし、頭で日付を計算するのも面倒くさいし、商品を一つずつ確認しなくちゃいけないし…。
実際日付の認識がどこまで学習させられるのかはわかりませんが、これがカメラでパパッと判断出来たら楽だろうなぁと感じました。

今回は以上になります。
最後までお付き合いいただきありがとうございました。