10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🍇🍐🍎秋の旬果実判定×TeachableMachine これで君も商品知識アップ!

Last updated at Posted at 2024-09-24

機械学習を生かした企画を考案

みなさん、こんにちは、45O(シンゴオー)です。
私は小売業に勤め、最近デジタルについて勉強している者です。
今回はML(Machine Learning) = 機械学習
活用した企画を考えました。

果実判定と商品知識を表示するアプリ

Teachable Machineを使用して果物の種類を分類し、それに基づいた保存方法やイチオシ情報を表示するアプリを作成しました。

:thinking:アプリ制作背景

野菜・果物売場の担当者は笑顔で元気な挨拶ができて
さらに、「商品知識も豊富であってほしい」

例えば
・今日のおすすめ旬の果物は、これ!
・鮮度の見極めポイントは、これ!
・家庭での保存方向は、これ! 
・イチオシ情報は、これ!    などなど

新人の担当者も効果的に、商品知識の習得はできないかと考え、
アプリで果実の判別に加え、商品知識を学べる方法を検討。
分厚いマニュアルから脱却し、スマホで商品を画像認識するだけで
知識が増えていく、そんなツールを考案してみました。

う.png

作成したものはこれ!

:wrench:使用ツール

TeachableMachine
CodePen
・GoogleSpreadSheet
GhatGPT

アプリ制作全体の流れ

全体の流れは下で図解した4ステップとなります。
この4ステップをそれぞれ説明していきます。

2.png

①TeachableMachineでURL取得

まず第1ステップを以下の図で説明していきます。
Teachable Machineのサイトを開きます。

image.png

①使ってみるをクリック。
②画像プロジェクトをクリック。
③標準の画像モデルをクリック。
④の画面までいけば、ここまでOK。

image.png
⑤の:pen_ballpoint:マークのところで果物の名前を入力。
 ウェブカメラをクリックします。
⑥の画面が開くので写真のようにカメラにりんごを写し、
 長押しで録画をクリックして、いろんな角度から撮影します。
※100枚以上撮影した方が判別精度が高くなります。
⑦のように複数の果物で同様の撮影を行ったあと、
 モデルトレーニングをするをクリック。
 少し待つと右下端の画面のようにモデルを試すことができます。
 うまく判定できていたら、モデルをエクスポートするをクリック。
⑧の画面が開くので、モデルのアップロードをクリック。
 そうすると、共有可能なリンク:にURLが表示されます。
 アプリ化する際はこのURLが必要になります。
 右下のコピーをクリックしてURLを取得ください。

image.png

②商品知識をGoogleSpreadSheetに準備

次は第2ステップです
果物の判別に伴って表示したい項目と内容を
GoogleSpreadSheetに準備します。
以下の図の通りです。

image.png

ちなみに上記、商品知識は販売マニュアルから引用したものなので
マニュアルの内容を学ぶことができます。
加えて、イチオシ情報は、妻が紹介してくれた「青髪のテツ」さんからの情報を参考にしました。野菜・果物についていろいろ勉強になるのでおすすめです。かなりの人がこの方をフォローしてます。
参考:「青髪のテツ」さんXはこちら。

③ChatGPTにコードを作成してもらう

次は第3ステップChatGPTCodePenに入力するコードを
作成してもらいます。
最終の完成のコードは下の「ChatGPT作成のソースコードはこちら」にありますが、ここではやり取りをしたプロンプトについて紹介します。

プロンプトのやり取りはこちら

Teachable Machineを使った果物分類アプリの作成
このやり取りでは、Teachable Machineを使用して、ビデオから物体や果実をリアルタイムで分類するアプリをCodePenで作成するプロセスを進めています。具体的には、果実の分類結果に基づき、見分け方や保存方法などの情報を表示するアプリを構築することを目指しています。

指示の流れ

  1. シャインマスカット、りんご、なしの判定
    「シャインマスカット、りんご、なしで判定して、HTML、CSS、JavaScriptのコードをそれぞれ分けて表示してください。」

  2. モデルが固まる問題
    「シャインマスカット、りんご、なしの果実判定を行うコードでModel Loaded!で固まってしまうが、これを修正したいです。」

  3. 見分け方の追加
    「果実の判定後に、その果実の見分け方のポイントを表示したいです。例えば、シャインマスカットと判定されたら、ヘタがピンとして緑色のものが鮮度がよいというように表示したいです。」

  4. 保存方法の追加
    「見分け方のポイントに加えて、保存方法も表示するように修正したいです。」

  5. 簡潔な表示と黒文字
    「見分け方のポイントを見分け方に修正し、文字色を緑から黒に変更したいです。さらに、表示は簡潔にしたいです。」

  6. スマホのアウトカメラ設定
    「CodePenでスマホのカメラをアウトカメラ(背面カメラ)に変更したいです。」

  7. 見分け方、保存方法、その他情報の表示
    「アウトカメラはそのままにして、①旬の時期、②見分け方、③家庭保存、④店舗保存、⑤イチオシ情報の5つを表示できるようにしたいです。」

(添付ファイルとして「秋の旬果実判別.xlsx」をアップロード)
8. Qiita記事用のコード
「これまでのコードをQiitaに載せたいので、説明付きでmodelURLをプレースホルダーにして、HTML、CSS、JavaScriptのコードを分けて書いてください。」

上のプロンプトように、ChatGPTは指示をすると都度コードを作成してくれます。また実際コードを作成してみてうまく動かないことも伝えると、再度修正コードを作成してくれます。いろいろやり取りをして、自分なりのベストなコードにしていただければ幸いです。

補足事項としては2点
6.スマホアウトカメラ設定
これは最終的にスマホでアプリを使用したいと考え、プロンプトで指示しアウトカメラの設定でコードを作成しました。
※従って、PCでのインカメラではこの記事のコードは稼働しないので注意ください。
7.見分け方、保存方法、その他情報の表示
7番目にGoogleSpreadSheetをアップロードしてプロンプトで指示をしていますが、これが先に決まっている場合はもちろん、前提を伝えたうえで最初に指示してもコードを作成してくれます。
下のような感じで指示しました。

image.png

ChatGPT作成のソースコードはこちら

Click!!(ソースコードが開きます!) Open!!

必要な準備

  • Teachable Machineで果物分類モデルを作成。
  • そのモデルのURLを取得して、YOUR_MODEL_URLの部分に差し替える。

HTML部分

以下のHTMLコードを使用して、Webカメラ映像の表示や分類結果を表示するエリアを設定します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>果物の旬と保存方法</title>
    <!-- ml5.jsライブラリを読み込み -->
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
    <!-- axiosライブラリを読み込み(サーバーへのデータ送信に使用) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <!-- 外部CSSをリンク -->
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>果物の判定と保存方法</h1>
    <!-- Webカメラ映像を表示するビデオ要素 -->
    <video id="webcam" autoplay playsinline width="430" height="320"></video>
    <p id="result">Loading model...</p>
    
    <!-- 各情報(旬の時期、見分け方、保存方法など)を表示する枠付きエリア -->
    <div class="info-box" id="fruit-season">旬の時期がここに表示されます。</div>
    <div class="info-box" id="fruit-tips">見分け方がここに表示されます。</div>
    <div class="info-box" id="fruit-homeStorage">家庭保存がここに表示されます。</div>
    <div class="info-box" id="fruit-storeStorage">店舗保存がここに表示されます。</div>
    <div class="info-box" id="fruit-recommendation">イチオシ情報がここに表示されます。</div>

    <!-- メインのJavaScriptをリンク -->
    <script src="script.js"></script>
</body>
</html>

CSS部分

CSSを使用して、画面のデザインを果物風に整えます。各情報にはボックス枠をつけ、全体の見やすさを高めます。

/* 果物風の背景と全体のスタイリング */
body {
    font-family: 'Arial', sans-serif;
    text-align: center;
    margin: 0;
    padding: 0;
    background-color: #fff4e6;  /* 柔らかいオレンジ背景 */
    color: #333; /* テキストを黒に */
}

h1 {
    color: #d35400;  /* 明るいオレンジ色で果物っぽさを演出 */
    margin-top: 20px;
    font-size: 2em;
}

#webcam {
    margin: 20px auto;
    border: 2px solid #3498db;
    border-radius: 10px;
}

#result {
    font-size: 1.5em;
    font-weight: bold;
    margin-top: 20px;
    color: #e74c3c;  /* 赤色で結果を強調 */
}

/* 各情報を表示するボックス */
.info-box {
    background-color: #f9f9f9;  /* 明るい背景色 */
    border: 2px solid #2ecc71;  /* 緑色の枠 */
    border-radius: 15px;  /* 角を丸く */
    padding: 15px;
    margin: 15px auto;
    width: 80%;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);  /* 影をつけて立体感 */
    font-size: 1.2em;
}

/* 果物をテーマにしたアクセントカラー */
.info-box:nth-child(odd) {
    background-color: #ffebcc;  /* 薄いオレンジ背景 */
}

.info-box:nth-child(even) {
    background-color: #e0ffd8;  /* 薄いグリーン背景 */
}

/* メディアクエリでモバイル表示対応 */
@media (max-width: 600px) {
    .info-box {
        width: 90%;
        font-size: 1.1em;
    }
}

JavaScript部分

JavaScriptでは、Teachable Machineを使ったモデルのロードとWebカメラの設定、分類結果を元に果物の情報を表示するロジックを実装します。

// 画像分類用の変数とビデオ要素を定義
let classifier;
let video;

// Teachable MachineのモデルURL(実際にはご自身のモデルURLを入力)
const modelURL = 'https://teachablemachine.withgoogle.com/models/YOUR_MODEL_URL/';

// 各果物に関する情報(旬の時期、見分け方、保存方法など)
const fruitData = {
    "シャインマスカット": {
        season: "8月~10月",
        tips: "ヘタがピンとして緑色のものが鮮度が良いです。",
        homeStorage: "冷蔵庫の野菜室で保存し、早めに食べましょう。",
        storeStorage: "冷蔵庫で保管。",
        recommendation: "軸が緑色の個体は鮮度が良いです!"
    },
    "なし": {
        season: "7月中旬~9月末",
        tips: "軸がしっかりとしており、みずみずしく張りがあり、重みのあるもの。",
        homeStorage: "冷蔵庫の野菜室で保存し、数日内に食べるのが良い。",
        storeStorage: "非冷ストックで保管。幸水は品質低下が早いので注意。",
        recommendation: "梨は軸が太いほうが木から栄養をしっかり吸収しています!"
    },
    "りんご": {
        season: "9月中旬~11月下旬",
        tips: "重みがあり、皮にハリがあり、色が均一でムラがないもの。",
        homeStorage: "袋で密閉して冷蔵庫で保存。低温で甘みが増す冷蔵室がおすすめ。",
        storeStorage: "夏季は冷蔵庫で保管。9月~2月は常温で保管。",
        recommendation: "りんごに含まれる果糖は低温で甘みが増します!"
    }
};

// Teachable Machineのモデルをロードする関数
async function loadModel() {
    classifier = await ml5.imageClassifier(modelURL + 'model.json');  // モデルのロード
    document.getElementById('result').innerText = 'Model loaded';
}

// スマホやPCのカメラを設定し、映像を表示する関数
async function setupWebcam() {
    video = document.getElementById('webcam');
    try {
        // アウトカメラ(背面カメラ)を使用
        const stream = await navigator.mediaDevices.getUserMedia({
            video: {
                facingMode: { exact: "environment" }  // 背面カメラ指定
            }
        });
        video.srcObject = stream;
    } catch (err) {
        console.error('Error accessing the webcam:', err);
    }
}

// Webカメラ映像から分類を行い、結果を表示する関数
async function classifyVideo() {
    try {
        const results = await classifier.classify(video);
        const fruitName = results[0].label;
        const confidence = results[0].confidence.toFixed(4);
        
        // 分類結果と信頼度を表示
        document.getElementById('result').innerText = `判定結果: ${fruitName} 信頼度: ${confidence}`;

        // 分類された果物の詳細情報を表示
        const info = fruitData[fruitName];
        if (info) {
            document.getElementById('fruit-season').innerText = `旬の時期: ${info.season}`;
            document.getElementById('fruit-tips').innerText = `見分け方: ${info.tips}`;
            document.getElementById('fruit-homeStorage').innerText = `家庭保存: ${

info.homeStorage}`;
            document.getElementById('fruit-storeStorage').innerText = `店舗保存: ${info.storeStorage}`;
            document.getElementById('fruit-recommendation').innerText = `イチオシ情報: ${info.recommendation}`;
        } else {
            // データがない場合の表示
            document.getElementById('fruit-season').innerText = "情報が見つかりません。";
            document.getElementById('fruit-tips').innerText = "";
            document.getElementById('fruit-homeStorage').innerText = "";
            document.getElementById('fruit-storeStorage').innerText = "";
            document.getElementById('fruit-recommendation').innerText = "";
        }

        classifyVideo(); // 次のフレームも分類を続行
    } catch (err) {
        console.error('Error during classification:', err);
    }
}

// ページのロード時にカメラとモデルを初期化する関数
async function init() {
    await setupWebcam();
    await loadModel();
    classifyVideo();
}

// ページが読み込まれたときに実行
window.onload = init;

④CodePenに作成したURLとコードを貼付

最後に第4ステップです。
作業は以下の図解の通りです。
image.png

image.png
これでアプリとしては完成しました。
アウトカメラなので、スマホで確認します。

:calling:スマホで確認

スマホで確認する際は以下の流れです。

image.png
CodePenのURLをコピーしスマホへメール送信。
②スマホでURLを開くと②の画面となるので上の:white_check_mark:をクリック
 デバッグモード (Debug Mode)をクリックします。
③の画面が開き、アウトカメラで
 果実判別と商品知識表示が実行されます。

CodePenのDebugモードは、作成したペン(HTML、CSS、JavaScriptのプロジェクト)を、余計なCodePenのフレームやインターフェースなしにブラウザ内で直接実行できるモードです。このモードを使うことで、プロジェクトがどのように動作するかを「本番環境」に近い形で確認できます。

:iphone:売場でも実装してみた!

許可をいただいて売場でも判別できるか実装しました。

image.png

ちゃんとできています!:v_tone2:
ただ、りんごやなしは2個パックや大袋での販売もしていて、
Teachable Machineでの機会学習の形状ではないので、
その点は判別できないものもありました。
また機械学習が1個をアップで撮影したこともあり、
1個売りに対してカメラを近づけないと
判断しずらいということも発見。
売場での実行はとても気づきが多いなあと感じました。

フィードバックもらってみた!

職場のメンバーに意見をきいてみました。
今回は動画を見てもらって、コメントをもらいました。

部長
・事前に学習させたデータを読み込む感じ?
 魚で食べ方なんかの表示が出ても面白いですね。
 リアルタイムでネットから情報を
収集してくるような感じだとやはり大変なのかな。

Mさん
・商品画像と、商品化(陳列する時の)画像と
 売場レイアウトが紐づけられると
朝の商品の店だし(売場づくり)に役立つ。
・商品コードと紐づけし、
欠品している(売場在庫がなくなっている)商品の
商品映像がでてくればバックルームで
商品を探す時間の短縮につながるのでは?

部長からの旬の魚🐡の画像から、メニュー提案がでてくる面白い。
今だったら秋刀魚(さんま)ですかね。
今年は例年よりは豊漁のようだし。やはり、塩焼き?
部長もMさんも、さらにレベル高いアイデアをぶつけてきました。
でも、とてもありがたいフィードバックです:hugging:

:white_check_mark:さらなる応用編

応用編として、品種判別とメニュー提案にチャレンジしました!
フィードバックをもらった事項の実現にチャレンジです。
北海道フェアでいろんなじゃがいもを発見!これでやります!

🥔じゃがいも品種判定&メニュー提案

完成した動画はこれ

:pushpin:ポイント

ポイントを説明します。
TeachableMachineでキタアカリ、メークイン、インカのめざめの機械学習をします。

image.png

果実の判別の時と同様GoogleSpreadSheetを活用し表示項目を入力。
今回はcookpadを活用してメニュー提案とサイトURLを入力。

image.png

ChaGPTへのプロンプトは以下の通りです。
URLは表示せず、メニュー提案の料理をクリックでの移動を指示したところが工夫した点です。

image.png

これで、ChaGPTがコードを作成してくれるので、あとは、果実の場合と同様に④CodePenに作成したURLとコードを貼付のステップを実施して確認すればOKです。

この取り組みからの気づき
品種の判別はけっこう難しい:disappointed_relieved:
当初は販売している状態、袋売を想定して、
透明ビニール袋に複数個入れて判定を目指したが
なかなかうまくいきませんでした。
1個ごとの判定に変更し、なんとか判定できました。
メニュー提案は想定したものができた!
メニュー提案は意図したことが実現できたので
チャレンジしてみてよかったです。
我が家はじゃがいも祭りです。🥔🥔🥔

:relaxed:あとがき

大変ながらも楽しく取り組みができました。
🍇🍐🍎果物を使ってプロトタイプを作ることは
とてもわくわくしました!
売場での実装や、フィードバックもいただけて、
さらなる可能性を感じました。

デジタルを学ぶって楽しい、モノづくりは楽しい
大変だけどそんな時間でした!

ここまで読んでいただき、ありがとうございます。
まだまだ成長できるはず!

:pushpin:参考記事

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?