OpenCV 3.0よりCPU/GPU実装のカプセル化を行うための仕組みであるT-API(Transparent API)が導入されました。そのためOpenCVユーザーは、T-APIで提供されるUMatと呼ばれるデータ構造を用いて実装することでCPU/GPUどちらでも動作する処理を同一コードで記述できます。
図1にUMatを用いた場合の内部処理の概要を示します。
この図を文章で説明すると、以下のような流れになります。
ただし、図1の青で囲んだ内部処理はOpenCV内部に隠ぺいされているため、OpenCVユーザーがこれらの処理を記述する必要はありません。
*1 OpenCL(Open Computing Language)は、並列コンピューティングのためのクロスプラットフォーム対応フレームワークです。「OpenCVとは? 最新3.0の新機能概要とモジュール構成」でも紹介しています。
また、図2は、CVPR 2015チュートリアルで紹介されているT-APIの計測結果です。
この結果より、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ついて詳しく知りたい方は以下のURLの記事も参照ください。
OpenCVのcoreモジュールには便利なユーティリティ関数が用意されています。この章では、以下のユーティリティ関数について紹介します。それ以外の関数については「公式ドキュメント(OpenCV 3.1.0)(英語)」を参照ください。
関数名 | 機能 |
---|---|
cv::getBuildInformation | OpenCVのビルド情報を表示する |
cv::checkHardwareSupport | CPU機能を取得する |
coreモジュールに用意されている便利なユーティリティ関数 |
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;
}
また、上記サンプルプログラムの出力結果(抜粋)を以下に示します。※ユーザーの環境、ビルド設定によって表示は異なる場合があります。
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
という表示が行われているため、
ということが読み取れます。
同様に「Media I/O」からは、各種画像フォーマットをエンコード/デコードするためのライブラリの導入状況、「Other third-party libraries」からは各種並列処理フレームワークなどの導入状況を把握することができます。
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;
}
coreモジュールにはエラー処理、並列処理、排他処理を記述するための機能も用意されています。詳細を知りたい方は筆者がまとめた以下の記事を参照ください。
また、ここでは触れていませんがOpenCVをOpenGLやDirectXと連携するためのユーティリティ機能も用意されています。詳細は以下の公式ドキュメントを参照ください。
今回は、OpenCVのcoreモジュールを紹介しました。次回は、imgcodecsモジュール、highguiモジュールの機能について例を用いながら解説します。
Copyright© Digital Advantage Corp. All Rights Reserved.