#概要
スマホで撮影した動物の写真をLINE Bot宛てに送ると、
動物の種類を教えてくれる動物図鑑。
###更新履歴
2019/09/07 デグーとチンチラとモルモットを追加。(結構げっ歯類の判定が厳しくなってきた!)
2019/09/01 ペンギンの種類を追加。
2019/08/30 一部要望のあった動物を追加。(ペンギン、トリ ※主にカラス を追加)
その他の動物もリクエストお待ちしております。
2019/08/20 LINEBotのQRコード追加
##作ったきっかけ
2019年8月某日からWindows10のログイン画面に急遽出現したカワウソ。
このカワウソの種類を簡単に調べるにはどうすれば良いか?
道端で動いている怪しい動物はなんていう動物なのか?
という非日常的な問題を簡単に解決できるようにしたい。
##完成デモ
https://www.youtube.com/watch?v=PeuqqgVQMRU&feature=youtu.be
※クリックするとYoutubeを開きます。
##実施環境
OS:Windows10 Pro 64ビット
画像認識:Azure CustomVisonService
動作:Node.js
デプロイ環境:Now
##事前準備(必要ツール)
- Python3.7.4(32ビット)のインストール
ダウンロード先:
https://www.python.org/ftp/python/3.7.4/python-3.7.4.exe
####Add Python 3.7 to PATHのチェックは忘れずに!
2.Python起動確認
コマンドプロンプトから Python --versionを入力
Python3.7.4などインストールしたバージョンが表示されればOK。
3.pipの確認(Pythonと同時にインストールされるらしい)
コマンドプロンプトから pip -V を入力
4.google-images-downloadをインストールします。
Pythonで作成されているため、導入はコマンドライン上から'pip'のコマンドを使ってインストールします。
コマンドプロンプトを立ち上げ、下記のコマンドを入力。
pip install google_images_download
##学習用の画像データの準備
google-images-download を使うことで、指定したキーワードの画像を一括入手できます。
1.コマンドプロンプトに下記のコマンドを入力し、実行します。
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium
バッチファイル化することでまとめて実行できます。
cd C:\Users\[アカウント名]\Desktop\download
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium -co white
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium -co black
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium -co red
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium -co green
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium -co gray
googleimagesdownload -k 'コツメカワウソ' -la Japanese -l 100 -s medium -co yellow
ダウンロードできる画像数は100を上限に指定できます。
100毎より多くダウンロードしたい場合は、chromedriver.exeが別途必要になります。
※オプションに -co red を付けると赤いカワウソがダウンロードできます。
各色毎にダウンロードして素材データとして使いました。
##学習用データの登録
-
Azure Cognitive Vision Servicesにアクセスします。
https://www.customvision.ai/projects -
各種項目を埋めていきます
Name:プロジェクト名
Description:プロジェクトの説明
Resource:AzurePortalで作成したリソースを選択します。無い場合は、Create Newから作成します。
ProjectTypes:Classificationを選択します。
Classification Types:Multilabel(Multiple tags per image)を選択します。
Domains:Generalを選択します。
Create projectをクリックします。
4.Training Images → Add imagesをクリックしてダウンロードしたファイルをまとめてアップロードします。
アップロード時に関連するタグを入力してUpload n filesをクリックします。
各動物ごとタグを付けてアップロードしていきます。
5.アップロードとタグ付け完了後、Train をクリックします。
Fast Training を選択し、Trainをクリックします。
※Advanced Trainingを選択するとかなり時間がかかります。
6.トレーニング完了後、QuickTestボタンより、分類したい画像をアップロードしてテストします。
99%コツメカワウソと判断されたのでOKですね。
LINE Bot との連携
1.Azure Custom Vision ServicesのPerformanceからPublishをクリックし、Prediction APIを発行する。
※下記のようなresourceなんちゃらのエラーで発行できない場合は、
ProtoOut Studio 講師長田中さん が書いたここの記事を参考にしてください。
https://protoout.studio/posts/custom-vision-project-publish-error
2.Prediction APIが表示された場合は、APIキーを控えておきます。
3.LINE BoTを作成します。
LINE Botの簡単な作り方はこちらの@n0bisukeさんの記事を参考にしてください。
https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d
4.下記のソースを参考にしてNowでデプロイすれば完成です。
Node.jsのソース
'use strict';
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const fs = require('fs');
const bodyParser = require('body-parser');
const Request = require('request');
const cv = require('customvision-api');
const config = {
channelSecret: '作成したBOTのチャンネルシークレット',
channelAccessToken: '作成したBOTのチャンネルアクセストークン'
};
const app = express();
app.use(bodyParser.json());
let middle = line.middleware(config);
const client = new line.Client(config);
app.post('/webhook', (req, res) => {
console.log(req.body.events);
if(req.body.events[0].message.type !== 'image') return;
// ユーザーがLINE Bot宛てに送った写真のURLを取得する
const options = {
url: `https://api.line.me/v2/bot/message/${req.body.events[0].message.id}/content`,
method: 'get',
headers: {
'Authorization': 'Bearer [アクセストークン]' ,
},
encoding: null
};
Request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
//保存
console.log(options.url + '/image.jpg');
let strURL = options.url + '/image.jpg';
//Nowでデプロイする場合は、/tmp/のパスが重要
fs.writeFileSync(`/tmp/` + req.body.events[0].message.id + `.png`, new Buffer(body), 'binary');
const filePath = `/tmp/` + req.body.events[0].message.id + `.png`;
//Azure Custom Vision APIの設定
const config = {
"predictionEndpoint": '[Iteration]',
"predictionKey": '[predictionKey]'
};
cv.sendImage(
filePath,
config,
(data) => {
console.log(data);
let strName = data.predictions[0].tagName;
let strTarget = "";
let strName2 = "";
let strTarget2 = "";
if (data.predictions[0].probability > 0.8) {
strTarget="だねー"
}else if(data.predictions[0].probability > 0.4){
strTarget="っぽいねー"
}else if(data.predictions[0].probability > 0.2){
strTarget="みたいだねー"
}else if(data.predictions[0].probability > 0.1){
strTarget="かな?ちょっとよくわからないねー"
}else{
console.log(data.predictions[0].tagName);
strName="なんのどうぶつか"
strTarget="わからないねー"
}
if (data.predictions[1].probability > 0.2) {
strName2='\n' + data.predictions[1].tagName
strTarget2="っぽいところもあるよねー"
}
client.replyMessage(req.body.events[0].replyToken, {
type: 'text',
text: 'これは' + strName + strTarget + strName2 + strTarget2 //実際に返信の言葉を入れる箇所
});
try {
fs.unlinkSync(filePath);
return true;
} catch(err) {
return false;
}
return;
},
(error) => { console.log(error) }
);
} else {
console.log('imageget-err');
}
});
});
(process.env.NOW_REGION) ? module.exports = app : app.listen(PORT);
console.log(`Server running at ${PORT}`);
##最後に
今回作成したLINEBotのQRコードはAzureCustomVisonを使用しているため、
金額がとんでもないことになるのが嫌なので公開しません。
興味ある方はツイッターでDMください。
2019/08/29 なんか大丈夫そうなのでQRコード追加。