Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

posted at

updated at

ローコードでマスクチェッカーを作ろう!

2020年10月27日にMicrosoft社が買収した Lobeのベータ版がリリースされていたので、
マスクをしているかどうか判定するツールをNode-REDを使ってローコードで作ってみました。

1. Lobeをインストールする

Lobeをダウンロード

下記URLにアクセスしてLobeのアプリをダウンロードします。

諸々情報を入力して 「Download」ボタンをクリックします。

s100.png

ダウンロードしたファイルをインストールしておきます。

2. 学習データを登録する

2-1. プロジェクト作成

①プロジェクト名を入力して、右上の ②「Import」をクリックし、画像、カメラ、データセットからインポートしたい形式を選びます。今回は③カメラを選択しました。

s200.png

2-2. 学習データ登録

カメラ画像の左下に学習するラベル名を入力します。入力したら、画面中央にあるシャッターボタンをクリックします。
長押しすることで連続して撮影することも可能です。学習が終われば、右上の「Done」をクリックします。

s201.png

同様にマスクを付けているタイプの写真を撮影して学習させます。

s202.png

2-3. トレーニング

撮影したデータの学習はバックグラウンドでされます。100%になれば効果音で知らせてくれます。

s203.png

2-4. 確認する

学習したデータが正しくできているか確認します。左側メニューの「Play」から確認できます。判定ラベルはリアルタイムで切り替わります。

s204.png

判定がおかしい場合は左下のアイコンで判定して正しいものを学習させてください。

3. Node-REDで使う

学習したデータは様々な形でプログラムに組み込むことができます。サポートされているのは、CoreML TensorFlow TensorFlow Lite Local API の4つがありました。
今回はNode-REDで使うので、 Local API を使用します。

3-1. エクスポートする

メニューから「Export」をクリックします。

s300.png

Local API をクリックします。

s301.png

APIのURLが発行されるので、メモしておきましょう。

s302.png

3-2. Node-REDの設定

Node-RED Desktop アプリをインストールしてください。

ダウンロードしてアプリを起動して、右上のハンバーガーメニューにある「パレットの管理」をクリックします。

s303.png

①「ノードを追加」タブをクリックして、②検索窓に下記4つのノード名を入力して検索します。それぞれ③ノードを追加してください。

s304.png

3-3. ノードを配置する

左側にあるパレットウィンドウから、 入力カテゴリにある Camera ノードをフローエディタにドラッグ・アンド・ドロップします。

s305.png

続いて、出力カテゴリにある image ノードをドラッグ・アンド・ドロップして、先程配置した Camera ノードと線でつなぎます。

s306.png

パーサカテゴリにある、 base64 ノードをドラッグ・アンド・ドロップして、 Camera ノードとつなぎます。

s307.png

分析カテゴリにある、 lobe-local ノードをドラッグ・アンド・ドロップして、 base64 ノードとつなぎます。ノードをダブルクリックして、プロパティ画面を開きます。

URLにLobeで発行されたLocal APIのURLを貼り付けます。

s308.png

共通カテゴリにある、 debug ノードをドラッグ・アンド・ドロップして、 lobe-local ノードとつなぎます。最後に右上にある 「デプロイ」ボタンをクリックします。

s309.png

Camera ノードの左側にあるボタンをクリックするとPC内蔵カメラが起動します。デバッグタブをクリックして、結果が表示されていることを確認してください。

s310.png

マスクをつけると、「マスクあり」と返ってきます。

s311.png

うまくいかない方は下記をお試しください。

[
    {
        "id": "c74ee55b.52b928",
        "type": "tab",
        "label": "ハンズオン",
        "disabled": false,
        "info": ""
    },
    {
        "id": "dfcc243c.fb35d8",
        "type": "camera",
        "z": "c74ee55b.52b928",
        "name": "",
        "x": 120,
        "y": 240,
        "wires": [
            [
                "1fcd09cb.659fc6",
                "e0780598.440308"
            ]
        ]
    },
    {
        "id": "1fcd09cb.659fc6",
        "type": "image",
        "z": "c74ee55b.52b928",
        "name": "",
        "width": 160,
        "data": "payload",
        "dataType": "msg",
        "thumbnail": false,
        "active": true,
        "pass": false,
        "outputs": 0,
        "x": 170,
        "y": 340,
        "wires": []
    },
    {
        "id": "e0780598.440308",
        "type": "base64",
        "z": "c74ee55b.52b928",
        "name": "",
        "action": "",
        "property": "payload",
        "x": 300,
        "y": 240,
        "wires": [
            [
                "897476b5.cd05b8"
            ]
        ]
    },
    {
        "id": "897476b5.cd05b8",
        "type": "lobe-local",
        "z": "c74ee55b.52b928",
        "name": "",
        "modelUrl": "",
        "base64Image": "",
        "output": "best",
        "x": 480,
        "y": 240,
        "wires": [
            [
                "db2c90a0.b4824"
            ]
        ]
    },
    {
        "id": "db2c90a0.b4824",
        "type": "debug",
        "z": "c74ee55b.52b928",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 670,
        "y": 240,
        "wires": []
    }
]

4. LINEと連携しよう

4-1. 新規チャネルを作成する

LINE DeveloperページへアクセスしてLINEログインしてください。

まだプロバイダー設定してない方は「新規プロバイダー作成」をクリックします。

s200

プロバイダー名はお好きなものを入力して、「作成」ボタンをクリックします。

s201

Messaging API をクリックします。

s400.png

各種項目を埋めていきます。

項目
①チャネル名 Lobeハンズオン
②チャネル説明 Lobeハンズオン
③大業種 個人
④小業種 個人(その他)
⑤メールアドレス あなたのメールアドレスを入力してください

s401.png

2つのチェックを入れて、[作成]ボタンをクリックします。

s402

[同意する]ボタンをクリックします。

s403

4-2. ボットと友だちなる

作成したボットと友だちになっておきます。「Messaging API設定」タブにあるQRコードをLINEアプリから読み取って友だちになっておいてください。

s402.png

4-3. アクセストークンを発行する

下の方にスクロールして、チャネルアクセストークンカテゴリにある「発行」ボタンをクリックして、チャネルアクセストークンを発行して、メモしておきましょう。終われば、応答メッセージにある「編集」をクリックします。

s403.png

4-4. Webhookの設定を行う

応答メッセージ オフ 、Webhookは オン にしてから「Messaging API設定」ボタンをクリックしてください。

s404.png

WebhookのURLはNode-RED Desktopアプリのメニューバー①「エンドポイント - ngrokに接続する」で発行された②URLをコピーしておきます。Webhook URLはngrokのURLを貼り付けて、末尾に③「/bot」と入力して、④「保存」ボタンをクリックします。
そして、最後に記載されている ⑤Channel secret はメモしておきましょう。後ほど使います。

※例) https://xxxxxxxxxxxx.jp.ngrok.io/bot

s405.png

4-5. LINE用ノードを設定する

パレット管理から下記ノードを追加しておいてください。

ネットワークカテゴリにある http in ノードをドラッグ・アンド・ドロップします。メソッドは POST を選択して、URLに「/bot」と入力して、「完了」ボタンをクリックします。

項目
メソッド POST
URL /bot
※「/」を付け忘れないよう気をつけてください

s406.png

機能カテゴリにある function ノードをドラッグ・アンド・ドロップします。 http in ノードとつないでおきましょう。下記コードを反映させてください。LINEから送られてくる返信用のトークンを取得しています。

コード
msg.replyToken = msg.payload.events[0].replyToken;
return msg;

s407.png

LINEカテゴリにある line-image ノードをドラッグ・アンド・ドロップします。 function ノードとつないでおきましょう。AccessTokenは 4-3 で発行したチャネルアクセストークンを貼り付けます。出力形式は base64 を選択します。

項目
AccessToken 4-3で発行したチャネルアクセストークンを貼り付ける
出力形式 base64

s408.png

line-image ノードと lobe-local ノードを線でつないでおきましょう。

s409.png

機能カテゴリにある function ノードをドラッグ・アンド・ドロップします。 lobe-local ノードとつないでおきましょう。コード部分に下記コードを反映してください。

コード
const ret = msg.payload;
const replyToken = msg.replyToken;

msg.payload = {};
msg.payload.events = [
    {
        "type": "message",
        "replyToken": replyToken,
        "message": {
            "type": "text",
            "text": `これは「${ret}」かな`
        }
    }
];
return msg;

s410.png

LINEカテゴリにある ReplyMessage ノード(※PushMessegeではないので気をつけてください)をドラッグ・アンド・ドロップします。 function ノードとつないでおきましょう。
Secret(※4-4でメモしています)とアクセストークン(※4-3でメモしています)をそれぞれ反映してください。

項目
Secret 4-4でメモしたChannel Scret
AccessToken 4-3で発行したチャネルアクセストークン

s411.png

4-6. 動作確認する

LINEアプリで友だちになった「Lobeハンズオン」を開いてください。
トーク画面からマスクをつけていない画像とつけている画像をそれぞれ投稿して、結果が返ってくることを確認してみましょう。

s412.png

4-7. 最終的なノード

どうしてもうまくいかない方は下記をNode-REDに適用してください。LINEのアクセストークンや、LobeのURLはご自身のものを設定してください。

ハンズオン
[
    {
        "id": "c74ee55b.52b928",
        "type": "tab",
        "label": "ハンズオン",
        "disabled": false,
        "info": ""
    },
    {
        "id": "dfcc243c.fb35d8",
        "type": "camera",
        "z": "c74ee55b.52b928",
        "name": "",
        "x": 130,
        "y": 320,
        "wires": [
            [
                "1fcd09cb.659fc6",
                "e0780598.440308"
            ]
        ]
    },
    {
        "id": "1fcd09cb.659fc6",
        "type": "image",
        "z": "c74ee55b.52b928",
        "name": "",
        "width": 160,
        "data": "payload",
        "dataType": "msg",
        "thumbnail": false,
        "active": true,
        "pass": false,
        "outputs": 0,
        "x": 180,
        "y": 420,
        "wires": []
    },
    {
        "id": "e0780598.440308",
        "type": "base64",
        "z": "c74ee55b.52b928",
        "name": "",
        "action": "",
        "property": "payload",
        "x": 310,
        "y": 320,
        "wires": [
            [
                "897476b5.cd05b8"
            ]
        ]
    },
    {
        "id": "897476b5.cd05b8",
        "type": "lobe-local",
        "z": "c74ee55b.52b928",
        "name": "",
        "modelUrl": "",
        "base64Image": "",
        "output": "best",
        "x": 490,
        "y": 320,
        "wires": [
            [
                "db2c90a0.b4824",
                "e5b7608a.4514f"
            ]
        ]
    },
    {
        "id": "db2c90a0.b4824",
        "type": "debug",
        "z": "c74ee55b.52b928",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 680,
        "y": 320,
        "wires": []
    },
    {
        "id": "768e340b.3fa3fc",
        "type": "http in",
        "z": "c74ee55b.52b928",
        "name": "",
        "url": "/bot",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 130,
        "y": 200,
        "wires": [
            [
                "78838a5f.9f3784"
            ]
        ]
    },
    {
        "id": "6404378b.892d18",
        "type": "line-image",
        "z": "c74ee55b.52b928",
        "name": "",
        "MessageId": "",
        "AccessToken": "",
        "output": "base64",
        "x": 570,
        "y": 200,
        "wires": [
            [
                "897476b5.cd05b8"
            ]
        ]
    },
    {
        "id": "e5b7608a.4514f",
        "type": "function",
        "z": "c74ee55b.52b928",
        "name": "結果取得",
        "func": "const ret = msg.payload;\nconst replyToken = msg.replyToken;\n\nmsg.payload = {};\nmsg.payload.events = [\n    {\n        \"type\": \"message\",\n        \"replyToken\": replyToken,\n        \"message\": {\n            \"type\": \"text\",\n            \"text\": `これは「${ret}」かな`\n        }\n    }\n];\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 570,
        "y": 420,
        "wires": [
            [
                "c48a597a.950508"
            ]
        ]
    },
    {
        "id": "c48a597a.950508",
        "type": "ReplyMessage",
        "z": "c74ee55b.52b928",
        "name": "",
        "channelSecret": "",
        "channelAccessToken": "",
        "replyMessage": "",
        "x": 770,
        "y": 420,
        "wires": []
    },
    {
        "id": "78838a5f.9f3784",
        "type": "function",
        "z": "c74ee55b.52b928",
        "name": "リプライトークン取得",
        "func": "msg.replyToken = msg.payload.events[0].replyToken;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 340,
        "y": 200,
        "wires": [
            [
                "6404378b.892d18"
            ]
        ]
    }
]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?