こんにちは、今年もやってまいりました クソアプリアドベントカレンダー2021 14日目担当の 黒神 (@kokushin) と申します。
今回で4回目の参加になります、今年もよろしくお願いします!
過去作
今回作ったもの
「映像内で「🖕(中指を立てる)」動作をした際に、自動的に指の先端にモザイク処理を入れてくれる」クソアプリをつくりました。
デモ:
クソみたいな仕草に対して、クソ役に立たない機能を実現した、正真正銘のクソアプリです。
使った技術
映像内の手の形を検出するために、ml5.jsという機械学習系のライブラリのHandposeを利用しています。
軽量かつ高速で動作し、検出精度もなかなか高かったので驚きました。クライアントサイドで完結して組み込めるのは本当にラクで良いですね。
映像とモザイクの描画にはp5.jsを利用しました。初めて使ったのでガッツリコード書いたわけではありませんが、メソッドなど直感的なものが多く非常に扱いやすい印象でした。
公式で提供されているWeb Editorも使いやすかったです。
実装
とりあえず中指の検出から行いました。
Handposeは手を検出すると、オブジェクト形式で座標を返してくれます。
[
{
handInViewConfidence: 1, // The probability of a hand being present.
boundingBox: { // The bounding box surrounding the hand.
topLeft: [162.91, -17.42],
bottomRight: [548.56, 368.23],
},
landmarks: [ // The 3D coordinates of each hand landmark.
[472.52, 298.59, 0.00],
[412.80, 315.64, -6.18],
...
],
annotations: { // Semantic groupings of the `landmarks` coordinates.
thumb: [
[412.80, 315.64, -6.18]
[350.02, 298.38, -7.14],
...
],
...
}
}
]
指の種類や関節毎に検出することが可能なので、今回は中指の第2関節より先が伸びていれば「🖕」という状態である...と判定しています。
for (let i = 0; i < predictions.length; i += 1) {
const prediction = predictions[i]; // ここにHandposeの検出結果が格納される
if (prediction.annotations.middleFinger[3][1] < prediction.annotations.middleFinger[2][1]) {
const x = prediction.annotations.middleFinger[3][0] - (size / 2);
const y = prediction.annotations.middleFinger[3][1] - (size / 2);
// モザイクを描画
// ...
}
}
あとは、取得した関節の座標に対してモザイクを描画してあげるだけです。p5.jsの loadPixels
メソッドを利用すれば、簡単にcanvas内のイメージをpixelの配列で取得することができます。便利!
モザイクのドット描画をもっと細かくやりたかったのですが、計算式を考えるのに時間を費やしそうだったので今回はクソデカ1ドットにしています。
普段からもっと触っていればよかった...
あとがき
今年もクライアントサイドで動作する機械学習系のライブラリを使って遊んでみました。クソアプリアドベントカレンダーは普段触らない技術やアイデアを扱えるのでやはり楽しいですね。
今回のクソアプリはデバッグの際、Macに対して中指を立てまくったので、周りの人からやべーやつだと思われていないかだけ一点心配です。
お疲れさまでした!