顔認識を失敗させる技術を失敗させるハッカソンという興味を惹かれる勉強会が開催されるという情報を聞きつけ、さっそく参加登録してみました。「自力で顔検出アプリケーションが作れること」が参加要件(?)のため、FreeBSD上にOpenCVの開発環境を構築し、顔認識アプリを作成してみることにしました。今回はその環境構築の手順を記事にしてみました。
環境はFreeBSD-10.2-RELEASE(i386)、HWはACER ASPIRE ONE AOA150-Bb1というちょっと古めのノートPCで試しています。
$ uname -a
FreeBSD fbsdmobile 10.2-RELEASE FreeBSD 10.2-RELEASE #0 r286666: Wed Aug 12 19:31:38 UTC 2015 root@releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC i386
$ freebsd-version -ku
10.2-RELEASE
10.2-RELEASE
OpenCVのインストール
パッケージからOpenCVをインストール
すでにパッケージとしてOpenCVが用意されており、これはサクッと環境構築できるのでは!と思っていたのですが、ちょっとハマり所がありました。
$ pkg search opencv | grep ^opencv
opencv-2.4.9_7 Open Source Computer Vision library
opencv-core-2.4.9_3 Open Source Computer Vision library
opencv-java-2.4.9_2 Open Source Computer Vision library
opencvs-20150501 BSD-licensed CVS implementation
パッケージでOpenCVをインストールし、簡単なサンプルプログラムを実行すると、以下のエラーが発生してしまいました(2016/03/26現在)
$ ./window
OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /wrkdirs/usr/ports/graphics/opencv/work/opencv-2.4.9/modules/highgui/src/window.cpp, line 483
どうやらパッケージ版のOpenCVではGUI(GTK/Qt)がビルドに含まれておらず、cvNamedWindow()が失敗してしまうようです。
$ pkg info opencv
opencv-2.4.9_7
...中略...
Options :
DC1394 : off
EIGEN3 : on
EXAMPLES : on
FFMPEG : off
GSTREAMER : off
GTK2 : off
JASPER : on
JPEG : on
NONFREE : off
OPENEXR : off
OPENGL : off
PNG : on
QT4 : off
SIMD : on
TBB : off
TIFF : on
V4L : on
Shared Libs required:
libpng16.so.16
libopencv_imgproc.so.2
libv4l1.so.0
libopencv_core.so.2
libjpeg.so.8
libtiff.so.5
libjasper.so.4
portsからOpenCVをインストールする
てっとり早い解決方法として、OpenCVのみportsからインストールしてみます。make reinstall時にOpenCVに組み込むライブラリを聞かれるので、GTKまたはQtを指定します。
$ fetch http://ftp.jaist.ac.jp/pub/FreeBSD/ports/ports/ports.tar.gz
$ sudo tar zxvf ports.tar.gz -C /usr
$ cd /usr/ports/graphics/opencv
$ sudo make reinstall
make reinstall後にpkg infoで確認すると、OptionsでGTKが組み込まれていることが分かります。
$ pkg info opencv
opencv-2.4.9_7
...中略...
Options :
DC1394 : off
EIGEN3 : on
EXAMPLES : on
FFMPEG : off
GSTREAMER : off
GTK2 : on
JASPER : on
JPEG : on
NONFREE : off
OPENEXR : off
OPENGL : off
PNG : on
QT4 : off
SIMD : on
TBB : off
TIFF : on
V4L : on
XINE : off
Shared Libs required:
libgtk-x11-2.0.so.0
libpangoft2-1.0.so.0
libglib-2.0.so.0
libv4l1.so.0
libgobject-2.0.so.0
libpango-1.0.so.0
libjpeg.so.8
libfreetype.so.6
libjasper.so.4
libcairo.so.2
libgdk-x11-2.0.so.0
libpng16.so.16
libopencv_imgproc.so.2
libatk-1.0.so.0
libopencv_core.so.2
libtiff.so.5
libintl.so.8
libgthread-2.0.so.0
libfontconfig.so.1
libgdk_pixbuf-2.0.so.0
libgio-2.0.so.0
libpangocairo-1.0.so.0
Webカメラの設定
静止画像のみでOpenCVを試してみるのも良いのですが、せっかくなのでWebカメラも利用できるようにしてOpenCVで動画を処理するようなアプリも作成してみたいものです。幸いにも環境構築に使用しているノートPCにはWebカメラが内蔵されているので、これを利用できるように設定してみます。
FreeBSDでWebカメラを扱うため、以下のパッケージをインストールします(pwcviewは単にWebカメラの動作確認用です)。
$ sudo pkg install cuse4bsd-kmod-0.1.36 webcamd pwcview
cuse4bsd-kmodをインストールすると以下のようなメッセージが表示されるので、これに従い設定ファイルに項目を追記します。
*********************************************************************
1) webcamd requires the cuse4bsd or cuse kernel module, depending on
how webcamd was compiled. Please load this dependency by doing:
# kldload cuse4bsd
or
# kldload cuse
or by adding
cuse4bsd_load="YES"
or
cuse_load="YES"
to your /boot/loader.conf.
2) add webcamd_enable="YES"
to your /etc/rc.conf
3) Please restart devd to start webcamd
# service devd restart
4) Optionally add a user to the "webcamd" group
# pw groupmod webcamd -m <username>
5) If webcamd still did not start, consult the installed webcamd rc.d
script for more help and instructions on how to start webcamd.
*********************************************************************
Webカメラ用ドライバをロードし、必要なデーモンを起動します。
$ sudo kldload cuse4bsd
$ kldstat | grep cuse
7 1 0xc77e5000 7000 cuse4bsd.ko
$ sudo service devd restart
$ sudo pw groupmod webcamd -m fpig
Webカメラの動作確認を行います。カメラの映像が表示されれば設定完了です。
$ sudo pwcview
サンプルプログラム
Webカメラも使用できるようになったので、さっそくOpenCVからWebカメラの映像を取得するサンプルプログラムを作成してみます。
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
cvNamedWindow("Camera", CV_WINDOW_AUTOSIZE);
CvCapture * cap = cvCaptureFromCAM(0);
if (cap == NULL) {
fprintf(stderr, "Camera is Not available.\n");
}
IplImage *cap_frame;
for (;;) {
cap_frame = cvQueryFrame(cap);
if (! cap_frame)
break;
cvShowImage("Camera", cap_frame);
char c = cvWaitKey(33); // 33msec
if (c == 27)
break;
}
cvReleaseCapture(&cap);
cvDestroyWindow("Camera");
return 0;
}
コンパイルしたプログラムを実行し、Webカメラの映像が表示されればOpenCVの開発環境構築はひとまず完了です。webcamdグループにユーザを所属させていれば、一般ユーザ権限でもWebカメラのデバイスにアクセスできます。
$ clang camera-capture-01.c `pkg-config opencv --cflags --libs`
$ ./a.out
まとめ
FreeBSD上にOpenCVの開発環境を構築してみました。少し型落ちのマシンで試してみましたが、Webカメラの映像がカクカクになったりせず、開発環境として普通に利用できそう(マシンパワー的には足りてそう)な感じです。
OpenCVはある程度扱えるようにしておきたいと常々思っていたので、環境が構築できたことをきっかけにOpenCV(と画像処理)でいろいろ試してみたいと考えています。