OpenCV 2.4 on Mac OS 10.8 導入メモ

Mac上にOpenCV 2.4の環境を整えたので、そのメモです。

導入時の環境

  • Mac OS X 10.8.4 (Moutain Lion)
  • OpenCV 2.4.6.1
  • Homebrew 0.9.4

OpenCVの導入

Homebrewを使います。

$ brew tap homebrew/science
$ brew install opencv
...
==> Installing opencv
==> Downloading http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.5
######################################################################## 100.0%
==> Downloading patches
######################################################################## 100.0%
==> Patching
patching file modules/ocl/include/opencv2/ocl/private/util.hpp
Hunk #1 succeeded at 49 with fuzz 1 (offset 2 lines).
patching file modules/ocl/src/safe_call.hpp
==> cmake -DCMAKE_INSTALL_PREFIX=/usr/local/Cellar/opencv/2.4.5 -DCMAKE_BUILD_TYPE=None
==> make
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [lib/libopencv_highgui.2.4.5.dylib] Error 1
make[1]: *** [modules/highgui/CMakeFiles/opencv_highgui.dir/all] Error 2
make: *** [all] Error 2

READ THIS: https://github.com/mxcl/homebrew/wiki/troubleshooting

brew tapというのは今回初めて知ったのですが、これを使って、コンピュータサイエンス系のfomulaを追加できるようです。

さて、OpenCVのfomulaが追加されたら普通にinstallすれば良いはずなのですが、エラーになってしまいました。「troubleshootingを見よ」と出ていますが、見ても解決しないです。

原因はffmpegにあるようで、とりあえずpull request承認待ち状態のパッチがあったので、適用します。

$ brew edit opencv
(ここのコードをコピペ)
$ brew install opencv
==> Downloading http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.6
Already downloaded: /Library/Caches/Homebrew/opencv-2.4.6.1.tar.gz
==> Patching
patching file modules/highgui/CMakeLists.txt
Hunk #1 succeeded at 191 (offset 19 lines).
==> cmake -DCMAKE_INSTALL_PREFIX=/usr/local/Cellar/opencv/2.4.6.1 -DCMAKE_BUILD_TYPE=Non
==> make
==> make install
==> Caveats
For non-homebrew python (2.x), you need to amend your PYTHONPATH like so:
  export PYTHONPATH=/usr/local/lib/python2.7/site-packages:$PYTHONPATH
==> Summary
 /usr/local/Cellar/opencv/2.4.6.1: 217 files, 42M, built in 5.1 minutes

SURFサンプルを動かしてみる

OpenCVはほぼ初めてなので、とりあえず以下のサンプルを動かしてみました。特徴点抽出のSURFで、特徴点に丸をつけるプログラムです。

ちなみに、OpenCV2.4からSURFは権利の関係上、nonfreeパッケージにまとめられたようです。なので、サンプルコード通りでは動かない点には注意が必要です。

コードはサンプルをちょっと改変して以下の通りにしました。

// main.cpp
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/nonfree/nonfree.hpp>

using namespace std;
using namespace cv;

int main(int argc, char* argv[]) {
  // load color image
  const char* imagename = argc > 1 ? argv[1] : "./img/lena.png";
  Mat colorImage = imread(imagename, 1);
  if (colorImage.empty()) {
    cout << "file not found" << endl;
    return -1;
  }

  // convert color image to grayscale for feature extraction
  Mat grayImage;
  cvtColor(colorImage, grayImage, CV_BGR2GRAY);

  // initialize SURF class
  SURF calc_surf = SURF(500, 4, 2, true);

  // extract SURF
  vector<KeyPoint> kp_vec;
  vector<float> dest_vec;
  calc_surf(grayImage, Mat(), kp_vec, dest_vec);

  // draw keypoints
  cout << "Image keypoints: " << kp_vec.size() << endl;
  for (int i = 0; i < kp_vec.size(); ++i) {
    KeyPoint* point = &(kp_vec[i]);
    Point center(cvRound(point->pt.x), cvRound(point->pt.y));
    int radius = cvRound(point->size * 0.25);
    circle(colorImage, center, radius, Scalar(255, 255, 0), 1, 8, 0);
  }

  namedWindow("SURF", CV_WINDOW_AUTOSIZE);
  imshow("SURF", colorImage);
  waitKey(0);

  return 0;
}

次にビルドですが、OpenCVに慣れてないので、ヘッダやリンカの設定が分からず試行錯誤しました。とりあえず、試行錯誤した感じでは、以下を抑えておけば良さそうです。

  • "/usr/local/include"をincludeパスに追加して、"opencv2/opencv.hpp"をインクルードする*1。これにより、標準のヘッダは大体includeされる。
  • "/usr/local/lib"をライブラリのパスに追加して、使用している機能のライブラリをリンクする。ライブラリはパッケージ単位に分かれているので、自分が使っている関数がどのパッケージに含まれるのか把握しておく。(参照:OpenCV2.4リファレンス
  • 標準以外の物は、必要に応じてinclude、リンクする。

というわけで、超手抜きMakefileを載せておきます。

CXXFLAGS = \
-I/usr/local/include

LDFLAGS = \
-L/usr/local/lib \
-lopencv_core \
-lopencv_highgui \
-lopencv_features2d \
-lopencv_imgproc \
-lopencv_nonfree

all:
     g++ $(CXXFLAGS) $(LDFLAGS) main.cpp

あとはmakeして実行するだけです。

$ make
$ ./a.out "lena.png"

f:id:s-shin:20130719211520p:plain

やったね!

*1:"opencv/cv.h"でも良いかもしれません