BlankTar

about | blog | works | photo

OpenCVはかなり楽しいのですが、python2しか対応してなくてつらいですよね。…って思っていたら、opencv3.0.0からはpython3系にも対応しているそうです。すてき。
というわけで、早速手元のmacに入れてみました。

とりあえず古いやつを消しておく。入れてないならやらなくておっけー。

$ brew uninstall opencv

で、新しいやつを入れる。

$ brew install opencv3 --with-python3
$ echo /usr/local/opt/opencv3/lib/python2.7/site-packages >> /usr/local/lib/python2.7/site-packages/opencv3.pth
$ echo /usr/local/opt/opencv3/lib/python3.5/site-packages >> /usr/local/lib/python3.5/site-packages/opencv3.pth

こんな感じ。以上。

インストール時のメッセージにも出てくるのだけれど、2行目と3行目のようなコマンドを打たないと動くようにならないので注意です。
opencv2と被らないように、自動でリンクしてくれないっぽい。

2.7とか3.5とかの部分はお使いのpythonのバージョンに合せてください。よしなに。

余談ですが、opencv3になってもモジュール名はcv2のままらしいです。使い方も変わりません。
せっかくならオブジェクト指向っぽいAPIにしてほしかったけれど、他の言語のバインディングとの兼ね合いなのかしら。めんどうくさい。

pythonのOpenCVで作った画像をOpenCVでそのまま描画すると何だかインターフェースが微妙です。なんとなくですが、速さも無い感じがします。
折角ならもっと描画向きのライブラリを使いたいと思ったので、pygameと連携してみることにしました。

変換は以下のような感じで出来ます。

>>> opencv_image = opencv_image[:,:,::-1]  # OpenCVはBGR、pygameはRGBなので変換してやる必要がある。
>>> shape = opencv_image.shape[1::-1]  # OpenCVは(高さ, 幅, 色数)、pygameは(幅, 高さ)なのでこれも変換。
>>> pygame_image = pygame.image.frombuffer(opencv_image.tostring(), shape, 'RGB')
<Surface(848x480x24 SW)>

こんな感じ。色の順番と、サイズの順番の両方を変換する必要がある、というのがポイントです。

描画するときは普通に読み込んだ画像と同じく以下のように。

>>> x = 0
>>> y = 0
>>> screen.blit(img, (x, y))

ふつうです。

参考: python - OpenCV cv2 image to PyGame image? - Stack Overflow

先程の記事でHTML5を使った音の解析をやったので、ついでに映像をやってみようかと思いまして。
pythonでやって好評だった笑い男をやってみました。

とりあえず、必要なライブラリを揃えておきます。といってもccv.jsだけ出来ます。
必要なのはccv.jsface.jsです。適当にダウンロードします。
あと、当然ながら笑い男も用意します。

で、とりあえず実行例。


こんなもん。ちょっと、いやすごく重い。

で、ソースコード。

<script src="ccv.js"></script>
<script src="face.js"></script>

<canvas></canvas>

<script>
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

var video = document.createElement('video');
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');

var laughingman = new Image();
laughingman.src = 'laughing.png';

navigator.getUserMedia(
	{video: true},
	function(stream){
		video.src = URL.createObjectURL(stream);

		video.addEventListener('loadedmetadata', function(){
			canvas.width = video.videoWidth;
			canvas.height = video.videoHeight;

			(function animation(){
				context.drawImage(video, 0, 0);

				ccv.detect_objects({
					'canvas': ccv.pre(canvas),
					'cascade': cascade,
					'interval': 5,
					'min_neighbors': 1
				}).forEach(function(x){
					context.drawImage(laughingman, x.x, x.y, x.width, x.height);
				});

				requestAnimationFrame(animation);
			})();
		});
	},
	console.log
);
</script>

実にシンプルです。
getUserMediaで映像を取得して、準備が出来たらcanvasのサイズを設定。
映像はcanvasに描画させて、そいつをccv.detect_objectsに渡すことで検出を行なっています。
出来ればvideoタグで描画させたかったのだけれど、videoタグを渡して検出させる方法が分からなかったのでcanvasを利用。

face.jsの中に認識に使うデータが書かれていて、そいつがcascadeって変数に入るようです。
なのでこいつを別のファイルに差し替えれば顔以外も検出出来るはず。

参考: WebRTC(2)ccv.jsと組み合わせて顔認識を実装〜笑い男〜 | potter0517

[ << ] [ 8 ] [ 10 ] [ 12 ] [ >> ]