Open6
ブラウザだけで指数えを検出
ブラウザで簡単機械学習できるml5js
ml5jsはProcessing出身の自分からしてみると、光ですね
もっと皆に知ってほしいライブラリです!
tensorflow.jsも触ったけど、やっぱり記述が多い
ただ、やはり新しいものなので機能がなかったり、記述のルールが機能によって違ったりするので、そこらへん注意ですね。
handposeで手の骨格を取得
handpose(https://learn.ml5js.org/#/reference/handpose)って前あったっけ?
すごくよくできてるので使ってみる
単眼で、しかもブラウザだけで3Dデータとして取得できるのは少し前から考えるとすごいですね
取得結果のjsonデータの中身を見てみる
[
{
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],
...
],
...
}
}
]
landmarks内に3Dデータが入ってますね
多分、x軸、y軸、z軸という順で2次配列ができていると予想できますね
ただ、第一階層目のどこの指のどの関節なのかがわからないので、確認するコードを作ってみます
指数えを取得してみる
指で表す数字のことですね。
結果、右手限定にしてみることで正確にとれているように見えます。
アルゴリズムは各指の付け根から先端までの角度を…とか考えたけど…簡略化したらもっと正確のように見えるとれかたしました
以下コードの一部
function getFingerNumber(hand) {
const annotations = hand.annotations;
let number = 0;
// 右手限定
// 親指が立っているかどうか
if (annotations.thumb[3][0] > annotations.thumb[2][0]) {
number++;
}
if (annotations.indexFinger[3][1] < annotations.indexFinger[2][1]) {
number++;
}
if (annotations.middleFinger[3][1] < annotations.middleFinger[2][1]) {
number++;
}
if (annotations.ringFinger[3][1] < annotations.ringFinger[2][1]) {
number++;
}
if (annotations.pinky[3][1] < annotations.pinky[2][1]) {
number++;
}
return number;
}
先端が、第一関節よりY座標が低かったら曲げてるということにしてます。
右手限定というのは、親指だけX座標で考えているだけです。(手のひらに近い、とかでもいいですけども…)
角度計算のものが、小指だけなんか正確じゃなくて…とくにZ座標が。
なので2DでY座標しか見ないようになってます。
なので、手のひらを逆さまにしたり、角度によって全然正確じゃないです。が、まぁいったんいいでしょう!