http://goo.gl/O2YkkJ
「マンガテレビ」の
作り方
第41回 HTML5とか勉強会
2013.8.26 こまつけんさく
http://goo.gl/O2YkkJ
自己紹介
 こまつけんさく
 NTTコミュニケーションズ
 最新Web技術の研究開発
 html5j スタッフ
 Google Developers Expert (HTML5)
 Micr...
http://goo.gl/O2YkkJ
「マンガテレビ」?
https://app.html5experts.jp/manga/
http://goo.gl/O2YkkJ
いわゆる「リスペクト」です
( ー`дー´)キリッ
http://goo.gl/O2YkkJ
開発のきっかけ
http://www.kakkoii.tv/events/20130726/index.html
http://goo.gl/O2YkkJ
HTML5 Experts Night
on 8/23@MTL
http://html5experts.jp/yusuke-naka/1698/
http://goo.gl/O2YkkJ
開発メンバー
http://goo.gl/O2YkkJ
What is 機能
http://goo.gl/O2YkkJ
マンガ化
http://goo.gl/O2YkkJ
音声コマンド、ふきだし、エ
フェクト
http://goo.gl/O2YkkJ
リアルタイムフィードバック
http://goo.gl/O2YkkJ
How to 実装
マンガ化
WebSpeech API
Headtrackr.js
http://goo.gl/O2YkkJ
マンガ化
1. getUserMedia()でビデオ取得
2. CanvasPixelArray 取得
3. フィルター処理
http://goo.gl/O2YkkJ
マンガ化 (1/3)
getUserMedia()
navigator.webkitGetUserMedia({video: true, audio: false},
function(stream){...
http://goo.gl/O2YkkJ
マンガ化(2/3)
CanvasPixelArray取得
var imgData = ctx.getImageData(0, 0, 640, 480);
3
1 2
4
imgData = [
255,...
http://goo.gl/O2YkkJ
マンガ化(3/3)
フィルター処理
 階調化とエッジ中抽出の組み合わせ
エッジ抽出
階調化
(三階調)
合成
参考)http://www.slideshare.net/masayukimaekawa/...
http://goo.gl/O2YkkJ
Code
for(var y = 1; y < height-1; y++){
for(var x = 1; x < width-1; x++){
c = y * width + x;
i = c <<...
http://goo.gl/O2YkkJ
WebSpeech API
var rec = new webkitSpeechRecognition();
rec.start();
rec.onresult = function(event) {
...
http://goo.gl/O2YkkJ
意外に重要
httpsじゃないと、途中でも、これ出ちゃう・・・
http://goo.gl/O2YkkJ
Headtrackr.js
 OepraのAudunさんが開発した顔検出ライブラリ
 Face.jsより高速で動く(MBPで30fpsぐらい)
var htracker = new headtrac...
http://goo.gl/O2YkkJ
ここまでの内容
http://html5experts.jp/komasshu/1649/
http://goo.gl/O2YkkJ
How to 向上
performance
http://goo.gl/O2YkkJ
高速化の
ポイント
for(var y = 1; y < height-1; y++){
for(var x = 1; x < width-1; x++){
c = y * width + x;
i =...
http://goo.gl/O2YkkJ
目標
 マンガ化フィルター処理を 60 fps @ MBPで!!
 1回あたりの処理は、大体10msec以下に抑える必要
がある
 1000 [msec] / 60 = (約)16 msec
 ...
http://goo.gl/O2YkkJ
パフォーマンスチェック
http://goo.gl/O2YkkJ
結論
 関数呼び出しは減らそう
 プロパティ参照は無くそう
 演算処理はなるべく減らそう
 ビットシフトは、若干早くなる
 (でも、なんか頭が良くなった気がする)
 parseInt(“1”...
http://goo.gl/O2YkkJ
パフォーマンスチューニング
はエコ!!
http://goo.gl/O2YkkJ
Thank you!!
@komasshu
Upcoming SlideShare
Loading in...5
×

「マンガテレビ」の作り方

1,597

Published on

第41回HTML5とか勉強会で講演した「マンガテレビ」の作り方。WebSpeech APIとかheadtrackr.jsとか

Published in: Technology, Design

「マンガテレビ」の作り方

  1. 1. http://goo.gl/O2YkkJ 「マンガテレビ」の 作り方 第41回 HTML5とか勉強会 2013.8.26 こまつけんさく
  2. 2. http://goo.gl/O2YkkJ 自己紹介  こまつけんさく  NTTコミュニケーションズ  最新Web技術の研究開発  html5j スタッフ  Google Developers Expert (HTML5)  Microsoft Valuable Professional (IE)
  3. 3. http://goo.gl/O2YkkJ 「マンガテレビ」? https://app.html5experts.jp/manga/
  4. 4. http://goo.gl/O2YkkJ いわゆる「リスペクト」です ( ー`дー´)キリッ
  5. 5. http://goo.gl/O2YkkJ 開発のきっかけ http://www.kakkoii.tv/events/20130726/index.html
  6. 6. http://goo.gl/O2YkkJ HTML5 Experts Night on 8/23@MTL http://html5experts.jp/yusuke-naka/1698/
  7. 7. http://goo.gl/O2YkkJ 開発メンバー
  8. 8. http://goo.gl/O2YkkJ What is 機能
  9. 9. http://goo.gl/O2YkkJ マンガ化
  10. 10. http://goo.gl/O2YkkJ 音声コマンド、ふきだし、エ フェクト
  11. 11. http://goo.gl/O2YkkJ リアルタイムフィードバック
  12. 12. http://goo.gl/O2YkkJ How to 実装 マンガ化 WebSpeech API Headtrackr.js
  13. 13. http://goo.gl/O2YkkJ マンガ化 1. getUserMedia()でビデオ取得 2. CanvasPixelArray 取得 3. フィルター処理
  14. 14. http://goo.gl/O2YkkJ マンガ化 (1/3) getUserMedia() navigator.webkitGetUserMedia({video: true, audio: false}, function(stream){ var url = window.webkitURL.createObjectURL(stream); $v_[0].src = url; $v_[0].play(); });
  15. 15. http://goo.gl/O2YkkJ マンガ化(2/3) CanvasPixelArray取得 var imgData = ctx.getImageData(0, 0, 640, 480); 3 1 2 4 imgData = [ 255, 0, 0, 255, // 1 (R, G, B, α) 0, 255, 0, 255, // 2 (R, G, B, α) 0, 0, 255, 255, // 3 (R, G, B, α) 255, 255, 0, 255 // 4 (R, G, B, α) ];
  16. 16. http://goo.gl/O2YkkJ マンガ化(3/3) フィルター処理  階調化とエッジ中抽出の組み合わせ エッジ抽出 階調化 (三階調) 合成 参考)http://www.slideshare.net/masayukimaekawa/java-script-14727253
  17. 17. http://goo.gl/O2YkkJ Code for(var y = 1; y < height-1; y++){ for(var x = 1; x < width-1; x++){ c = y * width + x; i = c << 2; // 周辺ピクセル tmp = (c - width) << 2; a0 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; tmp = (c - 1) << 2; a1 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; tmp = (c + 1) << 2; a2 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; tmp = (c + width) << 2; a3 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; // グレー値 gray = (dotList[i] + dotList[i+1] + dotList[i + 2] ); if((a0 + a1 + a2+ a3) < ((gray & FILTER) << 2)) { // エッジ化 img_toon.data[i] = 0; img_toon.data[i+1] = 0; img_toon.data[i+2] = 0; } else { // 階調化 if( gray < DARK ) { gra = 0; } else if( gray > BLIGHT ) { gra = 255; } else { gra = 1; } // スクリーントーン if( gra == 1 ) { dx_ = (x & 0x03); dy_ = (y & 0x03) if( (!dx_ && !dy_) || (dx_ == 2) && (dy_ == 2)){ gra = 0; } else { gra = 255; } }; img_toon.data[i] = gra; img_toon.data[i+1] = gra; img_toon.data[i+2] = gra; } img_toon.data[i+3] = 0xff; //img.data[i + 3]; } } 30万回のループ処理です。。。
  18. 18. http://goo.gl/O2YkkJ WebSpeech API var rec = new webkitSpeechRecognition(); rec.start(); rec.onresult = function(event) { // event.results に認識結果が格納 }  音声認識API  W3Cでドラフトにもなっていない。Chromeのみ実装  認識は、Googleさんが頑張っています
  19. 19. http://goo.gl/O2YkkJ 意外に重要 httpsじゃないと、途中でも、これ出ちゃう・・・
  20. 20. http://goo.gl/O2YkkJ Headtrackr.js  OepraのAudunさんが開発した顔検出ライブラリ  Face.jsより高速で動く(MBPで30fpsぐらい) var htracker = new headtrackr.Tracker(); htracker.init($("video")[0], $("canvas")[0]); htracker.start(); document.addEventListener("facetrackingEvent", function( ev ) { // ev.width : 幅, ev.height : 高さ, ev.x : 中心(x), ev.y : 中心 (y) });
  21. 21. http://goo.gl/O2YkkJ ここまでの内容 http://html5experts.jp/komasshu/1649/
  22. 22. http://goo.gl/O2YkkJ How to 向上 performance
  23. 23. http://goo.gl/O2YkkJ 高速化の ポイント for(var y = 1; y < height-1; y++){ for(var x = 1; x < width-1; x++){ c = y * width + x; i = c << 2; // 周辺ピクセル tmp = (c - width) << 2; a0 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; tmp = (c - 1) << 2; a1 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; tmp = (c + 1) << 2; a2 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; tmp = (c + width) << 2; a3 = (dotList[tmp] + dotList[tmp+1] + dotList[tmp + 2]) & FILTER; // グレー値 gray = (dotList[i] + dotList[i+1] + dotList[i + 2] ); if((a0 + a1 + a2+ a3) < ((gray & FILTER) << 2)) { // エッジ化 img_toon.data[i] = 0; img_toon.data[i+1] = 0; img_toon.data[i+2] = 0; } else { // 階調化 if( gray < DARK ) { gra = 0; } else if( gray > BLIGHT ) { gra = 255; } else { gra = 1; } // スクリーントーン if( gra == 1 ) { dx_ = (x & 0x03); dy_ = (y & 0x03) if( (!dx_ && !dy_) || (dx_ == 2) && (dy_ == 2)){ gra = 0; } else { gra = 255; } }; img_toon.data[i] = gra; img_toon.data[i+1] = gra; img_toon.data[i+2] = gra; } img_toon.data[i+3] = 0xff; //img.data[i + 3]; } }
  24. 24. http://goo.gl/O2YkkJ 目標  マンガ化フィルター処理を 60 fps @ MBPで!!  1回あたりの処理は、大体10msec以下に抑える必要 がある  1000 [msec] / 60 = (約)16 msec  ループ1回あたりの処理は、30 nano-sec以下が目標  10 msec / 300,000
  25. 25. http://goo.gl/O2YkkJ パフォーマンスチェック
  26. 26. http://goo.gl/O2YkkJ 結論  関数呼び出しは減らそう  プロパティ参照は無くそう  演算処理はなるべく減らそう  ビットシフトは、若干早くなる  (でも、なんか頭が良くなった気がする)  parseInt(“1”) < “1”|0  InternetExplorerを除く
  27. 27. http://goo.gl/O2YkkJ パフォーマンスチューニング はエコ!!
  28. 28. http://goo.gl/O2YkkJ Thank you!! @komasshu
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×