6 その他の機能

6.1 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

6.2 処理時間を計測する

#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]

6.3 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)

6.4 CV_Assert/CV_DbgAssert

#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 !!

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

#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.