機械学習「Face-Api」を使って、顔パーツにピカチュウを表示する
機械学習(Face-Api)
数日前に「機械学習」を習ったので、ポケモンネタで何かを作ろうと試行錯誤した話です。
"モンスターボールから、ピカチュウが飛び出してくるイメージ"のものを作ろうとしたのですが、果たしてどのモデルで実現できるのかが分からず・・・。
そこで、試しにml5.jsの「Face-Api」を使ってみました。
結果、無事にピカチュウは表示できたものの、イメージどおりにはなりませんでした・・・。
ですが、いつか使える日が来るかも?と思い、ちょっとおもしろかったので記事にしておきます。
試作品
両目の位置が特定されると、その上にピカチュウが表示されます。(何だかイメージしてたのと違う・・・)
ピカチュウ画像は、PokeAPIから取ってきたものをイメージファイルとして呼び出しています。
ソースコード
作成にあたっては、以下の記事を大変参考にさせていただきました。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ピカチュウeyes</title>
</head>
<body>
<h1>ピカチュウeyes</h1>
<!-- CDNの読み込み -->
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script> -->
<script>
let faceapi;
let video;
let width = 640;
let height = 480;
let ctx;
let img;
// Face-Apiのオプション設定
const detection_options = {
withLandmarks: true,
withDescriptors: false,
}
// メイン処理
async function make(){
img = new Image();
img.src = 'https://cdn-ak.f.st-hatena.com/images/fotolife/K/Kokano23/20210508/20210508184830.png';
video = await getVideo();
let canvas = createCanvas(width, height);
ctx = canvas.getContext('2d');
// faceapiモデルのオブジェクト生成
faceapi = await ml5.faceApi(video, detection_options, modelReady)
}
// DOMの読み込み
window.addEventListener('DOMContentLoaded', function() {
make();
});
// Face-Apiモデルの読み込み
function modelReady() {
console.log('ready!')
faceapi.detect(gotResults)
}
// Face-Api呼び出し関数
function gotResults(err, result) {
if (err) {
console.log(err)
return
}
// 自分の映像の情報を取得
let detections = result;
// 描画キャンパスを初期化
ctx.fillStyle = "#000000"
ctx.fillRect(0,0, width, height);
ctx.drawImage(video, 0,0, width, height);
// 自分の映像に描画する処理
if (detections) {
if(detections.length > 0){
drawLandmarks(detections)
}
}
// Face-Apiの再呼び出し
faceapi.detect(gotResults)
}
// Face-Apiで取得した目の位置を特定する処理
function drawLandmarks(detections){
for(let i = 0; i < detections.length; i++){
const leftEye = detections[i].parts.leftEye;
const rightEye = detections[i].parts.rightEye;
// 目に画像を描画
ctx.drawImage(img, leftEye[0].x -10, leftEye[0].y -25, 50, 50);
ctx.drawImage(img, rightEye[0].x -10, rightEye[0].y -25, 50, 50);
}
}
// Helper Functions
async function getVideo(){
// 要素の取得、設定の作成など
const videoElement = document.createElement('video');
videoElement.setAttribute("style", "display: none;");
videoElement.width = width;
videoElement.height = height;
document.body.appendChild(videoElement);
// Webカメラのキャプチャを作成
const capture = await navigator.mediaDevices.getUserMedia({ video: true })
videoElement.srcObject = capture;
videoElement.play();
return videoElement
}
// キャンパスの作成
function createCanvas(w, h){
const canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
document.body.appendChild(canvas);
return canvas;
}
</script>
</body>
</html>
最後に
- 本当にやりたいのは、「Teachable Machine」で機械学習したモンスターボールを検知した場合、モンスターボール上にピカチュウを表示させることです。
- 上記を実現するには、「Handpose」を使って、モンスターボールを持つ手の関節にピカチュウを表示させる、という方法がよさそうです。(実現できたら、別記事にする予定です)
- 今回の試作品は、想像していたものとは大分違ったのですが、これはこれで子どもに「おもしろい!」と言ってもらえました。
- 試しにマスクを着用してみたところ、うまく座標位置が認識されませんでした。(勉強になりました)
- ポケモン好きのお子さんがいらっしゃる方など、ぜひ遊んでみてください!
Author And Source
この問題について(機械学習「Face-Api」を使って、顔パーツにピカチュウを表示する), 我々は、より多くの情報をここで見つけました https://qiita.com/kokano23/items/e226dd746f43dc34d9b8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .