JavaScriptで実行できるというとんでもない ディープラーニングライブラリ TensorFlow.js が公開されたので試してみました。
この記事では、学習とかは置いといてとりあえず公式で配布されている人間の姿勢推定の機械学習モデル PoseNet Model を使ってみようと思います。
JavaScriptだけでディープラーニングを実行できるなんてすごい時代になりましたね。
準備
CDNからTensorFlow.js本体と、学習モデルを読み込みます。
<!-- Load TensorFlow.js --> <script src="https://unpkg.com/@tensorflow/tfjs"></script> <!-- Load Posenet --> <script src="https://unpkg.com/@tensorflow-models/posenet"></script>
以上。
ドキュメントによると、これで使えるようになったので、画像を読み込ませればいいようです。
<img id="cat" src="/images/cat.jpg " /> <script> var imageScaleFactor = 0.5; var outputStride = 16; var flipHorizontal = false; var imageElement = document.getElementById('cat'); posenet.load().then(function(net){ return net.estimateSinglePose(imageElement, imageScaleFactor, flipHorizontal, outputStride) }).then(function(pose){ console.log(pose); }) </script>
すると、推定された人物の姿勢の座標とスコアがオブジェクトで返ってきます。
keypoints: Array(17) 0: { part: "nose" position: {x: 559.4002674138435, y: 141.08637113206584} score: 0.9950814843177795 } 1: { part: "leftEye" position: {x: 566.9908806631498, y: 124.27595203791105} score: 0.9906600713729858 } 2: { part: "rightEye" position: {x: 546.6160900080315, y: 131.975860902721} score: 0.9881068468093872 } 3: {score: 0.9263632297515869, part: "leftEar", position: {…}} 4: {score: 0.9380532503128052, part: "rightEar", position: {…}} 5: {score: 0.9954990744590759, part: "leftShoulder", position: {…}} 6: {score: 0.987337589263916, part: "rightShoulder", position: {…}} 7: {score: 0.9554400444030762, part: "leftElbow", position: {…}} 8: {score: 0.9726150035858154, part: "rightElbow", position: {…}} 9: {score: 0.9837473034858704, part: "leftWrist", position: {…}} 10: {score: 0.9540407061576843, part: "rightWrist", position: {…}} 11: {score: 0.9856992363929749, part: "leftHip", position: {…}} 12: {score: 0.9832989573478699, part: "rightHip", position: {…}} 13: {score: 0.925571084022522, part: "leftKnee", position: {…}} 14: {score: 0.9708266258239746, part: "rightKnee", position: {…}} 15: {score: 0.7345849871635437, part: "leftAnkle", position: {…}} 16: {score: 0.7921262979507446, part: "rightAnkle", position: {…}}
実際につかってみる
顔のパーツ(nose, leftEye, rightEyeなど)の位置も推定できるようなので、練習がてらつくってみました。
読み込んだ画像の顔に目線を入れるテスト( https://arrival-quality.com/lab/tensorflow-looking/ )
人工知能(TensorFlow.js と Pose Net Model)を用いて、読み込んだ画像の顔に目線を入れるというもの。
動画やカメラで取得した映像をリアルタイムで解析できるみたいですが、今回は静止画に対してやってみます。
[姿勢推定ドット表示] のチェックをいれれば、推定されたパーツの位置を表示できます。
スマホでも動きますがパフォーマンスは悪いです。大きな画像だとブラウザがクラッシュするので、PC以外は画像を縮小する処理を挟んでからTensorFlowに投げているため、PCとスマホで結果が異なる場合があります。
目線の入れる位置と大きさの求め方
顔のパーツの位置がわかったので、いい感じに目線を引いてみましょう。
耳と目の位置から目線を引く場所を求めます。
人間の目は両耳の間に1:1:1:1くらいで配置されているはずなので、左耳から右耳の距離を目線の横幅として、両目の中点を中心に書くといい感じの目線になりました。
所感
学習モデルの精度や端末のスペックなどの影響は大きいですが、 TensorFlow.js + PoseNet では動画をリアルタイムで解析できる程度の処理はできるようなので、それをブラウザで、JavaScriptで動かせるというのはいろんな可能性を感じさせます。
PoseNet も立ち位置や向きさえ気をつければいい感じの精度になるので、決まった位置で動いてもらえば、たとえばキャラクターを動かしたりするゲームとかに使えるんじゃないでしょうか。
これまでもJavaScriptによる画像解析はありましたが、ディープ・ラーニングと学習モデルで、より正確でより速い解析ができるようになりそうです。
今回試しにつくったものはCodepenにも置いてます。
See the Pen TensorFlow.js と PoseNet Model by Satoshi Yoshida (@aq_yoshida) on CodePen.