OpenCV野良ビルド時にCMakeが指定したPythonのライブラリをうまく見つけてくれない時は

OpenCVをPythonサポート込みでビルドしたいことがあります。
Python側へインタフェースを露出するためのヘッダなどが必要なので、いくつかのPython関連パッケージを入れれば、あとはシンプルにCMakeを実行すればよいことがほとんどです。
(そのやり方はネットにたくさんまとまっているので他をご参照ください)

% sudo apt-get install python2.7-dev python3.4-dev #などなど。
% cd /path/to/opencv/source/root
% mkdir build; cd build
% cmake -DBUILD_opencv_python2=ON -DBUILD_opencv_python3=ON ..

一方で、rootがないなどの状況でpython2.7-devなどのパッケージがシステムにない場合は、例えばpyenvを使って一時的にpythonをユーザ環境に入れそのパスを参照させることで、Python対応こみでビルドすることが可能です。
(ビルドがおわったら一時的に入れたPython環境は消してOKです)

% pyenv install miniconda2-latest
% pyenv install miniconda3-latest
% cmake -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=$HOME \
        -DBUILD_opencv_python2=ON \
        -DPYTHON2_EXECUTABLE=`pyenv local miniconda2-latest; pyenv which python` \
        -DPYTHON2_INCLUDE_DIR=`pyenv local miniconda2-latest; python -c 'from distutils.sysconfig import get_python_inc; print(get_python_inc())'` \
        -DPYTHON2_NUMPY_INCLUDE_DIRS=`pyenv local miniconda2-latest; python -c 'import numpy; print(numpy.get_include())'` \
        -DPYTHON2_LIBRARIES=`find $PYENV_ROOT/versions/miniconda2-latest/lib -name 'libpython*.so'` \
        -DBUILD_opencv_python3=ON \
        -DPYTHON3_EXECUTABLE=`pyenv local miniconda3-latest; pyenv which python` \
        -DPYTHON3_INCLUDE_DIR=`pyenv local miniconda3-latest; python -c 'from distutils.sysconfig import get_python_inc; print(get_python_inc())'` \
        -DPYTHON3_NUMPY_INCLUDE_DIRS=`pyenv local miniconda3-latest; python -c 'import numpy; print(numpy.get_include())'` \
        -DPYTHON3_LIBRARIES=`find $PYENV_ROOT/versions/miniconda3-latest/lib -name 'libpython*.so'` \
        ..

このとき、CMakeを走らせたときの序盤にこんなメッセージが出たり(PythonLibsを見つけられてなかったり、意図したのと違うものを見つけに行ってる)、

 -- Found PythonInterp: /home/xxxx/.pyenv/versions/miniconda2-latest/bin/python (found suitable version "2.7.14", minimum required is "2.7")
 -- Found PythonLibs: /usr/lib/x86_64-linux-gnu/libpython2.7.so (found suitable exact version "2.7.14")
 -- Found PythonInterp: /home/xxxx/.pyenv/versions/miniconda3-latest/bin/python (found suitable version "3.6.3", minimum required is "3.4")
 -- Could NOT find PythonLibs (missing:  PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS) (found suitable exact version "3.6.3")

CMakeの最後の結果表示のときにこんなメッセージが出たり(LibrariesがNO)、

 --   Python 2:
 --     Interpreter:                 /home/xxxx/.pyenv/versions/miniconda2-latest/bin/python (ver 2.7.14)
 --     Libraries:                   NO
 --     numpy:                       /home/xxxx/.pyenv/versions/miniconda2-latest/lib/python2.7/site-packages/numpy/core/include (ver 1.14.0)
 --     packages path:               lib/python2.7/site-packages
 --
 --   Python 3:
 --     Interpreter:                 /home/xxxx/.pyenv/versions/miniconda3-latest/bin/python (ver 3.6.3)
 --     Libraries:                   NO
 --     numpy:                       /home/xxxx/.pyenv/versions/miniconda3-latest/lib/python3.6/site-packages/numpy/core/include (ver 1.14.0)
 --     packages path:               lib/python3.6/site-packages

正しく指定したはずのライブラリのパスをCMakeがどうも認識してくれない様子のときは、CMakeのバージョンを疑ってみてください

% cmake --version
cmake version 2.8.12.2

2.8系では、うまくPythonのライブラリをみつけてくることができないようです。
OpenCVの提供するCMakeLists.txtのcmake_minimum_requiredは(Linuxであれば)2.8になっているので、特に怒られることなく進んでしまう、というのが罠でした(今回取り上げたかなり限定的なシチュエーション以外ではそれで問題なく動くためです)。
より新しいCMake 3.5などを使ってください。

特にUbuntu14.04をまだ使っていたりした場合は、標準でapt-getしたものは2.8までになります。
野良ビルドするなり、PPAにするなり、新しいUbuntuに乗り換えるなりするといいです。

自分用メモ。

UbuntuでOpenCVをlibjpeg-turboつきでビルドする

都道府県別の一人あたり魚介類消費量では、青森県がトップで、以下秋田、鳥取、新潟、富山と日本海側の県が続きます。島国・沖縄が意外にも最下位です。

さて、OpenCVで画像をロードするのを速くしたくて、JPEGについてはlibjpeg-turboというのが使えることを知りました。
libjpeg-turboはlibjpegをSIMDなどによって高速化したものでAPIレベルの互換性を保っています。
条件が良ければデコードが数倍速くなるということで、これをOpenCVに組み込んでビルドする方法をメモ。

Continue reading

OpenCVビルド時のCUDAのccbinの指定方法

リンネの生物階級分類において,「スズキ目」というのは脊椎動物中で最大の規模を誇る「目」なんだそうです.
スズキ目スズキ科スズキはまさに全生物中における最大勢力を束ねる王者と言えましょう.だから何.

さかな前線 » CMakeでCUDAの-ccbinの正しい指定方法の姉妹記事です.

さて,Linux上でOpenCVでCUDAサポートをONにしてビルドするとき,GCCのバージョンを指定したいことがあります.
基本的にはデフォルトGCCなんですが,4.8系などは現在のCUDAのnvccではサポートされていませんので,CUDAビルド時に限りGCC4.4や4.6を使うという設定です.

具体的には,CMakeのときに以下のように書きます

$ pwd
/home/hogehogehogehogeho/opencv-2.4.6.1/build

$ cmake -DWITH_CUDA=ON -DCUDA_HOST_COMPILER=/usr/bin/g++-4.4 ..

$ make -j40 -s; sudo make install

WITH_CUDAとともにCUDA_HOST_COMPILERを正しく設定すればいいのですが,CUDA_HOST_COMPILERに指定するgccはPATHが通っていても絶対パスで指定する必要があるようです.
CUDA_HOST_COMPILER=g++-4.4と書くと,ないよ>< って言われます.

以上です.

参考:OpenCV – Bug #2844: build with CUDA 5.0 on macosx – OpenCV DevZone

cv::SurfDescriptorExtractorの拡張ディスクリプタを無効にする

魚類というのは分類学的にどうなるのか調べてみたら,昔は「綱」だったけどそうも言えないことがわかって,今は魚類をひっくるめた分類というのはない(生物学的には意味がなくなってしまう)んだそうですね.

さて,局所特徴量のSURFと言うと64次元だよね!という認識が一般的だと思います.
実際には原著(*1)の段階から特徴量を128次元で記述する拡張ディスクリプタ(extended descriptor)についても言及されていて,OpenCVの実装ではSURF特徴記述を行うcv::SurfDescriptorExtractorにおいてデフォルトで有効となっています.

cv::SurfDescriptorExtractor extractor;
std::cout << extractor.descriptorSize() << std::endl;  //128と出力されます

本来の64次元で使うには,特徴記述処理を行う前にこれを無効にします.
SurfDescriptorExtractorのコンストラクタのextendedをfalseにすればおkなんですが,
ぐぐって見つかるリファレンスでは最新のバージョンに同期されてなくて,でもコンパイルは通るので一瞬困惑します.

コンストラクタで指定するよりは,

cv::SurfDescriptorExtractor extractor;
extractor.extended = false;
std::cout << extractor.descriptorSize() << std::endl;  //64と出力されます

とすれば,その他のコンストラクタの他のデフォルトはそのままにいけます.少し汚いですが.

*1: H.Bay et. al., “Speeded-Up Robust Features (SURF),” ECCV2006

cv::Matとcv::Mat_<T>の画素アクセスの速度

近くのスーパーに秋は国内産の鮭が売っててよく買ってたんですが最近は輸入のサーモンばっかしです少し寂しいです.

OpenCVでちょっと気になって,画素単位のアクセスをするときcv::Matのat()による方法とcv::Mat_のoperator()による方法でどっちが速いかなと思って調べてみました.
星の数ほどされてる議論のようなするけどぱっと見た範囲で見当たらなかったのでやってみた.
参考までに画像ピクセル値へのアクセスと計算速度 | OpenCV.jpもあります.

結論から言うと,全く同じでした.

コードはこんなかんじ.時間計測はオレオレライブラリで高精度な計測ができます.

実行結果はこんなかんじ.

% ./a.out
cv::Mat::at<T>() -> 9.82353ms/回
cv::Mat_<unsigned char>::operator() -> 9.69412ms/回

大きさ(w,h)によらず同じくらいの模様.

あと気になる生配列とのアクセス速度の差ですが,上述プログラムと同じ処理を書いちゃうと最適化で全部消えちゃうしそうならないくらい複雑なプログラムは面倒だったので断念.
最適化しなければ,cv::Matの方が3割くらい遅いくらいでした.最適化するとどうなるやら.

  • CPU: i7 870 (2.93GHz)
  • OS: Ubuntu 11.10 x86
  • gcc: 4.7.0
  • option: -std=c++0x
  • OpenCV: 2.4.3

追記:
Ivy Bridge速すぎワロタw

  • CPU: i5 3570 (3.40 GHz)
  • OS: Linux Mint 13
  • gcc: 4.6.3
  • OpenCV: 2.4.3
% ./a.out
cv::Mat::at<T>() -> 2.34902ms/回
cv::Mat_<unsigned char>::operator() -> 2.34902ms/回

ECCV2012で発表されたKAZE局所特徴量を試してみた

先日ちょっと膝をケガしてしまいまして,ギプスに松葉杖です.けっこうリアルさかなに近づけたんじゃないかと思うのですがいかがでしょう?
折しも12/6で私も23歳を迎えました.できれば無事健康体で迎えたかったこの日.

この記事はComputer Vision Advent Calendar 2012の12/7担当分として書かれたものです.
主催者でありながら華麗に遅刻をキメました.これはひどい.
高専時代の後輩でもある@blue_jamくん,お疲れ様でした.そして誕生日メッセージありがとうございます.

さて,コンピュータビジョンにおける極めて重要な要素のひとつに画像特徴量があります.
これまでにたくさんの特徴抽出手法が提案されてきているわけですが,この度は最近の国際会議で発表されたばかりの新しい手法の実装が公開されていたので,それを試して見ることにしました.

Continue reading

Linuxでの野良ビルドのOpenCVでカメラをちゃんと使うにはlibv4l-devが必要みたい

地元に鮎の美味しいお店があって,そこの背ごしは最高の絶品だったりします.また行きたいですが,地元でも山の中なので,行くこと自体がけっこう大変.

さて,Computer Vision Advent Calendarの担当日からすでに3時間遅刻していますがこれはその記事ではありません.
今,がんばって書いてるところです(←

手元のLinux環境でOpenCVを野良ビルドするとき,libv4l-devをインストールしてからでないと,cv::VideoCaptureが動かないみたいです.

$ sudo apt-get install libv4l-dev
 ...
 --   Video I/O:
 --     DC1394 1.x:                  NO
 --     DC1394 2.x:                  YES (ver 2.2.0)
 --     FFMPEG:                      YES
 --       codec:                     YES (ver 53.35.0)
 --       format:                    YES (ver 53.21.0)
 --       util:                      YES (ver 51.22.1)
 --       swscale:                   YES (ver 2.1.0)
 --       gentoo-style:              YES
 --     GStreamer:                   NO
 --     OpenNI:                      NO
 --     OpenNI PrimeSensor Modules:  NO
 --     PvAPI:                       NO
 --     GigEVisionSDK:               NO
 --     UniCap:                      NO
 --     UniCap ucil:                 NO
 --     V4L/V4L2:                    Using libv4l (ver 0.8.6)
 --     XIMEA:                       NO
 --     Xine:                        NO
 ...

ここでUsing libv4lとなってることが重要みたいです.

cv::VideoCaptureが無言でエラーだけ返すので困りましたがそういうことだったみたいです.

OpenCVの二値画像からの画素値の取得でハマった

OpenCVの画像形式cv::Matはいろんな格納方式ができて,二値画像ももちろんいけるんですが,画素値を個別にアクセスするときのやり方でうっかりしたミスでハマってしまいました.

ということで自虐を兼ねてメモ.(逆では

//画像を読み込む
cv::Mat img = cv::imread("fugafuga.png", CV_LOAD_IMAGE_GRAYSCALE);

//大津の方法で二値化.こうすると二値画像のフォーマットでMatに格納してくれます
//srcとdstが一緒ですが一応問題ないです
cv::threshold(img, img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

//全画素をPGMフォーマットで出してみる
std::cout << "P1" << std::endl;
std::cout << img.cols << " " << img.rows << std::endl;
for(int y = 0; y < img.rows; y++)
{
    for(int x = 0; x < img.cols; x++)
    {
        //std::cout << img.at<int>(y, x) << " ";    //まちがい!!
        std::cout << static_cast<int>(img.at<unsigned char>(y, x)) << " ";
    }
    std::cout << std::endl;
}

at<int>()はカラー画像のBGRAをごそっと取り出すとき用だったりするので,二値画像の画素値を出すときはat<unsigned char>()を使いましょうというお話でした.static_castはべつにせんでもええです.
ちなみにat<int>()でやると事実上のゴミが出てきます.
何をいまさらこんなところでつまづいてるのか小一時間問い詰めたい.

OpenCV+IPP

Linux版OpenCVを,30日限定評価版のIPP付きでビルドする手順.
IPPとはマルチメディア処理ライブラリIntel Performance Primitivesのことで,intel製CPUを使ったマシンにおいてタスクによって2倍から10倍の性能向上があるとのこと.
事例をぐぐったかんじ,それほど誇張のある数字でもなさそう.

IPPのダウンロードとインストール
  1. http://software.intel.com/en-us/articles/intel-ipp/からダウンロード

    1. 登録が必要になります
    2. ライセンスファイルを添付したメールが届きます
    3. 僕はx86なので現在最新のl_ipp_7.0.7.319_ia32.tgzを落としました
  2. IPPのインストール

    1. 落としたアーカイブを展開
    2. % sudo ./install.sh
    3. あとは質問に答えるだけ

      1. ライセンスファイルのフルパスを入力するところがあります
      2. 正式サポート対象外のディストロの場合(Ubuntu等)では警告されますが無視で
OpenCVのインストール
  1. http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/からダウンロード
  2. 展開
  3. 展開した中に”release”ディレクトリを作成
  4. そこにcd
  5. % cmake -D WITH_IPP=ON -D IPP_H_PATH=/opt/intel/ipp/include -D BUILD_SHARED_LIBS=OFF ..

    1. IPP関連のオプションだけつけた例です

      1. 最後のオプションがないとリンクエラーでます(´・ω・`)
      2. http://stackoverflow.com/questions/10508926/opencv-fails-to-build-with-ipp-support-enabled
    2. 必要に応じて他のオプションもつけて
  6. % make -s -j8
  7. % sudo make install

ついでに,OpenCVビルドのときのオプション全体
% cmake -D WITH_TBB=ON -D WITH_IPP=ON -D IPP_H_PATH=/opt/intel/ipp/include -D BUILD_SHARED_LIBS=OFF -D WITH_FFMPEG=OFF ..

  • TBB使います(objdetectとかimageprocモジュールの中とかで使ってるみたい)
  • FFMPEGがあるとなんかエラーでるので><
  • OpenMPはもはや使われない,んだそうですね.haartrainingの中ではふつーに使ってるんですが
IPPのライセンスの話

IPPを展開した場所にあるlicenseファイルとかNon-Commercial Software Download – Intel® Software Networkにあるとおり,非商用利用においては無料でライセンスを提供して頂けるそうです.
(ライセンスは変更される場合があります.自分で利用される際に再確認をお願いいたします)