ブラウザ上からのDARKNET(YOLO)による認識ラベル画像出力
目次
ブラウザ上からのDarknet(YOLO)による認識ラベル画像出力をやってみた。
- Darknet(YOLO)による認識ラベル付与済み画像を、ブラウザをインターフェイスとして生成したい(以下の画像を参考)(Python)
- 環境としてWindows Subsystem on Linux(WSL)のUbuntuを用いる。ブラウザはChromeとする(ほかのブラウザでも可)
Darknetの導入
- まずdarknetを導入する。以下のコマンドで導入できる:
git clone https://github.com/pjreddie/darknet
cd darknet
make
- 次に学習済みモデルをダウンロードする。以下のコマンドでできる:
wget http://pjreddie.com/media/files/yolo.weights
Node.jsの導入
- サーバとしてjsが必要になるので、まずはNode.jsと、Node.jsのパッケージマネージャであるnpmをインストールする。Ubuntuなら以下のコマンドで導入できる。OSによっては「nodejs」が単に「node」のこともある
sudo apt-get install nodejs npm
- 次に適当なディレクトリ(フォルダ)を作り、作業ディレクトリとする。このディレクトリに入り、以下のコマンドを実行してnodejsプロジェクトとして初期化する。いくつかのことを尋ねられるが全部そのままEnterでよい
npm init
- js上のサーバサイドフレームワークであるExpressと、ファイルアップロードを補助するライブラリmulterを導入する。以下のコマンドで導入できる:
npm install express multer –save
サーバとウェブページの作成
- jsというファイルを作り、以下のコードを貼り付ける。詳しくはコード中のコメントを参照
‘use strict’;
const execSync = require(‘child_process’).execSync;
const express = require(‘express’);
const multer = require(‘multer’);
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, ‘./’);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const upload = multer({storage: storage});
const app = express();
app.use(express.static(__dirname));
// darknetを導入したディレクトリ。
// 今回はホームディレクトリ直下
const dnDir = ‘~/darknet’;
// HTMLを表示
app.get(‘/’, (req, res) => res.sendFile(‘./index.html’));
// 画像アップロードをPOSTで受け付け
app.post(‘/’, upload.single(‘input-img’), (req, res) => {
console.log(`[done] Image upload`);
console.log(req.file);
// darknetを導入したディレクトリに移動し、
// darknetを実行する。するとpredictions.pngというファイルが出力されるので、
// それをウェブサーバのディレクトリまでコピーしてくる
//
// 注意:この方法だと複数のユーザから同時にアップロードされた場合対応できないので
// 別の方法を考える必要がある。
execSync(`(cd ${dnDir} && ./darknet detect cfg/yolo.cfg yolo.weights ${__dirname}/${req.file.filename} && cp predictions.png ${__dirname}/predictions.png)`);
console.log(‘Darknet done.’);
// 画像ファイルのパスをJSONで返す
res.type(‘application/json’);
res.send(JSON.stringify({
“path”: “predictions.png”
}));
res.end();
});
// listenを開始する
app.listen(3000);
- 次にブラウザ側のインターフェイスとなるhtmlを用意する。Inde.htmlに以下のコードを貼り付ける。詳しくはコード中のコメントを参照
<!DOCTYPE html>
<html lang=”ja”>
<head>
<meta charset=”UTF-8″>
<title>Darknet Web</title>
<style>
.result-img {
max-width: 50vw;
}
</style>
</head>
<body>
<form method=”post” action=”./” enctype=”multipart/form-data”>
<input id=”input-file” type=”file” name=”input-img” accept=”image/*”>
<input id=”submit-button” type=”submit” value=”送信”>
</form>
<progress id=”progress-bar” style=”display: none”></progress>
<img class=”result-img”>
<script>
const submitBtn = document.querySelector(‘#submit-button’);
const progBar = document.querySelector(‘#progress-bar’);
const resultImg = document.querySelector(‘.result-img’);
// submitボタンがクリックされたら
submitBtn.onclick = (evt) => {
// ブラウザデフォルトの挙動をキャンセルする
evt.preventDefault();
// プログレスバーを表示する
progBar.style.display = ‘inline’;
// 情報をfetchするためのヘッダとボディを作成する
const headers = { ‘Accept’: ‘application/json’ };
const body = new FormData();
body.append(‘input-img’, document.querySelector(‘#input-file’).files[0]);
// Fetch APIを利用してサーバに画像を送り返答を待つ
// Fetch APIの詳しい利用方法は以下のURLを参照
// https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
fetch(‘./’, {method: ‘POST’, headers, body})
.then(response => response.json())
.then((result) => {
// 帰ってきたJSONに画像のパスが含まれているので
// それをimg要素にセットする
const path = result.path;
resultImg.src = path;
// プログレスバーを非表示にする
progBar.style.display = ‘none’;
});
};
</script>
</body>
</html>
起動と動作確認
- ここまでできたら、以下のコマンドでサーバを立ち上げる:
nodejs app.js
- サーバが立ち上がったらブラウザで http://localhost:3000/ にアクセスする
- あとはブラウザ上から画像を送信して、処理が終わるまでしばらく待てば認識ラベルがついた画像が表示される。
株式会社アプリズムは
大手メーカー様の先端技術研究部署(Research and development、R&D)と連携し、
研究開発(システム開発)を行っており、お客様の企業価値向上の原動力として、
競争優位性を生み出す技術を開発します。
注力する領域として「IoT、AI/人工知能、機械学習」と定め、
アプリズムの強みを持つ技術を生かし、
さらに進化させることにより、研究開発の方向性を示すことで、
より良い暮らしと社会を実現していきます。
株式会社アプリズム
〒541-0053 大阪市中央区本町4-5-18 本町YSビル3F