FreeBSD上にOpenCV開発環境を構築する

[顔認識を失敗させる技術を失敗させるハッカソン](http://connpass.com/event/29007/)という興味を惹かれる勉強会が開催されるという情報を聞きつけ、さっそく参加登録してみました。「自力で顔検出アプリケーションが作れること」が参加要件(？)のため、FreeBSD上にOpenCVの開発環境を構築し、顔認識アプリを作成してみることにしました。今回はその環境構築の手順を記事にしてみました。

環境はFreeBSD-10.2-RELEASE(i386)、HWは[ACER ASPIRE ONE AOA150-Bb1](http://www.amazon.co.jp/exec/obidos/ASIN/B001IEKWMI/nabelabs-22/ref=nosim/)というちょっと古めのノートPCで試しています。

```shell-session
$ 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が用意されており、これはサクッと環境構築できるのでは！と思っていたのですが、ちょっとハマり所がありました。

```shell-session
$ 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現在)

![img003.png](https://qiita-image-store.s3.amazonaws.com/0/61137/92f89b4b-801d-2dfc-02f9-706b14664265.png)

```shell-session
$ ./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()が失敗してしまうようです。

```shell-session
$ 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を指定します。

```shell-session
$ 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が組み込まれていることが分かります。

```shell-session
$ 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カメラの動作確認用です)。

```shell-session
$ sudo pkg install cuse4bsd-kmod-0.1.36 webcamd pwcview
```

cuse4bsd-kmodをインストールすると以下のようなメッセージが表示されるので、これに従い設定ファイルに項目を追記します。

```shell-session
*********************************************************************
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カメラ用ドライバをロードし、必要なデーモンを起動します。

```shell-session
$ sudo kldload cuse4bsd
$ kldstat | grep cuse
 7    1 0xc77e5000 7000     cuse4bsd.ko
$ sudo service devd restart
$ sudo pw groupmod webcamd -m fpig
```

Webカメラの動作確認を行います。カメラの映像が表示されれば設定完了です。

```shell-session
$ sudo pwcview
```

# サンプルプログラム

Webカメラも使用できるようになったので、さっそくOpenCVからWebカメラの映像を取得するサンプルプログラムを作成してみます。

```c
#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カメラのデバイスにアクセスできます。

```shell-session
$ clang camera-capture-01.c `pkg-config opencv --cflags --libs`
$ ./a.out 
```

# まとめ

FreeBSD上にOpenCVの開発環境を構築してみました。少し型落ちのマシンで試してみましたが、Webカメラの映像がカクカクになったりせず、開発環境として普通に利用できそう(マシンパワー的には足りてそう)な感じです。

OpenCVはある程度扱えるようにしておきたいと常々思っていたので、環境が構築できたことをきっかけにOpenCV(と画像処理)でいろいろ試してみたいと考えています。

# 参考URL

 * [OpenCV 2.2 (r4295) documentation](http://opencv.jp/opencv-2.2/c/index.html)
   * [索引](http://opencv.jp/opencv-2.2/c/genindex.html)
 * [Installing OpenCV 2.2 in Ubuntu 11.04](http://www.samontab.com/web/2011/06/installing-opencv-2-2-in-ubuntu-11-04/)
 * [Portsライブラリをソースからビルドする](http://qiita.com/jj1bdx/items/e17a86e17ec59fd835e1)
 * [NotePCに付いているカメラを FreeBSD で使う。](http://running-dog.net/2015/03/post_1395.html)