2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

qnoteAdvent Calendar 2020

Day 20

空の画像で天気を予想してくれるLINE BOTを作った

Last updated at Posted at 2020-12-19

機械学習とLINE BOT作りに興味があったので、この二つを組み合わせて、撮影した空や雲の画像から天気を予想してくれるLINE BOTを作りました。

参考にした記事

画像認識AIを使ったLINE BOTの作り方
さらに、上記の記事の作者様が作成された、AIメーカーで天気予想の部分はまるっと作成可能でした。

AIメーカーでAIを作る

スクリーンショット 2020-12-07 21.10.16.png

「AIに識別させるラベル」という項目がAIが返す結果になります。
今回は「すぐに雨が降るか」「数時間後に雨が降るか」「雨は降らないか」の3つの結果を返すようにしました。
AIの名前など適宜入力をしたら、いよいよ学習に入ります。
スクリーンショット 2020-12-07 21.07.11.png
学習方法は、作成したラベルに該当する画像をひたすら読み込ませるだけです。
この辺のサイトから雨を降らせる雲の名前を調べて、「検索して画像を追加」ボタンを押すだけで自動的に画像を収集して登録してくれます。便利!
もちろん全然関係のない画像を拾ってきてしまうこともあるので、その場合は手動で削除します。
それぞれのラベルに画像を登録してAIの作成は完了です。

LINE BOT を作る

アカウントの作成方法は公式ページの1~5を参照しました。
スクリーンショット 2020-12-18 21.34.39.png
画像のように「応答メッセージ」と「あいさつメッセージ」は無効に設定しておき、「Webhookの利用」を有効にしておきます。
同じ設定画面から「チャンネルアクセストークン」を発行しておきます。

あとはGoogle Apps Script に下記コードを記述します。

var AIMAKER_MODEL_ID = AIメーカーで作成したモデルのID;
var AIMAKER_API_KEY = AIメーカーのAPIキー;
var LINE_ACCESS_TOKEN = LINE BOTのチャンネルアクセストークン;

function doPost(e){
  try {
    var json = JSON.parse(e.postData.contents);
    var token= json.events[0].replyToken;
    var url = 'https://api.line.me/v2/bot/message/'+ json.events[0].message.id +'/content/';
    var image = getImage(url);
    var base64 = Utilities.base64Encode(image.getContent());
    var message = getResult(base64);
    if (message == '') {
      message = "識別できませんでした。";
    }
    sendLineMessage(message, token);
  } catch (e) {
    message = "処理に失敗しました。"
    sendLineMessage(message, token);
  }
}

function getImage(url){
  return UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN,
    },
    'method': 'GET'
  });
}

function getResult(base64){
  var result = '';
  var url = 'https://aimaker.io/image/classification/api';
  var payload = {
    "id": AIMAKER_MODEL_ID,
    "apikey": AIMAKER_API_KEY,
    "base64": base64
  };
  var response = UrlFetchApp.fetch(url, {   
    method: 'POST', 
    payload: payload, 
    muteHttpExceptions: true
  });
  response = response.getContentText();
  var json = JSON.parse(response);
  var labels = sortLabel(json.labels);
  if (labels[0].label && labels[0].score){  
    result = 'この画像の診断結果は、「' + labels[0].label + ': ' + (Math.round(labels[0].score * 10000) / 100) + "%」です!\n\n";
  }
  for (var i in labels) {
    if (labels[i].label && labels[i].score) {
      result = result + labels[i].label + ': ' + (Math.round(labels[i].score * 10000) / 100) + "%\n";
    }
  }
  return result;
}

function sortLabel(labels){
  labels.sort(function(a,b){
    if (a.score > b.score) return -1;
    if (a.score < b.score) return 1;
    return 0;
  });
  return labels;
}

function sendLineMessage(message,token){
  var url = "https://api.line.me/v2/bot/message/reply";
  return UrlFetchApp.fetch(url, {
    'headers': { 
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN,
    },
    'method': 'POST',
    'payload': JSON.stringify({ 
      'replyToken': token,
      'messages': [
        { 
          "type": "text",
          "text": message
        } 
      ], 
    })
  });
}

コードの記述が済んだら、公開タブのウェブアプリケーションとして導入を選択し、以下のように実行します。
Execute the app as(次のユーザーとしてアプリケーションを実行):自分
Who has access to the app(アプリケーションにアクセスできるユーザー):全員(匿名ユーザーを含む)
初回のみGoogleアカウントへのアクセス許可が出るのでこれを許可します。
発行されたURLは、LINE BOTの管理画面のWebhook URLに設定します。
ちなみに、コードを修正等で更新した場合は、Project versionを New としないとなぜかうまく更新されません。これで地味に詰まりました…。
#完成したもの
967qpnwu.png
肝心の精度ですが、快晴の日の空で試してみたものの
IMG_3797.jpg
うーん…???とりあえず今すぐには雨は降らないということですね!
まぁ普通に天気予報見ろってことですが、機械学習の片鱗を味わえたことと、LINE BOTは意外と簡単に作れると知れたのがよかったです。
特にLINE BOTとGASの組み合わせはいろいろ使えそうな気がします。
もう少し実用的なものも今度作ってみたいなと思いました。

###おまけ
BOTからの返信に画像を使うこともできます。
公式にある通り、返信の部分をこのようにすると画像を返すこともできます。

'messages': [
        { 
          "type": "image",
          "originalContentUrl": message,
          "previewImageUrl": message
        } 
      ], 

originalContentUrlとpreviewImageUrlには画像のパスを指定します。
Googleドライブに置いてある画像を使いたかったので調べたところ、共有設定を「リンクを知っている全員」にして、画像パスをhttps://drive.google.com/uc?id=画像IDと指定するとできました。
画像IDは共有リンクのhttps://drive.google.com/file/d/この部分です/view?usp=sharing
###おまけでできたもの
古のネタ、〇〇のAAくださいのノリで、送った画像の紅度に応じた紅だAAを返してくれます。
とてもくだらないですごめんなさい。
452lbjsl.png

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?