AIを活用したWebアプリ②・顔検出
p5.js
前回はml5.jsとjQueryを組み合わせた 画像分類 のWebアプリを作成しました. 今回はml5.jsで推奨されているp5.jsを組み合わせて 顔検出 のWebアプリを作成しましょう. p5.jsはプログラミング1で 取り組んだProcessingのJavaScript版です. Processingと同様にキャンバスに自由に図形やアニメーションを描画できます. 専用のオンライン・エディタもあるので, 自由に試してみると良いでしょう.
CodePenの準備
CodePenにアクセスして,Penを作成し,タイトルを設定しましょう. Penのタイトルは「Chapter11」に設定しましょう.
p5.jsと前回利用したml5.jsを導入しましょう. p5.jsのCDNはCodePenで検索すれば良いです.
https://unpkg.com/ml5@latest/dist/ml5.min.js
顔検出
ml5.jsとp5.jsを 組み合わせて 顔検出 にチャレンジします. ここでは,下記の画像(face.jpg)に対して顔検出を適用してみます. 事前にダウンロードしておきましょう.
HTMLに下記のコードを入力してください.
今回はp5.jsを利用するため,h1
でタイトルのみを記述します.
<h1>顔検出</h1>
ml5.jsの顔検出はface-api.jsを利用しています. ただし,表情(expression),年齢(age),性別(gender)の検出はできません.
最初に検出オプションを設定します.
withLandmarks
をtrue
に設定すると68点のランドマークを検出します.
また,withDescriptors
をtrue
に設定すると128次元の特徴ベクトルを抽出します.
ここでは,ランドマークのみを検出します.
ファイル選択ダイアログはcreateFileInput()
で生成します.
ファイルを選択するとhandleFile()
が呼び出されます.
選択されたファイルのデータfile.data
から画像img
を生成します.
顔検出器を生成するにはml5.faceAPI()
を利用します.
第一引数は検出オプションoptions
,第二引数はモデルがロードされたタイミングで実行されるmodelReady()
を設定します.
画像をimage()
でキャンバスに描画した後で,顔検出をdetectSingle()
で実行します.
第一引数は対象の画像img
,第二引数は検出結果を処理する無名関数を設定します.
無名関数の引数は,エラーに関する情報を含むerror
と,分類結果を含むresults
です.
このresults
はJSON形式であることに注意してください.
検出された輪郭のデータはresults["detection"]
,
ランドマークのデータはresults["landmarks"]
に格納されています.
輪郭はrect()
でキャンバスに四角形として描画し,
ランドマークはcircle()
でキャンバスに円として描画します.
let input;
let img;
let faceapi;
// 検出オプション
let options = {
withLandmarks: true,
withDescriptors: false
};
// 初期化
function setup(){
input = createFileInput(handleFile); // ファイル選択ダイアログ
createCanvas(600, 400); // キャンバス
rect(0, 0, width, height); //枠線
}
// ファイル選択後の処理
function handleFile(file){
if (file.type === 'image') {
img = createImg(file.data, '');
img.hide();
faceapi = ml5.faceApi(options, modelReady); // 顔検出
}
}
function modelReady(){
// 画像をキャンバスに描画
image(img, 0, 0, width, height);
// 顔検出
faceapi.detectSingle(img, (error, results) => {
// 輪郭
let x = results["detection"]["_box"]["_x"];
let y = results["detection"]["_box"]["_y"];
let width = results["detection"]["_box"]["_width"];
let height = results["detection"]["_box"]["_height"];
noFill(); // 塗りつぶしなし
stroke("#ff0000"); // 線の色
rect(x, y, width, height); // 四角形を描画
// ランドマーク
let landmarks = results["landmarks"]["_positions"];
for(let landmark of landmarks){
let x = landmark["_x"];
let y = landmark["_y"];
fill("#00ff00"); // 塗りつぶしの色
noStroke(); // 線なし
circle(x, y, 5); // 円をキャンバスに描画
}
});
}
アプリの確認
See the Pen Chapter11 by Naoto Mukai (@nmukai) on CodePen.
課題
検出された顔の位置に画像を表示させることで,女性に お面 を被せてください.
p5.js で画像を読み込むには下記のように記述します.
let mask;
function preload(){
mask = loadImage("https://assets.codepen.io/4660782/mask.png");
}
課題を完成させたら,Penの ZIPファイル と リンク を提出してください. 提出方法は初回のWebアプリの開発を参考にしてください.