Inside  of  聖徳⽟玉⼦子
インフォコム技術企画室  ⼤大津
⾃自⼰己紹介
•  ⼤大津  学(おおつ  まなぶ)
–  インフォコム技術企画室所属
–  部署の活動はVR、IoT、AIなどの
先端技術の研究、調査です
•  前職はゲーム会社で開発してました
Angry  Birdsに⾊色々要素を増やしたゲーム
聖徳⽟玉⼦子とは
しゃべっている⼈人を⾃自動で表⽰示してくれる360°ビデオチャットアプリ
デモ
聖徳⽟玉⼦子構成
Dual-‐‑‒Fisheye
SocketIO
(WebSocket)
Json Json 画⾯面の分割
WebSocket
⾳音の⽅方向
Stdout
⾳音の⽅方向を定位し、
ログ出⼒力力
⾳音の⽅方向をリアルタイムで処理理
標準⼊入⼒力力のログから
⾓角度度を抽出
WebSocket  Client
WebSocketで⾓角度度を送信
並列列処理理並列列処理理
⾳音の⽅方向を⾓角度度に変換し、WebSocketで送信
リアルタイム処理理はGoの並列列処理理(Goroutine)で橋渡ししている
並列列処理理間でメッセージを送信
WebSocket  Server
package websocket
https://godoc.org/golang.org/x/net/websocket
⾳音の⽅方向
製品名「たまご型マイクアレイ」
by  システムインフロンティア
⾳音の⽅方向はハードウェアとソフトウェアで実現
8⽅方向にマイクが付いている
全⽅方位の⾳音を取得
マイクの配置には意味があり、
マイク毎に⾳音の到達時間が異異なる。
この遅延性を利利⽤用し、⽅方向を識識別する
by  ホンダ・リサーチ・インスティチュート・ジャパン
ハード ソフト
http://hark.jp
ハードウェアの認識識
USB  Audio  Class1.0に対応
ドライバを別途インストール不不要
HARKの付属ソフトウェアでは、認識識するとこのように表⽰示
AudacityのようなOSSでもマイクとして利利⽤用出来る
HARKの主な機能
⾳音源定位
各マイクに届いた⾳音から
⾳音の⽅方向を決める
⾳音源分離離
定位⽅方向の
⾳音を分離離する
⾳音声認識識
分離離⾳音声の認識識
かつどん
今回は⾳音源定位を利利⽤用
3つの主軸となる研究
HARKの設定
•  HARKの設定はブラウザから⾏行行う
•  ノードと呼ばれるパーツを配置し、
ネットワークの構成を⾏行行う
保存データは「ネットワークファイル」と呼ばれるファイルで管理理
HARK設定画⾯面
1.  マイク⼊入⼒力力
2.  ⾼高速フーリエ変換
3.  ⾳音源定位
4.  ⾳音源トラッキング
5.  出⼒力力のインターバル
6.  定位位置の表⽰示
7.  定位位置の保存
HARKの設定2
ネットワークファイルはXMLフォーマットで記述
今回はSourceTrackerのログを標準⼊入⼒力力に利利⽤用
<Node  name="node_̲SourceTracker_̲1"  type="SourceTracker"  x="410"  y="310">
        <Parameter  name="THRESH"  type="float"  value="38.5"  description=“…."/>
        <Parameter  name="PAUSE_̲LENGTH"  type="float"  value="1200"  description="…"/>
        <Parameter  name="MIN_̲SRC_̲INTERVAL"  type="float"  value="20"  description="…"/>
        <Parameter  name="MIN_̲ID"  type="int"  value="0"  description="…"/>
        <Parameter  name="DEBUG"  type="bool"  value="true"  description="…"/>
</Node>
SourceTracker
⾳音源にIDを付与し、同じ⾳音と判断すれば同じIDとして追跡する
GoでHARKの標準出⼒力力を処理理
•  GoからHARKのbatchflowコマンドを実⾏行行
cmd  :=  exec.Command(“batchflow”,  [ネットワークファイル])
stdout,  err  :=  cmd.StdoutPipe()
if  err  !=  nil  {
        log.Fatal(err)
}
if  err  :=  cmd.Start();  err  !=  nil  {
        log.Fatal(err)
}
in  :=  bufio.NewScanner(stdout)
for  in.Scan()  {
        s  :=  in.Text()
....
time:  198,  ID:  0,  x:  9.250000e-‐‑‒001  2.480000e-‐‑‒001  2.870000e-‐‑‒001,  power:  3.869943e+001,  
ID:  1,  x:  8.680000e-‐‑‒001  -‐‑‒4.050000e-‐‑‒001  2.870000e-‐‑‒001,  power:  4.168919e+001,  
ax  :=  strings.Split(val[1],  "  ")
x0,  _̲  :=  strconv.ParseFloat(ax[0],  64)
x1,  _̲  :=  strconv.ParseFloat(ax[1],  64)
radian  :=  math.Atan2(x1,  x0)
ラジアンは、アークタンジェント2で求めれる
HARKからの標準出⼒力力
(SourceTrackerのログ)
↓HARKの起動コマンド
聖徳⽟玉⼦子構成
Dual-‐‑‒Fisheye
SocketIO
(WebSocket)
Json Json 画⾯面の分割
WebSocket
⾳音の⽅方向
Stdout
ビデオソースの取り込み
let  viewer  =  document.getElementById('viewer');
…
navigator.mediaDevices.getUserMedia({video:  true,  audio:  false})
        .then(function  (stream)  {  //  success
                localStream  =  stream;
                viewer.firstChild.src  =  window.URL.createObjectURL(localStream);
…
WEBカメラからビデオソースの取り込み
<div  id="viewer"><video  id="mainView"  autoplay></video>
ブラウザに⽤用意されたAPIをコールし、
ビデオタグに反映している
映像をオブジェクトに描画
thetaview.js    ※Ricoh提供のライブラリ
https://raw.githubusercontent.com/ricohapi/video-‐‑‒streaming-‐‑‒sample-‐‑‒app/master/samples/common/thetaview.js
<script  src="three.min.js"></script>
<script  src="thetaview.js"></script>
class  ThetaViewWrapper  extends  ThetaView  {
…
}
let  viewer  =  document.getElementById('viewer');
let  thetaview  =  new  ThetaViewWrapper();
let  canvasList  =  [];
let  localStream;
navigator.mediaDevices.getUserMedia({video:  true,  audio:  false})
        .then(function  (stream)  {  //  success
                localStream  =  stream;
                thetaview.setContainer(viewer);
                viewer.firstChild.src  =  window.URL.createObjectURL(localStream);
                thetaview.start(viewer.firstChild);
…
メッシュオブジェクトに描画
映像の描画にはthree.jsとthetaview.jsを使⽤用
Dual-‐‑‒Fisheye
〜~ライブラリの中⾝身について解説〜~
描画遷移
シーンと呼ばれる空間にオブジェクトを配置する
シーンに配置オブジェクトの作成
3Dモデルの頂点マップに、
UVマップを配置し、テクスチャを貼りつける
画像参照:  https://en.wikipedia.org/wiki/UV_̲mapping
カメラの表⽰示領領域をレンダリング
カメラはメッシュオブジェクトの内側に配置
⼀一部を切切り出して投影
オブジェクトの作成
ビデオソースをテクスチャに置き換えたマテリアルを作成
_̲createGeometryでは
dual-‐‑‒fisheye⽤用の3Dモデルを作成。
計算で座標や⾯面を構成し、⾯面にUVを配置
this._̲mesh  =  new  THREE.Mesh(this._̲createGeometry(),  this._̲createMaterial(videoDOM));
画像参照:  https://en.wikipedia.org/wiki/UV_̲mapping
_̲createMaterial(video)  {  //  video:DOM
        const  texture  =  new  THREE.VideoTexture(video);
        texture.minFilter  =  THREE.LinearFilter;
        texture.magFilter  =  THREE.LinearFilter;
        return  new  THREE.MeshBasicMaterial({
            map:  texture,
            side:  THREE.BackSide,
        });
} Texture
オブジェクトの作成
円形の映像を半球体に投影
Dual-‐‑‒Fisheye
THETAの場合
this._̲mesh  =  new  THREE.Mesh(this._̲createGeometry(),  this._̲createMaterial(videoDOM));
ビデオソースを引数にメッシュオブジェクトの⽣生成
カメラの表⽰示領領域をレンダリング
this._̲scene  =  new  THREE.Scene();
this._̲scene.add(this._̲mesh);
const  w  =  this._̲container.clientWidth;
const  h  =  this._̲container.clientHeight;
this._̲camera  =  new  THREE.PerspectiveCamera(75,  w  /  h,  1,  1100);
this._̲camera.target  =  new  THREE.Vector3(0,  0,  0);
シーンにメッシュオブジェクトを配置
カメラを配置
this._̲renderer  =  new  THREE.WebGLRenderer({"canvas":  canvas});
this._̲renderer.render(this._̲scene,  this._̲camera);
カメラの表⽰示領領域をレンダリング
サブ画⾯面の描画
<body>
        <div  id="viewer"><video  id="mainView"  autoplay></video>
        <canvas  id="subView1"  class="subview"  style="left:  0%"></canvas>
        <canvas  id="subView2"  class="subview"  style="left:  25%"></canvas>
        <canvas  id="subView3"  class="subview"  style="left:  50%"></canvas>
        <canvas  id="subView4"  class="subview"  style="left:  75%"></canvas>
        </div>
</body>
ひとつのビデオソースを元にキャンバスに映像を投影
画⾯面分割のサンプルコードを⽤用意
https://gist.github.com/otmb/b2ee019a28e6d80dee141473ee22666e
SubView1
〜~SubView4
〜~どのようにカスタムしているか〜~
サブ画⾯面の描画
ひとつのシーン、ひとつのメッシュオブジェクトに対し、
複数のカメラで投影
this._̲subRenderer[i].render(this._̲scene,  this._̲subCamera[i]);
それぞれのキャンバスに描画
_̲addSubView(canvas)  {
        var  i  =  this._̲canvasNum;
        const  w  =  this._̲container.clientWidth;
        const  h  =  this._̲container.clientHeight;
        this._̲subCamera[i]  =  new  THREE.PerspectiveCamera(75,  w  /  h,  1,  1100);
        this._̲subCamera[i].target  =  new  THREE.Vector3(0,  0,  0);
        this._̲subRenderer[i]  =  new  THREE.WebGLRenderer({"canvas":  canvas});
        this._̲canvasNum++;
}
⾓角度度の切切替
カメラのrotationの変更更で描画位置を変更更
this._̲subCamera[i].rotation.y  =  [⾓角度度];
説明は以上になります
Theta  x  IoT  デベロッパー
コンテスト受賞
〇コンテスト受賞ページ
http://award.contest.theta360.com/prize1.html
〇ソースコードダウンロードページ
https://lab.infocom.co.jp/2016/08/theta.html
以上。ご清聴ありがとうございました

Inside of 聖徳玉子 by O2