画像で認識させた商品の在庫数をLINEで返信してくれる物を作ってみた！！【Teachable Machine】




## はじめに
こんにちは！2回目の投稿になります！

まだQiitaの書き方不慣れですので見づらいかもしれませんが、以前の投稿を見てくださった方が以外に多くて感謝しかありません！！ありがとうございます！！

是非この記事もご一読いただけますととても励みになります！


さて今回は、Teachable Machine を使って在庫数を売り場で確認できるものを目指して開発してきました！！

私は小売業の会社に勤務しているのですが、自動で発注を行ってくれるシステムを1年前に導入致しました。しかし**在庫数がいくつか数えて入力するのが手間で、せっかく時間を削減できているのにもったいない！**　と思っていました！

そこで誰もが使えるスマホで確認できれば…。

ということで、作ってみました！

---
## 使用ツール
・Teachable Machine
・CodePen
・ml5.js（ImageClassifier）
・Google Sheets
・Make（旧integromat）
・各LINEモジュール
## 実際の動き
https://twitter.com/D04985466D/status/1572395226513444865

**CodePenで画像を判定し、その判定した商品名をMakeに送ります。
Makeは商品名に合わせた在庫数を取得しLINEに送ります。**

## 作成したCodePen

https://codepen.io/d04985466d/full/KKRmMzQ

## Google Sheets の中身
![スクリーンショット (302).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2806030/aefa2db1-4b62-7710-c52f-2a446e7779cd.png)
現在は３品のみですが、今後はより多くの商品に対応させていく予定です。

## Teachable Machineの設定
１商品のJANコードと外観を150~400枚ほど読み込ませる
２学習させ、学習後のプレビューで正確に認識できているか確認
３モデルをエクスポート
![スクリーンショット (301).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2806030/dfffb109-d440-d67b-1e6c-6c1e202532a2.png)


## Make の中身
![スクリーンショット (299).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2806030/038cd024-5eb8-ebb9-e0fc-043d6dcc98c3.png)
    Webhooksで?"text"="商品名"で設定、連携します。
### プログラム
引用を元にCodePenでコードを書き替えていきます。

``` html
<h1>在庫数確認</h1>

    <!-- このapp内のみVue.jsの管理範囲です -->
    <div id="app">
      <p>{{ modelState }}</p>
      <p>結果……{{ result }}</p>
      <button v-on:click="onButtonClicked">判定開始！</button>
      <video id="myvideo" width="640" height="480" autoplay></video>
    </div>

    <!-- ml5.js、Vue.js、axios.jsをCDNから読み込みます -->
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

// 作成したモデルのURL
      const imageModelURL = 'https://teachablemachine.withgoogle.com/models/T8pcu8SJd/';
      let classifier;

      const webhook = 'https://hook.eu1.make.com/bvi72t4nkmi1nh1kgslt9tgalp2jl6f5';

      const app = new Vue({
        el: '#app',
        data: {
          modelState: 'モデルロード中...',
          result: '判定待ち',
        },

        async mounted() {
          
          // カメラからの映像取得
          const stream = await navigator.mediaDevices.getUserMedia({
            audio: false,
            video: true,
          });

          // IDが"myvideo"であるDOMを取得
          const video = document.getElementById('myvideo');

          // videoにカメラ映像をセット
          video.srcObject = stream;

          // 自作モデルのロード
         classifier = ml5.imageClassifier(imageModelURL + 'model.json', video , () => {
            // ロード完了
            app.modelState = 'モデルロード完了！';
            console.log('Model Loaded!');
          });
        },

        methods: {
          getResult(error, results) {
            if (error) {
              console.error(error);
              return;
            }
            label = results[0].label;
            console.log(label);

            if (label === '成分無調整牛乳') {
              app.result = '成分無調整牛乳';
            } else if (label === '低脂肪乳飲料') {
              app.result = '低脂肪乳飲料';
               } else if (label === 'まきばの空') {
              app.result = 'まきばの空';
            } else {
              app.result = '測定できない';
            }
          },
          onButtonClicked: async function () {
            const results = await 
            classifier.classify(app.getResult);
            let res = 'NotFound';

            if (app.result === '成分無調整牛乳') {
              res = '成分無調整牛乳';
            } else if (app.result === '低脂肪乳飲料') {
              res = '低脂肪乳飲料';
               } else if (app.result === 'まきばの空') {
              res = 'まきばの空';
            } else {
              res = 'NotFound';
            }

            try {
              // GETリクエストでWebhookに送信
              const response = await axios.get(webhook + '?text=' + res);
              // データ送信が成功するとレスポンスが来る
              console.log('レスポンスを受信しました：' + response.data);
              console.log('POSTに成功しました！');
            } catch (error) {
              // ネットワークに接続できてない、サーバーが落ちてる、URLが違うなど様々なエラー
              console.log('POSTに失敗しました……');
              console.error(error);
            }
          },
        },
      });

``` 



### 参考にさせて頂いたリンク
https://qiita.com/heihei15408697/items/8311c3bbb0c88db12fb1





# 課題
課題として２点あります
**・スマホで行うとカメラが真っ暗になり認識できない**

**・わざわざGoogle Sheetsに在庫数を入力するのが手間**

在庫数入力の手間に関しては、業務で行っているRPAを利用しGoogle Sheetsに売上数、仕入れ数等を計算し自動で入力されるようにしたいと思います！
※盗まれる等もあるので完全に正確な数字は無理ですが…。

スマホで行うとカメラの画面が真っ暗で認識できない問題に関しては、JavaScriptを試行錯誤してみましたがうまくいきませんでした…。

有識者の方がこの記事をご覧になっていただけていましたら、コメントでお教えいただけますと幸いです。

# 最後に
今回はTeachable Machine を用いて開発してみましたが
引用したJavaScriptを**自分の動かしたい形に書き直すのにかなり時間がかかりました。（勉強しました）**
引用元のコードを検索し、どのような動きをしているかを把握しその部分を自分の実現したい形に書き直してみるをひたすら繰り返しました。

ですができた時の喜びはもう何よりも勝ります！！
まだまだ勉強して、知識を深めたいと思います。

寒くなって参りましたので皆さん体調にはお気を付けください！！