その他の機能

OpenCVのバージョンを調べる

#include <iostream>
#include <opencv2/core/core.hpp>

#define OPENCV_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#define OPENCV_VERSION_CODE OPENCV_VERSION(CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION)

int
main(int argc, char *argv[])
{
  std::cout << "version: " << CV_VERSION << std::endl;
  std::cout << "  major: " << CV_MAJOR_VERSION << std::endl;
  std::cout << "  minor: " << CV_MINOR_VERSION << std::endl;
  std::cout << "  subminor: " << CV_SUBMINOR_VERSION << std::endl;
  std::cout << "OpenCV >= 2.0.0: " << (OPENCV_VERSION_CODE>=OPENCV_VERSION(2,0,0)?"true":"false") << std::endl;
}

実行結果:

version: 2.3.1
  major: 2
  minor: 3
  subminor: 1
OpenCV >= 2.0.0: true

処理時間を計測する

#include <iostream>
#include <opencv2/core/core.hpp>

int
main(int argc, char *argv[])
{
  cv::Mat_<uchar> img = cv::Mat::zeros(500, 500, CV_8UC1);

  // 現在のTickCount
  double f = 1000.0/cv::getTickFrequency();
  int64 time = cv::getTickCount();
  
  // なんらかの処理...
  cv::MatIterator_<uchar> it = img.begin();
  for(; it!=img.end(); ++it)
    *it = 0x10;

  // TickCountの変化を[ms]単位で表示
  std::cout<<(cv::getTickCount()-time)*f<<" [ms]"<<std::endl;
}

実行結果:

8.00547 [ms]

printf風の表記で文字列を出力する

#include <iostream>
#include <opencv2/core/core.hpp>

int
main(int argc, char *argv[])
{
  int x=10, y=20;
  double v = 3.141592;

  std::cout << cv::format("value=%.3f, (%d, %d)", v, x, y) << std::endl;
  std::string test = cv::format("value=%.3f, (%d, %d)", v, x, y);
  std::cout << test << std::endl;
}

実行結果:

value=3.142, (10, 20)

CV_Assert/CV_DbgAssert

例外発生時のメッセージは,OpenCV のバージョンによって異なります.

#include <iostream>
#include <opencv2/core/core.hpp>

int
main(int argc, char *argv[])
{
  // 3x3 の行列
  cv::Mat m1 = (cv::Mat_<double>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);

  try {
    // デバッグ時のみ有効
    CV_DbgAssert(m1.type()==CV_8UC1);
  } catch(cv::Exception e) {
    std::cout << "CV_DbgAssert !!" << std::endl;
  }
  std::cout << std::endl;

  try {
    // 常に有効
    CV_Assert(m1.type()==CV_8UC1);
  } catch(cv::Exception e) {
    std::cout << "CV_Assert !!" << std::endl;
  }
}

実行結果(デバッグ):

OpenCV Error: Assertion failed (m1.type()==(((0) & ((1 << 3) - 1)) + (((1)-1) << 3))) in main, file sample_assert.cpp, line 12
CV_DbgAssert !!

OpenCV Error: Assertion failed (m1.type()==CV_8UC1) in main, file sample_assert.cpp, line 20
CV_Assert !!

実行結果(リリース):

OpenCV Error: Assertion failed (m1.type()==CV_8UC1) in main, file sample_assert.cpp, line 20
CV_Assert !!

CPUがサポートする機能(SSEなど)をチェックする

CPUが,MMXやSSE2/3/4.1/4.2,AVX(Intel Advanced Vector eXtentions),POPCOUNTなどをサポートしているか否かを調べることができます.

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/core/core_c.h>

#ifndef CV_CPU_POPCNT
#define CV_CPU_POPCNT CV_CPU_SSE4_2+1
#endif

using std::string;
using std::pair;

int
main(int argc, char *argv[])
{
  // 判定するCPU機能
  std::vector< pair<int, string> >flags;
  flags.push_back(pair<int,string>(CV_CPU_MMX, "MMX"));
  flags.push_back(pair<int,string>(CV_CPU_SSE, "SSE"));
  flags.push_back(pair<int,string>(CV_CPU_SSE2, "SSE 2"));
  flags.push_back(pair<int,string>(CV_CPU_SSE3, "SSE 3"));
  flags.push_back(pair<int,string>(CV_CPU_SSSE3, "SSSE 3"));
  flags.push_back(pair<int,string>(CV_CPU_SSE4_1, "SSE 4.1"));
  flags.push_back(pair<int,string>(CV_CPU_SSE4_2, "SSE 4.2"));
  flags.push_back(pair<int,string>(CV_CPU_AVX, "AVX"));
  // only for 2.3 or later
  flags.push_back(pair<int,string>(CV_CPU_POPCNT, "POPCOUNT"));

  std::vector< pair<int, string> >::const_iterator it = flags.begin();
  for(; it!=flags.end(); ++it) {
    std::cout << it->second << " is ";
    if(cv::checkHardwareSupport(it->first))
      std::cout << "supported." << std::endl;
    else
      std::cout << "NOT supported." << std::endl;
  }
}

(筆者の環境における)実行結果:

MMX is supported.
SSE is supported.
SSE 2 is supported.
SSE 3 is supported.
SSSE 3 is supported.
SSE 4.1 is NOT supported.
SSE 4.2 is NOT supported.
AVX is NOT supported.
POPCOUNT is NOT supported.

コマンドライン引数をパースする

getopt, gflags, boost/program_options, などコマンドライン引数をパースするための様々な方法がありますが,OpenCV(>=2.3.0)のみを利用しても簡単なパースを行うことができます.

ここでサポートされるシンタックスは以下の通りです.

  • -key1=value1

  • –key2=value2

    “-” または “–” で始まるパラメータに対して値を指定する場合,”=” を利用します.また,値を指定しない場合,それは bool型の値見なされます. パラメータ名には,ショートネームとフルネームのどちらでも利用可能です.

  • key3

    値を取らないパラメータです.

#include <iostream>
#include <opencv2/core/core.hpp>

#define OPENCV_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#define OPENCV_VERSION_CODE OPENCV_VERSION(CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION)

int main( int argc, const char* argv[] )
{
#if OPENCV_VERSION_CODE<OPENCV_VERSION(2,3,1)
    std::cout << "cannot support this opencv version:"
              <<  CV_VERSION << std::endl;
    return -1;
#else

  // {:パーサ文字列の開始
  // }:パーサ文字列の終了
  // |:セパレータ
  // ショートネーム,フルネーム,デフォルト値,ヘルプ文
  const char* keys =
    {
      "{s|string  |123asd   |string parameter}"
      "{d|digit   |100      |digit parameter }"
      "{c|noCamera|false    |without camera  }"
      "{1|        |some text|help            }"
      "{2|        |3.3      |another help    }"
    };
  cv::CommandLineParser parser(argc, argv, keys);
  if(argc==1) {
    parser.printParams();
    return 0;
  }

  // 値をとるパラメータ引数
  // int param_d = parser.get<int>("digit");
  // などとフルネーム書くこともできます.
  std::string param_s = parser.get<std::string>("string");
  int param_d = parser.get<int>("d");
  bool param_c = parser.get<bool>("c");
  // 値を取らない引数
  std::string arg1 = parser.get<std::string>("1");
  double arg2 = parser.get<double>("2");

  std::cout << "string   = " << param_s << std::endl;
  std::cout << "digit    = " << param_d << std::endl;
  std::cout << "noCamera = " << param_c << std::endl;
  std::cout << "arg1 = " << arg1 << std::endl;
  std::cout << "arg2 = " << arg2 << std::endl;
#endif
}

実行結果1(入力,出力):

./sample_commandline_parser
	1 [        ] (   some text - by default) - help            
	2 [        ] (   3.3       - by default) - another help    
	c [noCamera] (   false     - by default) - without camera  
	d [   digit] (   100       - by default) - digit parameter 
	s [  string] (   123asd    - by default) - string parameter

実行結果2(入力,出力):

./sample_commandline_parser -d=99 -c=false -s=image.jpg hoge.dat 3.4
string   = image.jpg
digit    = 99
noCamera = 0
arg1 = hoge.dat
arg2 = 3.4

実行結果3(入力,出力):

./sample_commandline_parser --digit=99 -c -string=image.jpg foo.dat 100.0
string   = image.jpg
digit    = 99
noCamera = 1
arg1 = foo.dat
arg2 = 100

OpenCVのビルド情報を出力する

OpenCV 2.4.0 では,OpenCV の完全なビルド情報を出力できるようになりました.

#include <iostream>
#include <opencv2/core/core.hpp>

#define OPENCV_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#define OPENCV_VERSION_CODE OPENCV_VERSION(CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION)

int
main(int argc, char *argv[])
{
#if OPENCV_VERSION_CODE<OPENCV_VERSION(2,4,0)
    std::cout << "cannot support this opencv version:"
              <<  CV_VERSION << std::endl;
    return -1;
#else
  std::cout << cv::getBuildInformation() << std::endl;
#endif
}

実行結果:

General configuration for OpenCV 2.4.0 =====================================

  Platform:
    Host:                        Linux 2.6.35-22-generic i686
    CMake:                       2.8.2
    CMake generator:             Unix Makefiles
    CMake build tool:            /usr/bin/make
    Configuration:               RELEASE

  C/C++:
    Built as dynamic libs?:      YES
    C++ Compiler:                /usr/bin/c++ (ver 4.4.4)
    C++ flags (Release):         -Wall -pthread -march=i686 -fomit-frame-pointer -msse -msse2 -mfpmath=sse -ffunction-sections -O3 -DNDEBUG   -DNDEBUG
    C++ flags (Debug):           -Wall -pthread -march=i686 -fomit-frame-pointer -msse -msse2 -mfpmath=sse -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG -ggdb3
    C Compiler:                  /usr/bin/gcc
    C flags (Release):           -Wall -pthread -march=i686 -fomit-frame-pointer -msse -msse2 -mfpmath=sse -ffunction-sections -O3 -DNDEBUG  -DNDEBUG
    C flags (Debug):             -Wall -pthread -march=i686 -fomit-frame-pointer -msse -msse2 -mfpmath=sse -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG -ggdb3
    Linker flags (Release):
    Linker flags (Debug):

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

  GUI: 
    GTK+ 2.x:                    YES (ver 2.22.0)
    GThread :                    YES (ver 2.26.1)
    GtkGlExt:                    NO
    OpenGL support:              NO

  Media I/O: 
    ZLib:                        /usr/lib/libz.so (ver 1.2.3)
    JPEG:                        /usr/lib/libjpeg.so (ver 62)
    PNG:                         /usr/lib/libpng.so (ver 1.2.44)
    TIFF:                        /usr/lib/libtiff.so (ver 42)
    JPEG 2000:                   build (ver 1.900.1)
    OpenEXR:                     NO
    OpenNI:                      NO
    OpenNI PrimeSensor Modules:  NO

  Video I/O:
    DC1394 1.x:                  NO
    DC1394 2.x:                  YES (ver 2.1.2)
    GStreamer:                   NO
    UniCap:                      NO
    UniCap ucil:                 NO
    PvAPI:                       NO
    V4L/V4L2:                    YES/YES
    Xine:                        NO
    FFMPEG:                      YES
      codec:                     YES (ver 52.72.2)
      format:                    YES (ver 52.64.2)
      util:                      YES (ver 50.15.1)
      swscale:                   YES (ver 0.11.0)
      gentoo-style:              YES

  Other third-party libraries:
    Use IPP:                     NO
    Use TBB:                     YES (ver 3.0 interface 5000)
    Use Cuda:                    NO
    Use Eigen:                   YES (ver 2.0.15)

  Python:
    Interpreter:                 /usr/bin/python2.6 (ver 2.6.6)
    Libraries:                   /usr/lib/libpython2.6.so
    numpy:                       /usr/lib/python2.6/dist-packages/numpy/core/include (ver 1.3.0)
    packages path:               lib/python2.6/dist-packages

  Documentation:
    Build Documentation:         YES
    Sphinx:                      /usr/bin/sphinx-build (ver 0.6.6)
    PdfLaTeX compiler:           /usr/bin/pdflatex

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

  Install path:                  /usr/local/OpenCV-2.4.0

  cvconfig.h is in:              /home/idojun/Downloads/OpenCV-2.4.0/release
-----------------------------------------------------------------

それよりも以前のバージョンでは,利用できません.

実行結果:

cannot support this opencv version:2.3.1