連載
» 2016年08月17日 05時00分 公開

OpenCV入門【3.0対応】:第5回 初めてのOpenCV開発 ― coreモジュール【OpenCV 3.1.0】 (2/2)

[@dandelion1124,著]
前のページへ 1|2       

3. UMatクラス

 OpenCV 3.0よりCPU/GPU実装のカプセル化を行うための仕組みであるT-API(Transparent API)が導入されました。そのためOpenCVユーザーは、T-APIで提供されるUMatと呼ばれるデータ構造を用いて実装することでCPU/GPUどちらでも動作する処理を同一コードで記述できます。

3.1 UMatの内部処理

 図1にUMatを用いた場合の内部処理の概要を示します。

UMatの内部処理 図1 UMatの内部処理

 この図を文章で説明すると、以下のような流れになります。

  1. OpenCL*1が使える環境かどうかをチェックする
  2. OpenCLが使える環境であればOpenCVで用意しているOpenCL実装を用い、そうでなければMatの実装を用いる

 ただし、図1の青で囲んだ内部処理はOpenCV内部に隠ぺいされているため、OpenCVユーザーがこれらの処理を記述する必要はありません。

*1 OpenCL(Open Computing Language)は、並列コンピューティングのためのクロスプラットフォーム対応フレームワークです。「OpenCVとは? 最新3.0の新機能概要とモジュール構成」でも紹介しています。


 また、図2は、CVPR 2015チュートリアルで紹介されているT-APIの計測結果です。

T-APIによる高速化 図2 T-APIによる高速化(CVPR 2015チュートリアル資料から引用)

 この結果より、UMat(OpenCL)を用いることで、Matを用いた場合に比べて高速化できていることが分かります。ただし、CPU、GPUのスペック含め、計測環境によって効果は異なるので高速化の度合いはあくまで参考程度とした方がよいでしょう。

 UMatを使ってグレースケール化を行うサンプルコードを以下に示します。

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>

#include <iostream>

int main(int argc, char *argv[])
{
  // (1)画像データをファイル(この例では「lena.jpg」)から読み込む
  cv::Mat img = cv::imread("lena.jpg", cv::IMREAD_COLOR);

  // 画像の読み込みに失敗したらエラー終了する
  if (img.empty())
  {
    std::cerr << "Failed to open image file." << std::endl;
    return -1;
  }

  // (2)UMatのインスタンスを定義する
  cv::UMat u_img, u_gray;

  // (3)MatのデータをUMatのインスタンスにコピーする
  img.copyTo(u_img);

  // (4)UMatのインスタンスを用いてグレースケール化を行う
  cv::cvtColor(u_img, u_gray, cv::COLOR_BGR2GRAY);

  return 0;
}

UMatクラスを使ったサンプルプログラム

 また、UMatついて詳しく知りたい方は以下のURLの記事も参照ください。

4. ユーティリティ関数

 OpenCVのcoreモジュールには便利なユーティリティ関数が用意されています。この章では、以下のユーティリティ関数について紹介します。それ以外の関数については「公式ドキュメント(OpenCV 3.1.0)(英語)」を参照ください。

関数名 機能
cv::getBuildInformation OpenCVのビルド情報を表示する
cv::checkHardwareSupport CPU機能を取得する
coreモジュールに用意されている便利なユーティリティ関数

4.1 cv::getBuildInformation関数

 OpenCVはユーザー自身で機能をカスタマイズしてビルドすることができます。そのため、公式にbugを報告する場合など、ビルド情報(ユーザーがOpenCVをビルドした環境、コンパイラー、依存ライブラリのバージョン、カスタマイズ情報など)をできるだけ正しく伝えることが重要になります。

 そのような理由から、OpenCVにはビルド情報を取得するためのcv::getBuildInformationというユーティリティ関数が用意されています。この関数を使ったサンプルプログラムは以下の通りです。

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

int main(int argc, const char* argv[])
{
  // ビルド情報を表示する
  std::cout << cv::getBuildInformation() << std::endl;

  return 0;
}

cv::getBuildInformationユーティリティ関数を使ったサンプルプログラム

 また、上記サンプルプログラムの出力結果(抜粋)を以下に示します。ユーザーの環境、ビルド設定によって表示は異なる場合があります。

General configuration for OpenCV 3.1.0 =====================================
  Platform:
    Host:                        Windows 10.0.10586 AMD64
    CMake:                       3.4.1
    CMake generator:             Visual Studio 12 2013 Win64
    CMake build tool:            C:/Program Files (x86)/MSBuild/12.0/bin/MSBuild.exe
    MSVC:                        1800

  Media I/O:
    ZLib:                        build (ver 1.2.8)
    JPEG:                        build (ver 90)
    WEBP:                        build (ver 0.3.1)
    PNG:                         build (ver 1.6.19)
    TIFF:                        build (ver 42 - 4.0.2)
    JPEG 2000:                   build (ver 1.900.1)
    OpenEXR:                     build (ver 1.7.1)
    GDAL:                        NO

  Parallel framework:            TBB (ver 4.4 interface 9002)

  Other third-party libraries:
    Use IPP:                     9.0.1 [9.0.1]
         at:                     C:/dev/opencv-3.1.0/3rdparty/ippicv/unpack/ippicv_win
    Use IPP Async:               NO
    Use Eigen:                   YES (ver 3.2.7)
    Use Cuda:                    YES (ver 7.5)
    Use OpenCL:                  YES
    Use custom HAL:              NO
-----------------------------------------------------------------


上記のサンプルプログラムの出力結果(抜粋)

 「Platform」から、OpenCVのビルドに用いたコンパイラーやCMakeのバージョンなどが分かります。前述の出力例の場合、

Platform:
  Host:                        Windows 10.0.10586 AMD64
  CMake:                       3.4.1
  CMake generator:             Visual Studio 12 2013 Win64


Platformに関する出力のみ抜粋

という表示が行われているため、

  • Windows 10(64bit)上でビルドが行われた
  • CMake 3.4.1を使用した
  • コンパイラーはVisual Studio 2013(x64ビルド)を使用した

ということが読み取れます。

 同様に「Media I/O」からは、各種画像フォーマットをエンコード/デコードするためのライブラリの導入状況、「Other third-party libraries」からは各種並列処理フレームワークなどの導入状況を把握することができます。

4.2 cv::checkHardwareSupport関数

 OpenCVにはCPU機能を取得するcv::checkHardwareSupportというユーティリティ関数が用意されています。指定したCPU機能をサポートしている場合、checkHardwareSupport関数はtrueを返します。

 また、この関数でサポート状況を取得できるCPU機能は以下の通りです。

定義名 対応するCPU機能
CV_CPU_MMX MMX
CV_CPU_SSE SSE
CV_CPU_SSE2 SSE2
CV_CPU_SSE3 SSE3
CV_CPU_SSSE3 SSSE3
CV_CPU_SSE4_1 SSE4.1
CV_CPU_SSE4_2 SSE4.2
CV_CPU_POPCNT POPCOUNT
CV_CPU_AVX AVX
CV_CPU_AVX2 AVX2
CV_CPU_NEON NEON
cv::checkHardwareSupport関数でサポート状況を取得できるCPU機能

 この関数を使ってCPUがSSE2をサポートしているかを調べるサンプルプログラムは以下の通りです。

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

int main(int argc, const char* argv[])
{
  // SSE2をサポートしているCPUかどうかをチェックする
  bool hasSSE2 = cv::checkHardwareSupport(CV_CPU_SSE2);

  // チェック結果を表示する
  std::cout << "hasSSE2: " << hasSSE2 << std::endl;

  return 0;
}

cv::checkHardwareSupport関数を使ってCPUがSSE2をサポートしているかを調べるサンプルプログラム

4.3 その他のユーティリティ関数

 coreモジュールにはエラー処理、並列処理、排他処理を記述するための機能も用意されています。詳細を知りたい方は筆者がまとめた以下の記事を参照ください。

 また、ここでは触れていませんがOpenCVをOpenGLやDirectXと連携するためのユーティリティ機能も用意されています。詳細は以下の公式ドキュメントを参照ください。

5. おわりに

 今回は、OpenCVのcoreモジュールを紹介しました。次回は、imgcodecsモジュール、highguiモジュールの機能について例を用いながら解説します。

「OpenCV入門【3.0対応】」のインデックス

OpenCV入門【3.0対応】

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。