あなたに次の選択肢を用意するサイト
Thoth Coworker
~ プログラミングの次++ ~
For
新社会人 / 新学生 / 新院生 / 新研究者
カテゴリ
Webで物体検出を動かしてみる
Facebookシェア Twitterツイート LINEで送る
P
ポイント
Webで物体検出を動かしてみる
Webで最新のDeepLearningによる画像の物体検出を簡単にやってみるための記事
  • Point 1
    ML5.jsを試用
    ML5.jsは誰でも簡単に最新の機械学習技術をブラウザで使うことができるライブラリ
  • Point 2
    CocoSSD学習済みモデルを使用
    YoloやCocoSSDがML5.jsでは選択して使用することができる.ここではCocoSSDを使った非常にシンプルなサンプルを掲載
  • Point 3
    領域とその名前を表示
    通常のスマホであらかじめ指定してある画像から物体の写っている領域とその種類を表示します.
P
ステップ概要
Webで物体検出を動かしてみる
ml5.jsを使用した簡単な物体検出プログラム(HTML+JS)を準備します.
Pythonを使って簡易的なWebサーバを立てます
実行して実際に画像上の領域の検出とその名前の表示を確認
モデルの初期化などコード全体の解説
物体検出を実行している箇所に関して解説
結果表示を行なっている箇所の解説
Step
1
物体検出プログラムを準備
今回はml5.jsの公式サンプルをベースにややアレンジして紹介しています.
: ブラウザで開く
https://github.com/ml5js/ml5-examples/tree/release/p5js/YOLO/YOLO_single_image
それでは、プログラムを用意し動かしていきます.全体の解説は追って行います.
以下のようなフォルダの構造になるように次のファイルを置いてください.
Folder : 物体検出プログラムのフォルダ
index.html
index.js
images/
cat.jpg
続いて各ファイルの中身です.
まず,index.htmlは以下のコードとなります.
HTML : canvasを載せたHTML
index.html
    
<html>
  <head>
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js" type="text/javascript"></script>
  </head>
  <body>
    <canvas id="canvas" width="640px" height="480px"></canvas>
    <img id="srcimg" width="640px" height="480px" src="images/cat.jpg">
    <script src="index.js"></script>
  </body>
</html>      
    
  
次にJavaScript側のソースコードは以下になります.
JavaScript : ML5.jsのCocoSSDによる物体検出を行う
index.js
    
let objectDetector;
let ctx;
let img = document.getElementById("srcimg");

async function init() {
    objectDetector = await ml5.objectDetector('cocossd', detect)
    ctx = document.getElementById("canvas").getContext('2d');
}

window.addEventListener('DOMContentLoaded', function () {
    init();
});

function detect() {
    objectDetector.detect(img, function (err, results) {
	if (err) {
	    console.log(err);
	    return
	}
	
	if (results) {
	    draw(results);
	}
    });
}

function draw(objects) {
    ctx.drawImage(img, 0, 0);
    for (let i = 0; i < objects.length; i++) {	
	ctx.font = "16px Arial";
	ctx.fillStyle = "green";
	ctx.fillText(objects[i].label, objects[i].x + 4, objects[i].y + 16);
	
	ctx.beginPath();
	ctx.rect(objects[i].x, objects[i].y, objects[i].width, objects[i].height);
	ctx.strokeStyle = "green";
	ctx.stroke();
	ctx.closePath();
    }
}

    
  
imagesフォルダにあるcat.jpgに関しては下記より取得ください.
cat.jpg
Step
2
Webサーバを立てる
ここではWebサーバを最も簡単な方法で立てます.
Bash : PythonでWebサーバを立てる
      
    python3 -m http.server 8000 
      
    
これで簡単なWebサーバを立てることができました.
Webサーバを立てる方法について、詳しくは「とりあえずWebサーバを立ててみる」をご参照ください.
とりあえずWebサーバを自分のパソコンに立ててみる
自分のパソコンにとりあえずシンプルなWebサーバを立ててみるためのページです.
リンク
Step
3
物体検出を実行する
それではいよいよ実行します.
下記のアドレスをブラウザのURLバーに貼り付けて開いてください.ポート番号をStep2で変えている方は適宜8000から変更してください.
: ブラウザで開く
http://localhost:8000/index.html
上記の実行によって以下のような画面が出ます
※モデルをロードしてくるため、非常に実行に時間がかかります.

猫の枠とそのカテゴリ名"cat"が表示されています
実行結果画面
Step
4
コード解説:全体概要
コード全体の解説を行います
全体構成は以下のようになっています.
サンプルコード全体構成
まずinit関数でmodelの初期化を行います.
モデルが読み込まれた後にdetect関数が呼ばれるように引数に与えています.

detect関数はimgタグに含まれる画像と読み込まれたmodelを使って実際に物体検出を行います.成功してresultsに結果が入っている場合のみ描画のdraw関数を実行します.

draw関数では検出されたobjectsに含まれる物体の結果からlabel, x, y, width, heightを取り出して通常のcanvasを描画する方法で表示します.

ml5.jsの本質的なところは、init関数detect関数のみです.
Step
5
コード解説:物体検出
まず物体検出のためのモデルをロードしているのは、以下の行です.objectDetectorの一つ目の引数がcocoSSDのモデルを使うように指定しており、二つ目の引数がモデル読み込み後に呼び出されるdetect関数.
JavaScript : 物体検出処理
    
    objectDetector = await ml5.objectDetector('cocossd', detect)
    
  
読み込み完了後にdetect関数の中で、実際に物体検出を行なっているのは以下の行です.
JavaScript : 物体検出処理
    
    objectDetector.detect(img, function (err, results) {
	if (err) {
	    console.log(err);
	    return
	}
	
	if (results) {
	    draw(results);
	}
    });
    
  
objectDetector.detect関数では、処理すべきimgタグとコールバック関数を与えています.
もし何らか物体検出で物体が検出されれば、resultsにその情報(識別結果、位置、サイズ)が格納されています
if文でresultsの結果を元に描画するかを決定しています.
Step
6
コード解説:結果表示
imgタグの画像をcanvasに描画したのちに,objectsの配列をfor文で取り出しながら描画していきます.
JavaScript : 物体検出結果の表示処理
    
    ctx.drawImage(img,0,0);
    for (let i = 0; i < objects.length; i++) {	
	ctx.font = "16px Arial";
	ctx.fillStyle = "green";
	ctx.fillText(objects[i].label, objects[i].x + 4, objects[i].y + 16);
	
	ctx.beginPath();
	ctx.rect(objects[i].x, objects[i].y, objects[i].width, objects[i].height);
	ctx.strokeStyle = "green";
	ctx.stroke();
	ctx.closePath();
    }
    
  
ctx.drawImageでimgタグの画像をcanvasに書き込み、その後のfor文を使ってラベルをテキストとして検出領域を矩形で表示しています. ここの処理はml5.jsとは関係なく通常のcanvas処理です.
Done