ちなみにmotionを利用する方法に関しては、以下をご覧ください。
Raspberry Piに大人の科学マガジンUSB特撮カメラをつないでみた
Raspberry PiにつないだUSBカメラの画像をブラウザから確認するものをrubyで作ってみた
画像から顔やらなんやらを認識するにはOpenCVを利用するわけです。
OpenCVは
sudo apt-get install libopencv-dev
でもインストールできるのですが、インストールされるバージョンは2.3系のものが入るようです。
OpenCVをrubyから使おうと思ったりする場合は、ruby-opencvというものを利用するのですが、こちらは2.4系を必要とします。
今回はrubyで利用するので、apt-getを利用せずにインストールします。
OpenCVは、以下のようにインストールします。
コンパイルに必要になるものを準備します。以下がすべて本当に必要なのかはよくわかりません。
sudo apt-get install build-essential libboost1.46-all-dev libqt4-dev libgtk2.0-dev pkg-config opencl-headers libjpeg-dev libopenjpeg-dev libjasper-dev libjasper-runtime libpng12-dev libpng++-dev libpng3 libpnglite-dev libtiff-dev libtiff-tools pngtools zlib1g-dev zlib1g-dbg v4l2ucp python autoconf libeigen2-dev cmake openexr gstreamer-plugins-* freeglut3-dev libglui-dev libavc1394-dev libdc1394-22-dev libdc1394-utils libxine-dev libxvidcore-dev libva-dev libssl-dev libv4l-dev libvo-aacenc-dev libvo-amrwbenc-dev libvorbis-dev libvpx-dev
ソースを取得して展開します。今回は2.4.9を持ってきました。
wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.9/opencv-2.4.9.zip
unzip opencv-2.4.9.zip
cd opencv-2.4.9
コンパイルします。cmakeで指定したパラメータの意味は正直よく分かりません。そしてmakeはすごく時間がかかります。
mkdir build
cd build
cmake -DBUILD_DOCS=ON -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=RELEASE -DWITH_TBB=OFF -DWITH_GTK=ON -DWITH_OPENGL=ON -DWITH_QT=OFF -DINSTALL_C_EXAMPLES=ON -DWITH_OPENCL=OFF -DWITH_CUDA=OFF -DWITH_OPENNI=OFF -DWITH_UNICAP=ON -DWITH_V4L=ON -DWITH_XINE=ON ..
make
インストールします。
sudo make install
そして、ruby-opencvをインストールします。
sudo gem install ruby-opencv
ここまでのものが正しくインストールされたことを確認します。
以下のソースを実行してoutput.jpgにカメラ画像が保存されていればOKです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'opencv' | |
capture = OpenCV::CvCapture.open | |
mat = capture.query.to_CvMat | |
mat.save('output.jpg') |
カメラ画像から顔認識して顔の部分を四角で囲ってみます。カメラ画像はwebsocketを利用してブラウザで確認できるようにします。
rubyでwebsocketを利用するためem-websocketをインストールします。
sudo gem install em-websocket
で以下のソースを実行します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'opencv' | |
require 'em-websocket' | |
require 'base64' | |
EM::run do | |
cap = OpenCV::CvCapture.open | |
det_file = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml" | |
det = OpenCV::CvHaarClassifierCascade::load det_file | |
connections = Array.new | |
EM::WebSocket.start(:host => '0.0.0.0', :port => 51234) do |ws| | |
ws.onopen do |handshake| | |
puts 'connected' | |
connections.push(ws) | |
end | |
ws.onclose do |handshake| | |
puts 'closed' | |
connections.delete(ws) | |
end | |
end | |
EM::defer do | |
loop do | |
sleep 0.1 | |
next if connections.size == 0 | |
img = cap.query | |
img = img.resize OpenCV::CvSize.new 640, 360 | |
det.detect_objects(img).each do |rect| | |
puts "detect!! : #{rect.top_left}, #{rect.top_right}, #{rect.bottom_left}, #{rect.bottom_right}" | |
img.rectangle! rect.top_left, rect.bottom_right, :color => OpenCV::CvColor::Red | |
end | |
mat = img.to_CvMat | |
data = Base64.encode64(mat.encode('.jpg').pack('C*')) | |
connections.each do |con| | |
con.send(data); | |
end | |
end | |
end | |
end |
サーバ側においてもいいし、手元のPCにファイルとして用意してもよいのでブラウザから開くと顔認識した画像が見れるはずです。
ブラウザはchromeでしか試していないです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>WebCam</title> | |
</head> | |
<body> | |
<div id="capture-area"> | |
</div> | |
<script src="http://codeorigin.jquery.com/jquery-2.0.3.min.js"></script> | |
<script> | |
$(function() { | |
var ws = new WebSocket('ws://raspberrypi.local:51234'); | |
ws.onopen = function() { | |
$('#capture-area').append($('<img>').attr('id', 'capture')); | |
$('#capture').css("width","800px"); | |
}; | |
ws.onclose = function() { | |
}; | |
ws.onmessage = function(evt) { | |
var src = 'data:image/jpeg;base64,' + evt.data; | |
$('#capture').attr('src', src); | |
}; | |
}); | |
</script> | |
</body> | |
</html> |
ちなみに処理はすごく遅いです。体感的には2秒ぐらいで1回画面が切り替わる感じです。
以下がすごく参考になりました。
http://naohiro7.hatenablog.com/entry/2013/04/22/142243
http://shokai.org/blog/archives/8627