Scratch Lab の Face Sensing のお試し（公式の顔認識の仕組み）＋追記

この記事は、以下のツイートで知った Scratch Lab で新しく提供されはじめた新ブロック、その 2種類あるうちの「Face Sensing Blocks」のほうを試してみた話について書いています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">さきほど、Scratch Labが公開されました。これは、新しい機能を追加する前に、それらを実際に動かして実験するための場所です。現時点では、Animated Text BlocksとFace Sensing Blocksが用意されています。日本語など他の言語への対応はまだ行われていませんが、使い方はなんとなくわかると思います。 <a href="https://t.co/W1sofdpRUP">https://t.co/W1sofdpRUP</a></p>&mdash; アベ先生 (CV: 阿部和広) (@abee2) <a href="https://twitter.com/abee2/status/1356625295478988800?ref_src=twsrc%5Etfw">February 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 2種類の新ブロックについて
冒頭のツイートで、引用ツイートされていた文章の中に、以下の URL が含まれていました。

●Scratch Lab: Extending Creative Possibilities and Play | by The Scratch Team | Feb, 2021 | Medium
　https://medium.com/@scratchfndn/scratch-lab-extending-creative-possibilities-and-play-5b131cc4d9de

そしてページを開くと、いろいろと画像や説明などが掲載されていました。
![Scratch Lab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9743bf91-1221-eb08-b722-7369422346aa.jpeg)

中を見ていくと、テキストアニメーション用の「Animated Text Blocks」と、顔認識を使う仕組みになっている「Face Sensing Blocks」を試すためのエディタへの導線もありました。

●Animated Text - Scratch Lab
　https://lab.scratch.mit.edu/text/

●Face Sensing - Scratch Lab
　https://lab.scratch.mit.edu/face/

今回は、Face Sensing のほうを試しています。

### Animated Text
今回の記事には出てこないほう、テキストのアニメーションを実現するためのものです。

https://lab.scratch.mit.edu/text/
![Animated_Text_-_Scratch_Lab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2f4a8b87-5b6b-d0ad-b65f-34a7cfe203d4.jpeg)

### Face Sensing
今回の記事でとりあげる、顔認識を使った仕組みのページは以下になります。

https://lab.scratch.mit.edu/face/
![Face_Sensing_-_Scratch_Lab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9b963e12-61f4-1d5d-a93d-4a07f3f27d18.jpeg)

「Try it out」と書かれたボタンを押すと、エディタへと移動できます。
エディタを開くと、以下のようなブロックが用意されているのを確認できました。
![Face Sensing のブロック.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/01029b23-50af-7735-4ddf-cf2aa24dd433.jpeg)

内容を見てみると、以下のような仕組みを利用できるようです。

* スプライトを顔の特定の部分（鼻、頭の上、など）へ移動させる
* スプライトの向きを顔の傾きに合わせる
* 顔の大きさ（※顔がカメラに大きくうつっているか、小さくうつっているかに影響を受ける）にあわせてサイズを変える
* 顔が左右のどちらかに傾いた時を検知
* スプライトが顔の特定の部分に触れたことを検知
* 顔が検出されたことを検知
* 顔が検出されているかどうかのフラグ
* 顔の傾きの数値
* 顔のうつっている大きさの数値

#### 作成したプログラム
今回のお試しでは、以下の機能のものを使ってみました。

* スプライトを顔の特定の部分（鼻、頭の上、など）へ移動させる
* スプライトの向きを顔の傾きに合わせる
* 顔が左右のどちらかに傾いた時を検知
* スプライトが顔の特定の部分に触れたことを検知

組んだブロックのプログラムは以下のとおりです。
![ブロックのプログラム.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ae7e7ed1-ca42-6496-f4aa-5848bf30bd69.jpeg)

#### 実行結果
上記のブロックのプログラムを実行した結果は以下のとおりで、次のような挙動を確認できると思います。

* ネコのスプライトが口に触れた時、画面のどこかに移動する
* 顔が右に傾いた時に、ネコのスプライトが頭の上に移動する
* 緑の旗を押した後は、ネコのスプライトの傾きが、顔の傾きに合わせて変わる

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/abee2?ref_src=twsrc%5Etfw">@abee2</a> さんが投稿されていた Scratch Lab の件、テキストアニメーションと顔の認識を使うものの2つがあるうち、顔の認識を使うほうを試してみました。<br>まずはサクッと試すために、実装した仕組みは3つ（使用ブロック7つ）です。<a href="https://twitter.com/scratch?ref_src=twsrc%5Etfw">@scratch</a> <a href="https://twitter.com/hashtag/ScratchLab?src=hash&amp;ref_src=twsrc%5Etfw">#ScratchLab</a> <a href="https://t.co/UYJjpVDeRw">pic.twitter.com/UYJjpVDeRw</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1356803736123756544?ref_src=twsrc%5Etfw">February 3, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 追記
### Face Sensing の別パターン
さらに別パターンとして、頭の上の部分を広く当たり判定にするような仕組みを作ってみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/abee2?ref_src=twsrc%5Etfw">@abee2</a> さんが投稿されていたScratch Labの件、またFace Sensingを使ってみました。<br><br>動画の途中で当たり判定の部分を見えるようにしてますが、適当な矢印みたいな線を描き足したものがあり、それを顔の傾きや顔とカメラの距離の変化に合わせ、傾きや大きさが変わるようにしています。<a href="https://twitter.com/hashtag/ScratchLab?src=hash&amp;ref_src=twsrc%5Etfw">#ScratchLab</a> <a href="https://t.co/Rgy6JBhSEl">pic.twitter.com/Rgy6JBhSEl</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1358812399571251200?ref_src=twsrc%5Etfw">February 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Face Sensing で常に頭の部分（「top of head」と指定する部分）に移動するようにしているボールのスプライトがあり、そのスプライトに手描きで線を描き足してます。
また、その線を含むスプライトの向きや大きさが、頭の傾きや、顔とカメラの距離（顔がうつる大きさ）に合わせて変わるようにしてます。

頭の部分に移動しているスプライトの、ブロックのプログラムはこんな感じです。

![Face_Sensing_-_Scratch_Lab.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e9d9e3e4-26e6-7049-3830-afac2e5a0374.jpeg)

大きさを計算する部分は、以下のようなことをやって決めました。

1. 顔とカメラの距離を、近づけたり遠ざけたりする
2. 特定の距離にした状態で、スプライトの大きさの値を手動で変えて、ちょうど頭の上のサイズと同じになりそうな値を記録する
3. 上記2 の状態で、変数 face size の値を合わせて記録する
4. 上記2 と上記3 の値のペアを 2つか 3つとってみて、その値におおよそ当てはまりそう計算式を見つける（とりあえず、一次方程式にあてはめてみて、ざっくりな値を決めました）

顔の傾きは、変数の face tilt をそのままスプライトの傾きにすればちょうど良い感じでした。