以前ご紹介した、猫背を監視するWebアプリ「ねこ背検知」をv2.0.0にアップデートしました。
→ 猫背を監視するWebアプリを作った
- アプリ「ねこ背検知」: https://nekoze.mujuko.com/
- ソースコード: https://github.com/mujuko/nekozekenchi
更新内容はUIの全面刷新、そしてなんといっても ジェスチャー操作 の追加です。カメラの前で手を動かすだけで、監視の一時停止・再開、ミュートなどを操作できるようになりました。
v1から引き続き、映像は端末内で処理され、外部には送信しません。安心してお使いください。
UIを全面刷新した
以前から弊団のテーマカラーというかデザインシステムというか、そんなものを試作していまして、今回それを試行導入してみました。これについてはいずれ別記事で述べたいと思います。
また、Codexが作った、猫のようで猫じゃない謎のアイコンもちゃんとしたものに差し替え、faviconやOGP1用の画像も用意しました。これで、どこに出しても恥ずかしくないプロダクトになりました!
刷新前のUIは 前回の記事 で見られますが、見なくて大丈夫です。(って言われると見たくなりますよね?)OGPは𝕏等で「 https://nekoze.mujuko.com 」と投稿すると見ることができますよ!
ジェスチャー操作を追加した
カメラの前で以下のジェスチャーをすると、画面に進捗バーが表示され、一定時間キープすると操作が実行されます。
| ジェスチャー | ジェスチャー名 | 操作 |
|---|---|---|
![]() |
両手でT字 | 監視を一時停止 |
![]() |
ピース | 監視を再開 |
![]() |
片手でパー | 監視を終了 |
![]() |
胸の前で合掌 | 猫背基準の再調整 |
![]() |
人差し指を口元へ | ミュート |
![]() |
サムズアップ | ミュート解除 |
誤検知防止のため、ジェスチャーを一瞬認識しただけでは実行しません。停止のパーは約1.5秒、それ以外はおおむね1秒ほど保持する必要があります。操作後は、いったん手を下ろすまで次のジェスチャーを受け付けないようにしています。
ジェスチャー検知時とジェスチャー操作が確定した時には電子音が鳴るので、画面を注視していなくてもジェスチャーが効いているかが分かります。
おまけ
細かい技術の話をします。
ジェスチャー判定は分類結果とランドマークの合わせ技
手の推定には MediaPipe Gesture Recognizer を使っており、パー/ピース/サムズアップなどはGesture Recognizerが返す分類結果を利用しています。
一方で、今回使いたいジェスチャーは、それだけではそろいません。
- T字は、片方の手が縦、もう片方の手が横になり、両手が接しているか
- 合掌は、左右の手首と人差し指が胸の前で近づいているか
- ミュートは、人差し指を立てた手が口元にあるか
といった条件を、手や姿勢のランドマークから追加で判定しています。
(ダメもとで6種類のポーズを指定したらCodexが一発で動くコードを出してきたので驚愕しました。多分、典型的なポーズだったから上手くいったんだろうとは思いますが、それでも6つ全部を一発とは……)
推論をWeb Workerへ移した
姿勢とジェスチャーの推論処理をメインスレッドからWeb Workerへ移しました。
Web Workerって?
Web Workerは、JavaScriptをブラウザのメインスレッドとは別のスレッドで動かす仕組みです。
メインスレッドはUIの描画やクリックなどのイベント処理を担当していて、ここで重い処理を行うと画面がカクついたり操作への反応が遅れたりします。
Web Workerに処理を逃がしておけば、それがどれだけ重くてもメインスレッドは影響を受けません。ただしメインスレッドとWorkerの間でオブジェクトを直接共有できないため、postMessage によるメッセージのやり取り(今回はImageBitmapの転送)でデータをやり取りします。
具体的な実装
メインスレッド側ではカメラ映像から ImageBitmap を作成し、Workerへ転送します。Worker側で姿勢と手の位置・形を推定し、必要なランドマークと分類結果だけをメインスレッドへ返します。前のフレームの推論結果が返ってくるまでは次のフレームを送らないようにし、Workerへのリクエストが重ならないようにしています。
なぜそんなことを?
ジェスチャー操作を追加すると、姿勢推定に加えて手の推定をする必要もあります。つまり、以前よりも推論処理が重たくなります。
メインスレッドで重たい推論をすると、UI描画やイベント処理と競合し、ジェスチャーへの反応やボタン操作がもたつく可能性があります。
そのため、推論をWorkerへ分離し、UIやイベント処理を担当するメインスレッドからMediaPipeの実行を切り離しました。MediaPipe Tasks Visionのドキュメントでも、推論はWeb Workerで実行することが推奨されています。
…といっても、性能比較をしたわけではないので正直何とも言えません。明らかな遅延は感じていないので、上記の狙い通りに効いているといいな、というところです。
今後の展望
デスクトップアプリにするという案もありますが、多分Tauriで簡単に実現できると思うのであんまり食指が動きません……それよりは、ブラウザ拡張にするのが面白いかなぁ?
それでは皆様、明日も良い姿勢と共にあらんことを……
-
Open Graph Protocol — SNSでリンクを共有した時に表示されるプレビュー画像・タイトルの規格。 ↩






