OpenCV 4.13.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 4.13.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
はじめに

OpenCV (Open Source Computer Vision Library: http://opencv.org) は、数百種類のコンピュータビジョンアルゴリズムを含むオープンソースライブラリである。本ドキュメントでは、いわゆるOpenCV 2.x APIについて説明する。これは本質的にC++ APIであり、CベースのOpenCV 1.x API(C APIは非推奨であり、OpenCV 2.4リリース以降は「C」コンパイラでテストされていない)とは対照的なものである。

OpenCVはモジュール構造を持っており、パッケージにはいくつかの共有ライブラリまたは静的ライブラリが含まれている。次のモジュールが利用できる:

  • コア機能 (core) - 密な多次元配列Matや、他のすべてのモジュールで使われる基本関数など、基本的なデータ構造を定義するコンパクトなモジュール。
  • 画像処理 (imgproc) - 線形・非線形の画像フィルタリング、幾何学的な画像変換(リサイズ、アフィン・透視ワーピング、汎用的なテーブルベースのリマッピング)、色空間変換、ヒストグラムなどを含む画像処理モジュール。
  • 画像ファイルの読み込みと書き込み (imgcodecs) - さまざまな形式の画像ファイルの読み書きを行う関数を含む。
  • ビデオI/O (videoio) - ビデオキャプチャとビデオコーデックに対する使いやすいインターフェース。
  • 高レベルGUI (highgui) - シンプルなUI機能に対する使いやすいインターフェース。
  • 動画解析 (video) - 動き推定、背景差分、物体追跡アルゴリズムを含むビデオ解析モジュール。
  • カメラキャリブレーションと3次元再構成 (calib3d) - 基本的な多視点幾何アルゴリズム、単眼・ステレオカメラのキャリブレーション、物体の姿勢推定、ステレオ対応点探索アルゴリズム、および3D再構成の要素。
  • 2D Features Framework (features2d) - 顕著な特徴検出器、記述子、および記述子マッチャ。
  • 物体検出 (objdetect) - あらかじめ定義されたクラス(例えば顔、目、マグカップ、人、車など)の物体やインスタンスの検出。
  • ディープニューラルネットワークモジュール (dnn) - ディープニューラルネットワークモジュール。
  • 機械学習 (ml) - 機械学習モジュールは、データの統計的分類、回帰、クラスタリングのための一連のクラスと関数を含む。
  • コンピュテーショナルフォトグラフィ (photo) - ノイズ除去や修復(インペインティング)といった高度な写真処理技術。
  • 画像のスティッチング (stitching) - 画像スティッチングとパノラマ作成のための関数。
  • ... FLANNやGoogleテストのラッパー、Pythonバインディングなど、その他のヘルパーモジュール。

本ドキュメントの以降の章では、各モジュールの機能について説明する。ただしその前に、ライブラリ全体で広く使われている共通のAPIの概念に必ず慣れておくこと。

APIの概念

cv名前空間

OpenCVのすべてのクラスと関数は cv 名前空間に配置されている。したがって、自分のコードからこの機能にアクセスするには、cv:: 指定子または using namespace cv; ディレクティブを使う:

#include "opencv2/core.hpp"
...
cv::Mat H = cv::findHomography(points1, points2, cv::RANSAC, 5);
...
Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray(), const int maxIters=2000, const double confidence=0.995)
Finds a perspective transformation between two planes.
@ RANSAC
RANSAC algorithm.
Definition calib3d.hpp:552

または:

#include "opencv2/core.hpp"
using namespace cv;
...
Mat H = findHomography(points1, points2, RANSAC, 5 );
...
n-dimensional dense array class
Definition mat.hpp:840
Definition core.hpp:107

現在または将来のOpenCVの外部名の一部は、STLや他のライブラリと衝突する可能性がある。その場合は、明示的に名前空間指定子を使って名前の衝突を解決する:

Mat a(100, 100, CV_32F);
randu(a, Scalar::all(1), Scalar::all(std::rand()));
cv::log(a, a);
a /= std::log(2.);
void log(InputArray src, OutputArray dst)
Calculates the natural logarithm of every array element.
#define CV_32F
Definition interface.h:78

自動メモリ管理

OpenCVはすべてのメモリを自動的に処理する。

まず第一に、std::vector、cv::Mat、および関数やメソッドで使われるその他のデータ構造は、必要に応じて基底のメモリバッファを解放するデストラクタを持っている。これは、Matの場合のようにデストラクタが常にバッファを解放するわけではないことを意味する。これらはデータ共有の可能性を考慮する。デストラクタは、行列データバッファに関連付けられた参照カウンタをデクリメントする。バッファは、参照カウンタがゼロに達したとき、すなわち他のどの構造も同じバッファを参照していないときに限り解放される。同様に、Matインスタンスがコピーされても、実際のデータはコピーされない。代わりに、同じデータの所有者がもう1つ存在することを記憶するために参照カウンタがインクリメントされる。また、行列データの完全なコピーを作成する cv::Mat::clone メソッドもある。以下の例を参照:

// create a big 8Mb matrix
Mat A(1000, 1000, CV_64F);
// create another header for the same matrix;
// this is an instant operation, regardless of the matrix size.
Mat B = A;
// create another header for the 3-rd row of A; no data is copied either
Mat C = B.row(3);
// now create a separate copy of the matrix
Mat D = B.clone();
// copy the 5-th row of B to C, that is, copy the 5-th row of A
// to the 3-rd row of A.
B.row(5).copyTo(C);
// now let A and D share the data; after that the modified version
// of A is still referenced by B and C.
A = D;
// now make B an empty matrix (which references no memory buffers),
// but the modified version of A will still be referenced by C,
// despite that C is just a single row of the original A
B.release();
// finally, make a full copy of C. As a result, the big modified
// matrix will be deallocated, since it is not referenced by anyone
C = C.clone();
CV_NODISCARD_STD Mat clone() const
Creates a full copy of the array and the underlying data.
void copyTo(OutputArray m) const
Copies the matrix to another one.
Mat row(int y) const
Creates a matrix header for the specified matrix row.
void release()
Decrements the reference counter and deallocates the matrix if needed.
#define CV_64F
Definition interface.h:79

Matやその他の基本構造の使用が簡単であることがわかる。しかし、自動メモリ管理を考慮せずに作成された高水準クラスやユーザー定義データ型についてはどうだろうか。それらのために、OpenCVはC++11のstd::shared_ptrに似た cv::Ptr テンプレートクラスを提供している。そのため、素のポインタを使う代わりに:

T* ptr = new T(...);

次のように書ける:

Ptr<T> ptr(new T(...));
std::shared_ptr< _Tp > Ptr
Definition cvstd_wrapper.hpp:23

または:

Ptr<T> ptr = makePtr<T>(...);

Ptr<T> は、T型インスタンスへのポインタと、そのポインタに関連付けられた参照カウンタをカプセル化する。詳細は cv::Ptr の説明を参照。

出力データの自動割り当て

OpenCVはメモリを自動的に解放するだけでなく、ほとんどの場合、出力関数引数のためのメモリも自動的に割り当てる。したがって、関数が1つ以上の入力配列(cv::Mat インスタンス)といくつかの出力配列を持つ場合、出力配列は自動的に割り当てまたは再割り当てされる。出力配列のサイズと型は、入力配列のサイズと型から決定される。必要に応じて、関数は出力配列の特性を判断するのに役立つ追加の引数を受け取る。

例:

using namespace cv;
int main(int, char**)
{
VideoCapture cap(0);
if(!cap.isOpened()) return -1;
Mat frame, edges;
namedWindow("edges", WINDOW_AUTOSIZE);
for(;;)
{
cap >> frame;
cvtColor(frame, edges, COLOR_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
if(waitKey(30) >= 0) break;
}
return 0;
}
Template class for specifying the size of an image or rectangle.
Definition types.hpp:335
Class for video capturing from video files, image sequences or cameras.
Definition videoio.hpp:786
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3

ビデオフレームの解像度とビット深度はビデオキャプチャモジュールが把握しているため、配列frameは >> 演算子によって自動的に割り当てられる。配列edgesはcvtColor関数によって自動的に割り当てられる。これは入力配列と同じサイズおよびビット深度を持つ。色変換コード cv::COLOR_BGR2GRAY が渡されており、これはカラーからグレースケールへの変換を意味するため、チャンネル数は1である。frameとedgesは、それ以降のすべてのビデオフレームが同じ解像度を持つため、ループ本体の最初の実行時に一度だけ割り当てられることに注意。もし何らかの方法でビデオ解像度を変更すると、配列は自動的に再割り当てされる。

この技術の鍵となる構成要素は cv::Mat::create メソッドである。このメソッドは、希望する配列のサイズと型を受け取る。配列がすでに指定されたサイズと型を持っている場合、メソッドは何もしない。そうでない場合は、以前に割り当てられたデータがあればそれを解放し(この処理には参照カウンタのデクリメントとゼロとの比較が含まれる)、その後、必要なサイズの新しいバッファを割り当てる。ほとんどの関数は各出力配列に対して cv::Mat::create メソッドを呼び出すため、出力データの自動割り当てが実現される。

このスキームの注目すべき例外として、cv::mixChannelscv::RNG::fill、およびその他いくつかの関数やメソッドがある。これらは出力配列を割り当てられないため、事前に自分で割り当てておく必要がある。

飽和演算 (Saturation Arithmetics)

コンピュータビジョンライブラリとして、OpenCVはしばしばチャンネルあたり8ビットまたは16ビットというコンパクトな形式でエンコードされ、そのため値の範囲が限られた画像ピクセルを多く扱う。さらに、色空間変換、明るさ・コントラスト調整、シャープニング、複雑な補間(バイキュービック、Lanczos)といった画像に対する特定の演算は、利用可能な範囲を超える値を生成しうる。結果の下位8(16)ビットだけを保存すると、視覚的なアーティファクトが生じ、その後の画像解析に影響を及ぼす可能性がある。この問題を解決するために、いわゆる飽和 (saturation) 演算が用いられる。例えば、演算結果 r を8ビット画像に保存するには、0..255の範囲内で最も近い値を求める:

\[I(x,y)= \min ( \max (\textrm{round}(r), 0), 255)\]

同様の規則が8ビット符号付き、16ビット符号付きおよび符号なしの型にも適用される。このセマンティクスはライブラリ全体で使われている。C++コードでは、標準的なC++のキャスト演算に似た cv::saturate_cast<> 関数を使って行われる。上で示した式の実装を以下に示す:

I.at<uchar>(y, x) = saturate_cast<uchar>(r);
unsigned char uchar
Definition interface.h:51

ここで cv::uchar はOpenCVの8ビット符号なし整数型である。最適化されたSIMDコードでは、paddusb、packuswbなどのSSE2命令が使われる。これらはC++コードとまったく同じ動作を実現するのに役立つ。

覚え書き
結果が32ビット整数の場合、飽和は適用されない。

固定ピクセル型。テンプレートの限定的な使用

テンプレートは、非常に強力で効率的かつ安全なデータ構造やアルゴリズムの実装を可能にするC++の優れた機能である。しかし、テンプレートを多用すると、コンパイル時間とコードサイズが劇的に増大する可能性がある。さらに、テンプレートだけを使う場合、インターフェースと実装を分離することが難しくなる。これは基本的なアルゴリズムには問題ないが、1つのアルゴリズムが数千行のコードに及ぶこともあるコンピュータビジョンライブラリには適していない。このため、また、テンプレートをまったく持たないか、限られたテンプレート機能しか持たないPython、Java、Matlabといった他言語向けのバインディング開発を簡素化するためにも、現在のOpenCVの実装は、テンプレートよりも多態性と実行時ディスパッチに基づいている。実行時ディスパッチが遅すぎる箇所(ピクセルアクセス演算子など)、不可能な箇所(汎用の cv::Ptr<> の実装)、あるいは単に非常に不便な箇所(cv::saturate_cast<>())では、現在の実装は小さなテンプレートクラス、メソッド、関数を導入している。現在のOpenCVバージョンのそれ以外の場所では、テンプレートの使用は限定的である。

その結果、ライブラリが扱える基本データ型は限られた固定の集合である。すなわち、配列の要素は次の型のいずれかでなければならない:

  • 8ビット符号なし整数 (uchar)
  • 8ビット符号付き整数 (schar)
  • 16ビット符号なし整数 (ushort)
  • 16ビット符号付き整数 (short)
  • 32ビット符号付き整数 (int)
  • 32ビット浮動小数点数 (float)
  • 64ビット浮動小数点数 (double)
  • すべての要素が同じ型(上記のいずれか)である複数要素のタプル。要素がこのようなタプルである配列はマルチチャンネル配列と呼ばれ、要素がスカラ値であるシングルチャンネル配列と対をなす。チャンネル数の最大値は CV_CN_MAX 定数で定義されており、現在は512に設定されている。

これらの基本型に対して、次の列挙が適用される:

enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };
#define CV_8S
Definition interface.h:74
#define CV_8U
Definition interface.h:73
#define CV_32S
Definition interface.h:77
#define CV_16S
Definition interface.h:76
#define CV_16U
Definition interface.h:75

マルチチャンネル(nチャンネル)型は、次のオプションを使って指定できる:

覚え書き
#CV_32FC1 == #CV_32F, #CV_32FC2 == #CV_32FC(2) == #CV_MAKETYPE(CV_32F, 2) であり、#CV_MAKETYPE(depth, n) == ((depth&7) + ((n-1)<<3) である。これは、型を表す定数が、下位3ビットを取るビット深度と、その次の log2(CV_CN_MAX) ビットを取るチャンネル数から1を引いた値とから構成されることを意味する。

例:

Mat mtx(3, 3, CV_32F); // make a 3x3 floating-point matrix
Mat cmtx(10, 1, CV_64FC2); // make a 10x1 2-channel floating-point
// matrix (10-element complex vector)
Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image
// of 1920 columns and 1080 rows.
Mat grayscale(img.size(), CV_MAKETYPE(img.depth(), 1)); // make a 1-channel image of
// the same size and same
// channel type as img
#define CV_8UC3
Definition interface.h:90
#define CV_64FC2
Definition interface.h:125
#define CV_MAKETYPE(depth, cn)
Definition interface.h:85

より複雑な要素を持つ配列は、OpenCVを使って構築したり処理したりすることはできない。さらに、各関数やメソッドは、可能なすべての配列型の一部しか扱えない。通常、アルゴリズムが複雑になるほど、サポートされる形式の部分集合は小さくなる。このような制限の典型的な例を以下に示す:

  • 顔検出アルゴリズムは、8ビットのグレースケール画像またはカラー画像でのみ動作する。
  • 線形代数の関数やほとんどの機械学習アルゴリズムは、浮動小数点配列でのみ動作する。
  • cv::add のような基本関数は、すべての型をサポートする。
  • 色空間変換関数は、8ビット符号なし、16ビット符号なし、32ビット浮動小数点の型をサポートする。

各関数がサポートする型の部分集合は実用上の必要性から定められており、将来的にユーザーの要望に応じて拡張される可能性がある。

InputArrayとOutputArray

多くのOpenCV関数は、密な2次元または多次元の数値配列を処理する。通常、そのような関数は cv::Mat を引数として受け取るが、場合によっては std::vector<>(例えば点集合の場合)や cv::Matx<>(3x3ホモグラフィ行列などの場合)を使う方が便利なこともある。APIにおける多くの重複を避けるため、特別な「プロキシ」クラスが導入されている。基底となる「プロキシ」クラスは cv::InputArray である。これは関数の入力として読み取り専用配列を渡すために使われる。InputArrayから派生したクラス cv::OutputArray は、関数の出力配列を指定するために使われる。通常、これらの中間型を気にする必要はない(また、これらの型の変数を明示的に宣言すべきではない)。すべて自動的にうまく機能する。InputArray/OutputArrayの代わりに、常に cv::Matstd::vector<>cv::Matx<>cv::Vec<>、または cv::Scalar を使えると考えてよい。関数が省略可能な入力配列または出力配列を持ち、それを持っていないか使いたくない場合は、cv::noArray() を渡す。

エラー処理

OpenCVは致命的なエラーを通知するために例外を使う。入力データが正しい形式で指定された値の範囲に属しているにもかかわらず、何らかの理由でアルゴリズムが成功できない場合(例えば最適化アルゴリズムが収束しなかった場合)は、特別なエラーコード(通常は単なるブール変数)を返す。

例外は cv::Exception クラスまたはその派生クラスのインスタンスとなりうる。さらに、cv::Exceptionstd::exception の派生クラスである。そのため、他の標準C++ライブラリのコンポーネントを使ってコード内で適切に処理できる。

例外は通常、#CV_Error(errcode, description) マクロ、またはそのprintf風の #CV_Error_(errcode, (printf-spec, printf-args)) 亜種を使うか、あるいは条件をチェックしてそれが満たされない場合に例外をスローする CV_Assert(condition) マクロを使ってスローされる。性能が重要なコードのためには、Debug構成でのみ保持される CV_DbgAssert(condition) がある。自動メモリ管理のおかげで、突然のエラーが発生した場合でも、すべての中間バッファは自動的に解放される。必要に応じて例外をキャッチするために、try文を追加するだけでよい:

try
{
... // call OpenCV
}
catch (const cv::Exception& e)
{
const char* err_msg = e.what();
std::cout << "exception caught: " << err_msg << std::endl;
}
Class passed to an error.
Definition core.hpp:120
virtual const char * what() const noexcept override

マルチスレッドと再入可能性

現在のOpenCV実装は完全にリエントラント(再入可能)である。すなわち、同じ関数や異なるクラスインスタンスの同じメソッドを異なるスレッドから呼び出せる。また、参照カウント操作にはアーキテクチャ固有のアトミック命令を使用するため、同じMatを異なるスレッドで使用できる。