OpenCV 「core モジュール」について [概要]

1. Core モジュールの概要

この記事では OpenCV の「core」モジュールの概要を,簡潔に述べます.

公式ドキュメント: Core Functionability

OpenCVカテゴリーの各記事では,OpenCV (4.x 系)をベースに 大事な要点・基礎のみを厳選した解説をしています.また,OpenCVの各記事は用語wikiの対応する記事とも連携しているゆえ「CV & OpenCVの基礎」を,勘所だけ省コストに学べる・復習できるはずです .

2. coreモジュールの主要な機能

2節では,元のC++版に基づいて「coreモジュールの主要な機能」のみを整理・リスト化します.

2.1 「画像 & 行列」の Matクラスと,その数値計算・機械学習を提供

元のC++版の「coreモジュール」では,行列データ・画像データを格納する,C++版OpenCVの基本データ構造である「Mat クラス(2.2節)」と,その行列・画像を演算するための,基本的な数値計算クラス・関数が提供されている.

また,基礎的な数値計算や線形代数や機械学習演算(及びそのためのデータ構造)も,core実装されており,以下のものはその代表例である:

  • PCA (主成分分析) ,SVD (特異値分解)
  • K-means クラスタリング
  • cv::min , cv::maxなどの基本的な数値計算系関数.
  • solveLP (Linera Programmingのソルバ)などの基本的な最適化関数.

よって,これらの線形代数・最適化・機械学習だけで済む場合は,OpenCV内だけで完結するので,独自に実装したり,他のC++ライブラリをincludeする必要がない.

このMatクラスのデータ構造にimread/imwrite関数 や videoioモジュールで,画像を読み込み/書き出ししておく.

2.2 Matクラス:画像データと任意の多次元配列・行列の処理を担当

cv::Mat クラスに画像データを格納・計算する場合は「①単一チャンネルのグレー画像」 もしくは 「②3チャンネルのカラー画像」を収納するのが基本です.ここでは詳しく述べませんが,座標(x,y)にアクセスする専用の関数()やポインタアクセスが手段として設けられています.それらを用いると(実装の工夫で苦労せずに)高速な「2重 for loop処理」を楽につくることができます.更には(OpenMPをONにするだけの)簡単な並列化・GPU化も提供されています(2.3節).

ただし,画素値アクセスを自作せずとも,画像フィルタやCannyエッジ検出などが「imgprocモジュール」に最初から提供されています.それらの処理を,イチから自作したり,改良したい開発者・研究者でもないかぎり,提供されているクラスを使うだけで事足りることが多いですが.

また,画像の1 or 3チャンネル配列を扱うMatクラスは,任意の多次元配列を取り扱う,numpyのarrayや Pytorch のTensor的な役割のクラスです.透視投影カメラモデルで用いるような行列なども,

※クラス名が 「Imageクラス」ではなく「Matクラス」であり,Matrix(行列)データ全般を扱う「多次元配列クラス」であることがポイントです.

2.3 その他のユーティリティ機能の提供

公式ドキュメント: Utility and system functions and macros

プログラミングに役立つ,以下のようなユーティリティ機能が用意されています:

  • CommandLineParserクラス: コマンドライン引数のアクセスを管理.
  • TickMeterクラス:経過時間の計測 (※ Python版でも有用)
  • cv::ParallelLoopBodyクラスと parallel_for_:楽な並列化のおまかせ. 
  • Logger : ロギング.
  • XML,YAMLの入出力.
  • cv::Error:エラーメッセージ表記.
  • Exception: 例管理.

3. OpenCV-Pythonでは Matを使わず「 numpy」 依存.

2.1節で書いたように,OpenCV C++版では,独自のcv::Matクラスで行列・画像データや行列演算が提供されています.それに対してOpenCV-Python版では「numpyのarrayオブジェクト で,行列・画像データを格納する」ように設計されています.

これにより「Numpyの関数で計算が済むものは,C++版OpenCVの関数・クラスをバインディングをする必要がなくなった」という設計の妙がある上に,scipyやscikit-learnにpytorchなど「numpy依存の数値計算・機械学習ライブラリ」とOpenCV-pythonが,numpy arraryを通じてシームレースに相互接続できるようになります.

3.1 scikit-imageでは画像データの取り扱いが違う

scikit-imageOpenCV-Python版では,チャンネルや色空間が一致しておらず,「多次元配列・行列データを,2ライブラリ間で相互交換する際」に,注意が必要です (※ ここではその詳しい話まではしません).

この「OpenCV-Pythonとscikit-image間での画像データ形式の不一致」があるので,例えば「Pytorch とOpenCV or scikit-image を一緒に使う場合」でも,OpenCV-Python版か,scikit-imageのどちらか1つだけを使用するのが無難です.

参考記事