こんにちは、東京アプリケーションシステム第三ソリューション部のW.F.です。
今回はml5.js、p5.jsを用いてWeb上から物体検出を行ってみます。
jsに触れたのがほぼ初めてということもあり、まずはp5.js・ml5.jsとは何者なのか調べてみました。
p5.jsとは
ProcessingをJavaScriptで書けるようにしたライブラリだそうで、Web上で描画機能を実装できるようになります。
使用方法については、setup関数とdraw関数の2種類の関数が用意されており、
setup関数は実行開始時に1回、draw関数は1秒に一回実行される関数になります。
これら2つの関数を用いて描画を行うことになります。
ml5.jsとは
https://ml5js.org/
より日本語訳してみると「このライブラリは、他の外部依存関係を持たずに TensorFlow.js 上に構築され、ブラウザーで機械学習アルゴリズムとモデルへのアクセスを提供します。」と書いてあります。つまり、Web上で機械学習を扱うことができるようになるライブラリですね。使える機能は上記URLの左側Reference欄にいろいろと載っていました。今回はその中のobjectDetectorを用いていきます。
動作
さっそく本題になりますが、今回の物体検出では上で記載した通りml5.js-objectDetectorを使用します。
物体検出に使用するモデルは、YOLOとCOCOSSDの2種類あるみたいですが今回はCOCOSSDを使用してみます。
コードは公式のサンプルソースをもとに作成してみました。(ほぼほぼ一緒ですが…)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Object Detection using COCO-SSD</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script> <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js" type="text/javascript"></script> </head> <body> <h1>Object Detection using COCO-SSD</h1> <script src="sketch.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
let video; let detector; let detections = []; function setup() { createCanvas(640, 480); video = createCapture(VIDEO, videoReady); video.size(640, 480); video.hide(); } function videoReady() { // Models available are 'cocossd', 'yolo' detector = ml5.objectDetector('cocossd', function () { detector.detect(video, gotDetections) }); } function gotDetections(error, results) { if (error) { console.error(error); } detections = results; detector.detect(video, gotDetections); } function draw() { image(video, 0, 0); if(detections) { for (let i = 0; i < detections.length; i += 1) { const object = detections[i]; stroke(0, 255, 0); strokeWeight(4); noFill(); rect(object.x, object.y, object.width, object.height); noStroke(); fill(255); textSize(24); text(object.label, object.x + 10, object.y + 24); } } } |
映像ではなく画像で分かりづらいですが、以下画像は私の顔で試してみたものです。
モザイクをかけるため判定枠内をオレンジで塗りつぶしてありますが、私の顔で「Person」と表示されており正常に判定されていることが分かります。
各処理について
各処理について軽く補足します。
html
・p5.jsとml5.jsをCDNから読み込む。
こちらの記述を記載することで使用できるようになります。
1 2 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script> <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js" type="text/javascript"></script> |
js
以下p5.jsで使用している関数の処理の詳細についてはこちらをご覧ください。
・描画する範囲の設定・カメラの設定を行う。
createCanvasで描画する範囲の設定を行い、createCapture以降の行でカメラの設定を行います。
1 2 3 4 |
createCanvas(640, 480); video = createCapture(VIDEO, videoReady); video.size(640, 480); video.hide(); |
・学習済みモデルの読み込み
YOLOとCOCOSSDの2種類指定でき、objectDetectorの引数に指定することで使用できます。
YOLOでも試してみましたが、COCOSSDよりも判定が不安定に感じました。
1 2 3 |
detector = ml5.objectDetector('cocossd', function () { detector.detect(video, gotDetections) }); |
・判定結果の取得
エラーがあればエラー内容をログに出力し、取得結果を変数detectionsに保持します。
1 2 3 4 5 |
if (error) { console.error(error); } detections = results; detector.detect(video, gotDetections); |
・取得結果を描画する
上記処理後、detectionsに結果が格納されていれば取得結果を画面に描画します。
rect()で判定している範囲を長方形の枠で描画、text()で判定した物体の種類を表示しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
if(detections) { for (let i = 0; i < detections.length; i += 1) { const object = detections[i]; stroke(0, 255, 0); strokeWeight(4); noFill(); rect(object.x, object.y, object.width, object.height); noStroke(); fill(255); textSize(24); text(object.label, object.x + 10, object.y + 24); } } |
最後に
最後までお読みいただきありがとうございました。
Pythonで画像分析をしたことはありましたが、jsだけで画像分析ができることは今回初めて知りました。
ml5.jsでは今回紹介した物体検出を行うobjectDetector以外にも、人間のポーズを検出し目や耳など体にパーツを検出できるPoseNetであったり、SoundClassifierやPitchDetectionをうまく用いれば音楽も生成できたりと、とても興味深いライブラリでした。
今後ほかの機能も試してみてご紹介できればと思います。