ブラウザとwebカメラで遊べるので気軽で楽しい。
概要
Webカメラで撮影した画像を取得できるWeb RTC APIを使って、
javascriptで画像を取得。
↓
それをtoDataURLメソッドでバイナリ文字列に変換し、
ajaxでrailsのサーバ側に送る。
↓
railsは受け取った画像をOpenCVで処理してクライアントに返す。
クライアントは受け取った画像を表示する。
公開コード
https://saoyagi@bitbucket.org/saoyagi/pose2.git
*このアプリは人のいろんなポーズを集めるために作ったので、
Poseというキーワードがいろんな所に出てくる。
関係サイト
ヒューマンインタフェース学会若手の会
HI2013ワークショップ
http://www.his.gr.jp/_sig/hist.html
事前準備
前提として、画像処理が簡単にできるライブラリOpenCVと、
それをrubyから使えるようにするラッパーであるruby-opencvをインストールしておかないとダメ
OpenCVのインストールの参考になるサイト
http://www.kkaneko.com/rinkou/opencv/opencvinstalllinux.html
ruby-opencvのgithubページ
https://github.com/ruby-opencv/ruby-opencv
ruby-opencvインストールの参考になるサイト
http://www.kkaneko.com/rinkou/ruby/rubyopencv.html
http://ser1zw.hatenablog.com/entry/2013/01/29/235320
重要部分のコード
Webカメラの画像を取得するjavascriptコード
参考
http://davidwalsh.name/browser-camera
http://slowquery.hatenablog.com/entry/2013/01/30/001310
htmlファイルに
<video id="video" autoplay></video>
というvideo要素を作ったとすると、そこにwebカメラからのリアルタイム入力動画を出力するのは
下のようなコードがあれば良いらしい。
Pose.videoElement = $("#video").get(0); var videoObj = { "video": true }; var falseCallback = function(error) { console.log("Video capture error: ", error.name); }; navigator.getUserMedia(videoObj, function(stream) { Pose.videoElement.src = stream; Pose.videoElement.play(); }, falseCallback);
video要素と、謎の{video:true}という内容のオブジェクト、それに取得失敗時のコールバックの3つを用意し、
navigator.getUserMediaメソッドを呼び出す。
成功時コールバックでは、引数としてもらえるstreamオブジェクトをvideo要素のsrcにセットして、
play()メソッドを呼ぶ。
実際にはブラウザごとの違いとかがあって以下のように書く。
function initCamera(){ Pose.videoElement = $("#video").get(0); var videoObj = { "video": true }; var falseCallback = function(error) { console.log("Video capture error: ", error.name); }; Pose.videoElement.setAttribute("width",Pose.MAGE_WIDTH); Pose.videoElement.setAttribute("height",Pose.IMAGE_HEIGHT); //ビデオリスナーのセット if(navigator.getUserMedia) { // Standard navigator.getUserMedia(videoObj, function(stream) { Pose.videoElement.src = stream; Pose.videoElement.play(); }, falseCallback); } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed navigator.webkitGetUserMedia(videoObj, function(stream){ Pose.videoElement.src = window.webkitURL.createObjectURL(stream); Pose.videoElement.play(); }, falseCallback); } else if(navigator.mozGetUserMedia) { // Firefox-prefixed navigator.mozGetUserMedia(videoObj, function(stream){ Pose.videoElement.src = window.URL.createObjectURL(stream); Pose.videoElement.play(); }, falseCallback); } }
そこから画像をとるには、document.createElement('canvas')でcanvas要素を作成し、
canvas.getContext("2d")でコンテクストというよく分からんオブジェクトとをもらって、
そいつのdrawImageメソッドの第一引数にセットして呼び出すだけ
canvasの中に画像が入るので、あとはcanvasをどっかの要素にappendしたりすれば良い
実際にはcanvasのサイズとかを指定しないと行けないのでこんな感じ
var canvas = document.createElement('canvas'); canvas.setAttribute("width", Pose.IMAGE_WIDTH); canvas.setAttribute("height", Pose.IMAGE_HEIGHT); context = canvas.getContext("2d"), context.drawImage(Pose.videoElement, 0, 0, Pose.IMAGE_WIDTH, Pose.IMAGE_HEIGHT);
画像をバイナリ文字列にして送信するjavascriptコード
疲れたので参考ページのみ
参考
html5のcanvas要素について
http://www.h2.dion.ne.jp/~defghi/canvasMemo/canvasMemo.htm#h10
jqueryのajax()メソッド
https://www.google.co.jp/search?q=jquery+ajax&oq=jquery+ajax&aqs=chrome..69i57j69i65l3j0l2.2881j0j7&sourceid=chrome&espv=210&es_sm=119&ie=UTF-8
画像のバイナリ文字列をなんか配列みたいなのに変換していろんな処理するrubyコード
疲れたので参考ページのみ
参考
ruby-opencvのリファレンス
http://rubydoc.info/gems/ruby-opencv/frames