徹底比較OpenCV 2.4.3 vs OpenCV 2.4.2

はじめに

この記事はComputer Vision Advent Calendar 2012の12/22の記事として書いたものです.12/8に別の記事を書いたのですが懲りもせずに2周目にチャレンジです.

実質やったことは,以前やったマクロ調査と同レベルで2.4.2と2.4.3のコードをWinMergeで差分確認するだけの簡単なお仕事なので他の人に比べてクオリティがアレな感じなのはご容赦ください。。。


どんな内容?

2012年11月にOpenCV 2.4.3がリリースされましたが前バージョンの2.4.2とどこが違うの?という方も多いと思います.個人的な興味もあってコード差分を確認しながら気になった点をまとめてみました.2.4.2から2.4.3に移行するかどうか迷ってる方の判断材料となれば幸いです.


公式ChangeLog

公式が出しているChangeLogは以下の通りです.
http://code.opencv.org/projects/opencv/wiki/ChangeLog#243
http://opencv.org/opencv-2-4-3-released.html


追加されたCMakeオプション

2.4.3からいくつかCMakeオプションが追加されています.オプションがこれ以上増えるとわけがわからなくなる!というのは置いておいて追加されたオプションを紹介します.

CMakeオプション意味
WITH_GIGEAPIInclude Smartek GigE support
WITH_CSTRIPESInclude C= support
WITH_OPENCLInclude OpenCL Runtime support
WITH_OPENCLAMDFFTInclude AMD OpenCL FFT library support
WITH_OPENCLAMDBLASInclude AMD OpenCL BLAS library support
ENABLE_AVXEnable AVX instructions




その中からいくつかピックアップして解説してみます.

  • WITH_GIGEAPI
    GigE VisionはAutomated Imaging Association(AIA)によって定められた規格で,イーサネット技術がベースになっているので特別な端子やケーブルが不要で最大100mまでのケーブル長に対応できるのでマシンビジョン用途のカメラで採用されているようです.この規格のカメラがhighguiで簡単に使えるようになるのでマシンビジョン分野の人には嬉しい追加機能かもしれませんね.
  • WITH_OPENCL
    OpenCL実装のoclMatが使えるようになります.個人的にはかなり大きめな追加機能だと思います.また,CUDA実装であるgpuMatとかなり使い方が似ているのでgpuMatを使ったことがある方は結構すんなり導入できると思います(現時点ではgpuMatの方が対応関数多いですが・・・).簡単な使い方はOpenCV/Method used for oclMat on OpenCV 2.4.3を参考ください.
  • ENABLE_AVX
    SIMD命令の一つであるAVXの実装も(まだ対応されているのは少ないですが)追加されています.ただ,AVXは画像処理の実装ではちょっと扱いづらいこともあり,整数演算が使えるAVX2が登場すればAVX2対応が加速するのでは?と予想しています.

iOS向け

2.4.3でiOS向けの変更がかなりあるので関連ファイルの差分をピックアップしながら追っていきます(※結論から述べると個人的にはiOS SDK 6で開発している方には2.4.3をオススメします).

[iOS.cmake]
2.4.2:

# Hidden visibilty is required for cxx on iOS 
set (CMAKE_C_FLAGS "")
set (CMAKE_CXX_FLAGS "-headerpad_max_install_names -fvisibility=hidden -fvisibility-inlines-hidden")

2.4.3:

# Hidden visibilty is required for cxx on iOS
set (CMAKE_C_FLAGS "")
set (CMAKE_CXX_FLAGS "-stdlib=libc++ -headerpad_max_install_names -fvisibility=hidden -fvisibility-inlines-hidden")

set (CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -fomit-frame-pointer -ffast-math")



2.4.3から最適化オプションが見直されました(そもそも2.4.2で最適化に関する問題が指摘されていたためですが・・・).また,2.4.3からlibc++が明示的に指定されるようになっている点は要注意です.

[build_framework.py]
2.4.3からarmv7sが正式にサポートされるようになりました.iOS SDK 6で開発されていて,armv7sアーキテクチャを有効に使いたい場合は2.4.3を使った方が良いと思われます.

[highgui]
iOSデバイスのカメラを使うためのクラスが追加されています.内部的にはAVFoundationを使ったカメラの制御になっているようです.

  • CvPhotoCameraクラス(静止画用)
  • CvVideoCameraクラス(動画用)

CvVideoCameraの使い方は公式のチュートリアルが参考になります.カメラ周りは色々とコーディングが面倒なのでこの辺を簡単に使えるようになるのは嬉しいです.


modules

2.4.3からopencv_worldモジュールが追加されました(正確にはiOS向けだけに提供されていたのですが2.4.3からそれ以外のプラットフォームでも有効になりました).

opencv_worldモジュールはOpenCVの全モジュール(core/imgproc/highgui etc…)を一つのライブラリにがっちゃんこしたものです.なので基本的にこのライブラリだけリンクしておけば全ての機能が使えることになります(ただし,特にiOS向けの場合プログラムサイズが大きくなるので注意!).BUILD_opencv_world – Memento Moriに詳しい解説があります.


3rdparty

OpenEXRがライブラリ同梱からソース同梱へ変更されました.以前はOpenCV/Method to enable OpenEXR on OpenCVのように自前でビルドする場合は涙ぐましい前準備が必要でしたが,CMake時に「WITH_OPENEXR」「BUILD_OPENEXR」をONにするだけでOpenCVビルド時に同梱ソースをビルドして勝手にリンクしてくれます.とても楽な時代になりましたね(苦笑)


core

様々な並列処理フレームワーク(TBB/OpenMP/GCD/C=/PPL)を抽象化するような関数が追加されています.そのため,自作関数を作る場合にこれらの関数を使うとマルチプラットフォーム対応になるだけでなく,並列処理フレームワーク毎に処理速度を比較することで使用フレームワーク検討が容易になるかもしれません.

  • ParallelLoopBody
  • parallel_for_
  • Mutex

[internal.hpp]
2.4.2:

#if defined ANDROID && defined __ARM_NEON__

2.4.3:

#ifdef __ARM_NEON__



2.4.2までCV_NEONというプリプロセッサ定義はANDROIDだけで定義されていましたが,2.4.3からこの制限が外れました.そのため,iOSでもCV_NEONが有効になります.CV_NEONが有効になる箇所を確認したところ,static関数のnormHamming関数で使われているようです.feature2dモジュールのDescriptorMatcherの中で使ってるようなのでこの辺を使う方には嬉しいかもしれません.


features2d

ICCV2011で発表されたBRISKが追加されています.実装は下記のファイルにあります.

modules/features2d/src/brisk.cpp

gpuMat

gpuMatで追加実装された機能のうち気になるものをピックアップしてみました.

  • bilateralFilter追加
  • HoughLines追加
  • HoughCircles追加
  • VideoReader_GPU追加
  • VideoWriter_GPU追加
  • resizeのリサイズ方法にINTER_AREA実装追加

個人的に気になるのはVideoReader/VideoWriterのCUDA実装は速いのか?ですね.
新しいPCにまだCUDAを入れていないので,そのうち試してみたいと思います.


highgui

  • png書き込みパラメータ追加
    enum
    {
    IMWRITE_JPEG_QUALITY =1,
    IMWRITE_PNG_COMPRESSION =16,
    IMWRITE_PNG_STRATEGY =17,
    IMWRITE_PNG_BILEVEL =18,
    IMWRITE_PNG_STRATEGY_DEFAULT =0,
    IMWRITE_PNG_STRATEGY_FILTERED =1,
    IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2,
    IMWRITE_PNG_STRATEGY_RLE =3,
    IMWRITE_PNG_STRATEGY_FIXED =4,
    IMWRITE_PXM_BINARY =32
    };

    imwriteでpng保存する場合に指定できるパラメータとして「IMWRITE_PNG_BILEVEL」が追加されました.どういう経緯で追加されたのかよくわかりません(苦笑)

  • OpenNI関連パラメータ追加
    enum
    {
    CV_CAP_OPENNI_VGA_30HZ = 0,
    CV_CAP_OPENNI_SXGA_15HZ = 1,
    CV_CAP_OPENNI_SXGA_30HZ = 2,
    CV_CAP_OPENNI_QVGA_30HZ = 3,
    CV_CAP_OPENNI_QVGA_60HZ = 4
    };

    OpenNI関連パラメータとして「CV_CAP_OPENNI_QVGA_30HZ」「CV_CAP_OPENNI_QVGA_60HZ」が追加されました.どういう経緯で追加されたのか(ry

photo

photoモジュールはこれまでinpaintのみ提供されていましたが2.4.3から以下のDenoising関数が追加されました.

  • fastNlMeansDenoising
  • fastNlMeansDenoisingColored
  • fastNlMeansDenoisingMulti
  • fastNlMeansDenoisingColoredMulti

※詳細はDenoising — OpenCV v2.4.3 documentationを参照ください.

実装はNon-Local Means Denoisingのアルゴリズムがベースになっているようです.オンラインデモも公開されているので気になる方は試してみると良いかと思います.


おわりに

というわけで個人的に気になる変更点を好き勝手に色々書いてみました(ドラフト版ではもう少し細かい差分をピックアップしていたのですが力尽きました・・・).2.4.2から2.4.3に移行するかどうか迷ってる方の判断材料となれば幸いです.明日は@payashimさんの記事なので楽しみです!

NativeViewerの使い方

この記事はComputer Vision Advent Calendar 2012の12/8の記事兼@sakanazensenさんへの誕生日プレゼントとして書いたものです.

つい最近,OpenCVプログラムのデバッグ中にMatの中身をプレビューできるプラグイン「NativeViewer」のv1.0がリリースされました.このプラグインの使い方について解説記事の要望があったので(30分くらいでてきとーに)書いてみました.基本的に公式のQuickStartGuideとほぼ同じ内容です.

以降の説明はVisual Studio 2012を使って説明します(Visual Studio 2010版のプラグインも用意されています).
※注意:Visual Studio Professional以上のエディションでしかプラグインは使えないようです.

■ダウンロード
配布ページからNativeViewer_VS2012_v1.0.0.vsixをダウンロードします.

■インストール
ダウンロードしたNativeViewer_VS2012_v1.0.0.vsixをダブルクリックすると以下のようなインストール画面が表示されます.ここで「インストール」ボタンを押すとインストール完了です.




■サンプルコード
なんてこともない2値化のサンプルです.このサンプルを用いて使い方の説明を行います.



■実際に使ってみる
この例では2値化結果をウィンドウに描画していますが,デバッグの時に2値化の前のグレースケールが正しい結果なのか知りたいような場合もあって,従来はグレースケール用にnamedWindowとimshowを追加し,リビルド・再実行する必要がありました.地味に面倒くさいです。。。この例ではリビルドしてもそんなに時間はかかりませんがそれなりの規模のプログラムだとビルド時間がもったいないです.

NativeViewerを使うとデバッグ用に新たにnamedWindowとimshowを追加してリビルドするといった面倒な作業から解放されます.やるのはデバッグ中にCtrlキーを押しながらプレビューしたいMatクラスの変数にマウスカーソルを合わせるだけです.




ここではデバッグ中にCtrlキーを押しながら「gray」という変数にマウスカーソルを合わせてみます.すると,以下のようなプレビュー画面が表示され,grayの描画内容を視覚的に確認することができます.デバッグ時にとても便利なのでVisual Studio使いにはオススメのプラグインです!



■オプション
また,Visual Studioのオプション画面からNativeViewerに関するレイアウト等の設定を行うことができます.



■アンインストール
「拡張機能と更新プログラム」画面から「NativeViewer」を選択して,「アンインストール」ボタンを押すことでプラグインをアンインストールすることができます.



■余談
12/22あたりにComputer Vision Advent Calendar 2012向けの別の記事公開予定です(他人事).過度な期待はせずにお待ちください。。。

OpenCVのビルド情報表示

OpenCVをCMakeでビルドして使う場合,CMakeオプションから様々な機能(TBB使用/CUDA使用/FFMPEG使用 etc…)のON/OFFを切り替えることができます.そのため,実際に使う場合の選択肢としてこれらの機能の組み合わせが大量に存在することになります.

これはユーザが多様な使い方を選択できるというメリットがある反面,複数のメンバでバグを調査する際に再現環境の情報共有が面倒であるというデメリットがあります.

例:CUDAを使った関数でバグが起きているケース
Aさん「OpenCV 2.4.3のWindows環境でこのバグを調査しといて」
Bさん「バグが再現しません」
Aさん「おかしいなー.TBB有効にしてるよね?」
Bさん「有効にしてます」
~こんなやり取りがしばらく続く~
Aさん「CUDA有効にしてる?」
Bさん「有効にしてないです」
Aさん「あー,こっちは有効にしてるのでそれで試してみて」
Bさん「・・・」

この例を見てもわかるようにとても面倒かつ非生産的ですね・・・.

この問題点を解消するためにOpenCV 2.4.0からOpenCVライブラリのビルド情報を出力することができるcv::getBuildInformation()関数が追加されています.実際に使う場合にはプログラム中に以下のような処理を1行追加するだけなのでとても簡単です.

std::cout << cv::getBuildInformation() << std::endl;


バグを調査する際にはまず再現させるということが重要です.そのため,公式へのバグ報告時にはこれらの情報も記載してあげた方が良いでしょう.以下にVS2012でOpenCV 2.4.3をビルドした場合の出力例を示します.

General configuration for OpenCV 2.4.3 =====================================

Platform:
Host: Windows 6.2 x86
CMake: 2.8.10.2
CMake generator: Visual Studio 11 Win64
CMake build tool: C:/PROGRA~2/MICROS~3.0/Common7/IDE/devenv.com
MSVC: 1700

C/C++:
Built as dynamic libs?: YES
C++ Compiler: C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/x86_amd64/cl.exe
C++ flags (Release): /DWIN32 /D_WINDOWS /W4 /GR /EHa /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:AVX /Oi /wd4251 /MD /O2 /Ob2 /D NDEBUG /Zi
C++ flags (Debug): /DWIN32 /D_WINDOWS /W4 /GR /EHa /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:AVX /Oi /wd4251 /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
C Compiler: C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/x86_amd64/cl.exe
C flags (Release): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:AVX /Oi /MD /O2 /Ob2 /D NDEBUG /Zi
C flags (Debug): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /arch:AVX /Oi /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
Linker flags (Release): /STACK:10000000 /machine:x64 /INCREMENTAL:NO /debug
Linker flags (Debug): /STACK:10000000 /machine:x64 /debug /INCREMENTAL
Precompiled headers: YES

OpenCV modules:
To be built: core imgproc flann highgui features2d calib3d ml video objdetect contrib nonfree photo legacy gpu stitching ts videostab
Disabled: world
Disabled by dependency: –
Unavailable: androidcamera java ocl python

GUI:
QT 4.x: NO
Win32 UI: YES
OpenGL support: NO

Media I/O:
ZLib: build (ver 1.2.7)
JPEG: build (ver 62)
PNG: build (ver 1.5.12)
TIFF: build (ver 42 – 4.0.2)
JPEG 2000: build (ver 1.900.1)
OpenEXR: NO

Video I/O:
FFMPEG: YES (prebuilt binaries)
codec: YES (ver 53.61.100)
format: YES (ver 53.32.100)
util: YES (ver 51.35.100)
swscale: YES (ver 2.1.100)
gentoo-style: YES
OpenNI: NO
OpenNI PrimeSensor Modules: NO
PvAPI: NO
GigEVisionSDK: NO
DirectShow: YES
XIMEA: NO

Other third-party libraries:
Use IPP: NO
Use TBB: YES (ver 4.1 interface 6101)
Use C=: NO
Use Cuda: NO
Use OpenCL: NO
Use Eigen: NO

Python:
Interpreter: NO

Tests and samples:
Tests: YES
Performance tests: YES
Examples: NO

Install path: C:/dev/OpenCV-2.4.3/build/install

cvconfig.h is in: C:/dev/OpenCV-2.4.3/build
—————————————————————–


色々情報が出ていますが簡単に眺めてみると,

「MSVC: 1700」
→Visual Studio 2012使ってるのかー

「DirectShow: YES」
→ビデオキャプチャはDirectShow使ってるのかー

「Use TBB: YES (ver 4.1 interface 6101)」
→TBBが有効になっててTBB 4.1使ってるのかー

などの情報が簡単にわかるようになります.