[出演] ※2023/08/10追記
– NTV「ぐるナイ」システム提供、出演
– TBS「審査員長・松本人志」システム提供、出演
[受賞] ※2016/10/18追記
– 日経みんなのラズパイコンテスト2016 アイデア賞
[メディア掲載] ※2016/10/24追記
– ITpro:「みんなのラズパイコンテスト2016」受賞作品決定
– 日経ソフトウェア(2016年12月号):「みんなのラズパイコンテスト2016受賞作品発表!」
| (0) はじめに
漫画は、キャラクターやストーリーに感情移入すればするほど
面白いことは言うまでもありません。
しかし、普段、どれだけ漫画に感情移入して読んでおりますでしょうか。
漫画を読んで、嗚咽をもらしたり、地団駄を踏んだり、
胸を掻きむしる体験よりも、
満員電車の中で、死んだ魚のような目で読んでいることの方が
多いのではないでしょうか。
そこで本稿では、
RaspberryPi、Node.js、心拍センサ、Google Cloud Visionとカメラモジュールを用いて
漫画のキャラクターと読者の感情を同期させる装置”Emotion Sync System”
を作成しました。
※別エントリで記載しております「RaspberryPiとNode.jsとcreate.jsを使用した心拍数連動漫画システム」の拡張となります。
| (1) 概要
本システムは、感情を”心拍数”と”表情”の組み合わせと仮定し、
漫画のキャラクターと読者の間で、心拍数と表情がマッチするたびに
ストーリーが進行するシステムとなります。
漫画のキャラクターの心拍数と表情は、
あらかじめシーンごとに想定で設定しておきます。
一方、読者の心拍数は心拍センサを用いてリアルタイムに測定し、
読者の表情は、カメラモジュールによる撮影画像を
Google Cloud Visionで画像解析した結果を用います。
上記の処理を、RaspberryPiに接続した各種センサをNode.jsで制御し、
リアルタイムにブラウザでセンサデータを処理・可視化することで
実現しています。
| (2) 全体システム構成・用いている技術
– RaspberryPi
カメラモジュールによる読者の表情撮影、
および心拍センサによる読者の心拍数をリアルタイムに取得するために使用。
– Node.js
RaspberryPiに接続した各種モジュール・センサの制御、
および取得したセンサデータをwebブラウザにリアルタイムに送信し処理するために使用。
– Google Cloud Vision API
Googleが提供する画像認識API。今回は「FACE DETECTION」という表情判別機能を使用。
RaspberryPiのカメラで撮影した画像をNode.js経由で
GoogleCloudVisionAPIに送信し、
表情判定結果をブラウザに戻して処理。(※詳細後述)
| (3) アイデア
漫画のキャラクターの感情(心拍数、表情)に応じて、
読者を強制的に制御することは、 現状困難と思われます。
そこで、「読者が、漫画のキャラクターの心拍数、
表情に一致しない 限り、ストーリーが進まない」ことで、
”結果的に”漫画のキャラクターと読者の、心拍数、 表情が一致しながら
ストーリーが進行する、という状態を実現しています。
| (4) Google Cloud Vision APIについて
Google Cloud Vision APIは下記様々な機能があります。
TYPE_UNSPECIFIED | 指定なし |
FACE_DETECTION | 顔検出。(および表情判定) 今回使用 |
LANDMARK_DETECTION | ランドマーク認識。 |
LOGO_DETECTION | ロゴ検出 |
LABEL_DETECTION | ラベル(カテゴリ)検出 |
TEXT_DETECTION | テキスト検出 |
SAFE_SEARCH_DETECTION | セーフサーチ(不適切コンテンツ判定) |
IMAGE_PROPERTIES | 画像のプロパティ検出 |
今回使用した「FACE_DETECTION」は、画像をPOSTすると、
目や鼻の位置など様々な判定結果とともに、下記のような表情判定結果を5段階で判別して返答します。
(FACE_DETECTIONの表情判定項目)
joyLikelihood | 喜び |
sorrowLikelihood | 悲しみ |
angerLikelihood | 怒り |
surpriseLikelihood | 驚き |
(FACE_DETECTIONの表情判定結果)
UNKNOWN | 判定不可 |
VERY_UNLIKELY | とてもそうとは言えない |
UNLIKELY | あまりそうとは言えない |
POSSIBLE | ややそう言える |
LIKELY | かなりそう言える |
VERY_LIKELY | とてもそう言える |
| (5) プログラミング
以前のエントリ同様、Node.jsでRaspberryPiに接続する機器を制御しており、
GoogleCloudVisionへのカメラ撮影画像の送受信も、
Node.jsで処理しております。
Node.jsにおけるGoogleCloudVision処理には
“node-cloud-vision-api”というパッケージがありますので、
あらかじめインストールしておきます。
(※ちなみにGoogleCloudVision用Node.jsパッケージは
他にもいろいろあるようです)
1 |
npm install node-cloud-vision-api |
下記はサーバ側の処理(のうち、GoogleCloudVision関連のパート)となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
'use strict' var app = require('http').createServer(handler), io = require('socket.io').listen(app), fs = require('fs'); var SPI = require('pi-spi'); var rpio = require('rpio'); var spawn = require('child_process').spawn; var camera_image_url = '/images/raspi_camera.jpg'; const vision = require('node-cloud-vision-api'); vision.init({auth: '****'}); var gcv_json_data; app.listen(1337); function handler(req,res){ fs.readFile(__dirname + '/index.html', function(err,data){ if(err){ res.writeHead(500); return res.end('Error'); } res.writeHead(200); res.write(data); res.end(); }) } io.sockets.on('connection',function(socket){ socket.on('emit_from_client_with_camera',function(data){ //クライアントウェブブラウザからの処理依頼(撮影ボタン)を押されたら、カメラモジュールを起動させ、読者の表情撮影 var raspistill = spawn('raspistill', [ '-o' , './images/raspi_camera.jpg','-w' , '320', '-h', '240', '-t','100']); //撮影した読者の表情画像をGoogle Cloud Vision APIに送信 const req1 = new vision.Request({ image: new vision.Image('./images/raspi_camera.jpg'), features: [ new vision.Feature('FACE_DETECTION', 4), ] }); //JSONデータにして、クライアントサーバに戻す vision.annotate(req1).then((res) => { gcv_json_data = JSON.stringify(res.responses); socket.emit('emit_from_server_with_camera',gcv_json_data); }, (e) => { console.log('Error: ', e) }); }); }); |
| (6) 動作イメージ
下記のように、定められた心拍数・表情条件をみたすごとにストーリー(コマ)が進行していきます。
下記動作イメージで使用している漫画は、私個人の描き下ろし作品であります『データサイエンティストたちの黙示録』となります。
以上、今回はGoogleCloudVisionとRaspberryPiを用いた
感情連動漫画システムの紹介となりました。
GoogleCloudVisionによる顔認識は非常に高精度であり、
目、鼻、口などの位置を正確に特定できます。
一方、”笑っている”、”悲しんでいる”などの表情判定は、
おそらくグローバルな画像を元に学習しているように思われ、
日本人的には、相当オーバーな表情をしないと
判定されないという結果となりました。
かといって無闇矢鱈にオーバーな表情をしても、
その心情が掴みづらい表情はもちろん判定されません。
ただし、友人で試すと、それなりに判定されました。
もしかして、私が単体で表情が掴みづらいのか?