Opencvにおけるmat詳細解析

5444 ワード

##1、起源OpenCVは強力なコンピュータ視覚のオープンソースライブラリとして、MatLabの実現の詳細と風格を大いに参考した.例えば、OpenCV 2.xバージョン以降、MatLabが持つ機能を実現する関数が増え、いっそ関数名までそっくり(imread、imshow、imwriterなど)になった.このやり方は、製品開発と学術研究の距離を縮めただけでなく、開発者の研究開発効率を極めて高めた.Intel社は本当に偉大な会社だと言わざるを得ない.
コンピュータメモリでは、デジタル画像はマトリクスの形で記憶され、演算される.例えば、MatLabでは、画像読取後にマトリクスが対応し、OpenCVでも同様である.
初期のOpenCV 1.xバージョンでは、画像の処理は、Intelの別のオープンソースライブラリIntel Image Processing Libraryに由来するIplImage構造によって実現される.初期のOpenCVはC言語で書かれていたので、提供された言い訳もC言語インタフェースであり、そのソースコードは完全にCのプログラミングスタイルである.IplImage構造はOpenCV行列演算の基本データ構造である.
OpenCV 2へxバージョンでは、OpenCVオープンソースライブラリはオブジェクト向けのプログラミング思想を導入し、大量のソースコードはC++で書き換えられ、Matrixクラス(Matrixの略)はOpenCVが画像を処理するために導入されたパッケージクラスである.機能的に言えば、MatクラスはIplImage構造に基づいてさらに強化され、また、C++の高度なプログラミング特性を導入することでMatクラスの拡張性が大幅に向上し、Matクラスの内容は後期のバージョンで絶えず豊富になり、Matクラスの定義を見ると(OpenCV 3.1sourcesmodulescoreincludeopencv 2coremat.hpp)、その設計の実現が非常に全面的で具体的であることがわかります.画像処理に対するコンピュータの視覚の基本的な要求を基本的にカバーする.Inheritanceの継承:
[外部チェーン画像の転送に失敗しました(img-4 eW 220 lz-156298915046)](http://7xiomr.com1.z0.glb.clouddn.com/classcv_1_1Mat.png)##2、コンストラクタ
	//        Mat A;
 	Mat ()
 	//        Mat A(10,10,8UC3);
 	Mat (int rows, int cols, int type)
  	
 	//Mat A(300, 400, CV_8UC3,Scalar(255,255,255));
 	Mat (int ndims, const int *sizes, int type, const Scalar &s)
 	
 	Mat (Size size, int type)
 
 	Mat (int rows, int cols, int type, const Scalar &s)
 
 	Mat (Size size, int type, const Scalar &s)
 
 	Mat (int ndims, const int *sizes, int type)

 	Mat (const Mat &m)
 
 	Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
 
 	Mat (Size size, int type, void *data, size_t step=AUTO_STEP)
 
 	Mat (int ndims, const int *sizes, int type, void *data, const size_t *steps=0)
 
 	Mat (const Mat &m, const Range &rowRange, const Range &colRange=Range::all())
 
	//Mat D (A, Rect(10, 10, 100, 100) );
 	Mat (const Mat &m, const Rect &roi)
 
 	Mat (const Mat &m, const Range *ranges)

##3、初期化は1つのMatファイルを初期化して、普通は2種類の形式があります:
// 1、imread
Mat src = imread("csdn.png");

//2、create
Mat src;
if(src.empty())
{
	src.create(Size size, VC_8UC3);
}

##3、Mat構造まずMat構造を見てみましょう.Mat構造を初期化するとき、そのすべての構造はこうです.Matクラスは,マトリクスヘッダと画素データを指すマトリクスポインタの2つの部分に分けられる.[外部リンク画像の転送失敗(img-Si 6 EmAtV-1562988915047)](http://7xiomr.com1.z0.glb.clouddn.com/MAT.PNG)] ###1.flags[外部チェーン画像の転送に失敗しました(img-AodENgAB-156298915047)(http://7xiomr.com1.z0.glb.clouddn.com/mat_flag.png)]定義からflagsはintタイプで32ビットを占めていることがわかりますが、上図を見ると皆さんが代表する意味がわかります.
下位から上位へ:
0-2ビットはdepthであるデータ型(例えばCV_8 U)を表し、OpenCVのデータ型は全部で7種類あるため、3ビットで全て表すことができる.
3-11ビットはチャネル数channelsを表し、OpenCVのデフォルト最大チャネル数は512であるため、9ビットで全て表すことができ、以下のチャネル数を求める部分を参照することができる.
0-11ビットはtype、すなわちチャネル数およびデータ型(CV_8 UC 3など)を共通に表す
12-13位しばらく役に立たなかったが、残しておいたのか、発見してから補充した.
14ビットはMatのメモリが連続しているかどうかを表し、creatによって作成されるmatは一般的に連続しており、連続している場合はデータへのアクセスが速くなります.
15ビットは、そのMatがいずれかのMatであるか否かを表すsubmatrixであり、一般的にROIおよびrow()、col()、rowRange()、colRange()等により得られるmatはsubmatrixである.
16-31はmagic signatureを表し、MatとSparseMatが
もっと細かい分析はこの文章flagsを推薦します
###2.dims
int cv::Mat::dims   ()  const

the matrix dimensionality>=2行列の次元数ですが、opencvは多次元行列を格納するのも2次元行列で計算されるようで、基本的なchannelsとは違います.
###3.channels
int cv::Mat::channels   ()  const

画像のチャネル数を返します.####4.cols rows
int cv::Mat::cols; //       

int cv::Mat::rows //       

###5.data
uchar* cv::Mat::data //             

###6.refcount refcountこのマトリクスのデータが他の変数に何回参照されたかを記録します.c++のマトリクスのいくつかの付与操作は、新しい変数に新しいヘッダファイルのみを付与し、データ部分はメモリに再分割せずにデータポインタだけを指し、プログラマがメモリを管理する必要があります.元の変数のデータメモリが解放されたのに、新しい変数がまだ存在し、解放されたメモリ領域を指しているため、新しい変数を操作すると、予想外の問題が発生する可能性が高いため、危険があります.しかし、心配しないでください.OpenCVの開発者はとっくにこの問題を考えていて、このrefcountでデータがどれだけの変数で共有されているかを記録して、最後の変数が解放されるまで、このストレージデータのメモリブロックを解放する解決方法を考えています.これもクラス定義でrefcountがポインタであり,実際の記録回数の変数をマトリクスデータの一番後ろに付ける理由である.画像画素データを保存するマトリクスは、画像のサイズに応じて変化し、通常はデータ量が大きく、マトリクスヘッダより数桁大きい.このように、画像の複製および伝達の過程において、主なオーバーヘッドは、画像画素を格納するマトリクスに起因する.したがって、OpenCVは参照回数を使用しており、画像のコピーと転送を行うと、Matデータ全体をコピーするのではなく、マトリクスヘッダと画素マトリクスを指すポインタだけをコピーしますが、マトリクスポインタは同じマトリクスを指しています.つまり、いずれかがマトリクスデータを変更すると、他のマトリクスに影響します.では、複数のMatが1つのマトリクスデータを共有し、最後に誰がマトリクスデータを解放しますか?これが参照カウントの役割であり、Matオブジェクトがコピーされるたびに参照カウントに1が加算され、Matオブジェクトが破棄されるたびに(同じマトリクスデータを共有する)参照カウントが1減少し、参照カウントが0になるとマトリクスデータがクリーンアップされます.これがrefcountの役割です.###7.datastart dataend datalimit
const uchar* cv::Mat::dataend
const uchar* cv::Mat::datalimit
const uchar* cv::Mat::datastart

helper fields used in locateROI and adjust ROIこれらは、ROI領域を制御して、いくつかの画像のローカルスライスを取得し、計算量や特殊なニーズを減らすために使用されます.
cv::Rect rect(100, 100, 100, 100); 

srcImage(rect).copyTo(roiImage); 

###8.allocator custom allocator新しいマトリクスのメモリ領域を作成する必要がある場合、メモリの割り当てのためにMatAllocatorクラスが呼び出されます.
###9.size
MatSize cv::Mat::size //       

###10.Stepマトリクス要素アドレス
addr(Mi0,...,iM.dims−1)=M.data+M.step[0]∗i0+M.step[1]∗i1+...+M.step[M.dims−1]∗iM.dims−1

Step[i]はMatクラスにおいて非常に重要な属性であり、i次元の総サイズを表し、単位バイトM.dataはこの列を格納するヘッダアドレス(配列名に類似)M.dimsが総次元であることを指す.
##もっと複雑な詳細はもっともっと
暇は公众号《算故为法》を书いて、本公众号は実は主に基础を固めて、后期の后でいくつか视野型の文章をしていくつか発展の前言に関心を持つことを书いて、しかし私と多くの同業者の交流の学习の过程の中で私は多くの学者がただ応用层に触れたことを発见して、理论の层は极度に不足して、本公众号は基础理论の知识を分かち合って整理して同業者にもよろしくお願いします.最后に、みんなの関心を歓迎して、あなたの関心は私の绝えず更新する动力です!