Mat-基本イメージコンテナ
4108 ワード
OpenCVは2.0バージョンで新しいC++インタフェースを導入し、自動メモリ管理を利用して問題を解決する新しい方法を提供した.この方法では、管理メモリにこだわる必要はありません.コードが簡潔になります(書くことが少なくなります).しかし、C++インタフェースの唯一の不足は、現在多くの組み込み開発システムがC言語のみをサポートしていることです.したがって,ターゲットがこのような開発プラットフォームでない場合,古い手法を用いる必要はない.
Matについては,まず,(1)手動で空間を開く必要がないこと(2)不要なときにすぐに空間を解放する必要がないことを知っておく必要がある.しかし、手動で行うことは可能です.ほとんどのOpenCV関数は、出力データに手動でスペースを開きます.既存のMatオブジェクトを渡すと、開いたマトリクス空間が再利用されます.つまり、私たちは毎回適切なサイズのメモリを使用してタスクを完了します.
基本的にMatはクラスであり、マトリクスヘッダ(マトリクスサイズ、格納方法、格納アドレスなどの情報を含む)と、すべての画素値を格納するマトリクス(選択した格納方法によって異なる次元であってもよい)を指すポインタとからなる.マトリクスヘッドのサイズは定数値ですが、マトリクス自体のサイズは画像によって異なり、通常はマトリクスヘッドのサイズより数桁大きいです.したがって、プログラム内で画像を転送し、コピーを作成する場合、大きなオーバーヘッドは、情報ヘッダではなくマトリクスによって生じる.OpenCVは画像処理ライブラリであり、大量の画像処理関数を網羅しているため、問題を解決するためにライブラリ内の複数の関数を使用することが多いため、関数に画像を渡すのは日常茶飯事である.同時に、計算量の大きい画像処理アルゴリズムについて議論していることを忘れないでください.そのため、やむを得ない限り、大きな画像をコピーすべきではありません.これはプログラム速度を低下させるからです.
この問題を解決するために,OpenCVは参照カウントメカニズムを用いる.Matオブジェクトごとに独自の情報ヘッダを持つが,同じマトリクスを共有することを考えた.これは、マトリクスポインタを同じアドレスに向けることによって実現される.コピーコンストラクション関数は、情報ヘッダとマトリクスポインタのみをコピーし、マトリクスをコピーしません.
上記のコードのすべてのMatオブジェクトは、最終的には同じデータ行列を指し、唯一のデータ行列を指します.情報ヘッダは異なりますが、いずれかのオブジェクトによって変更されると、他のオブジェクトにも影響します.実際には、異なるオブジェクトは同じデータにアクセスする異なる方法にすぎません.ここでは、データの一部のみを参照する情報ヘッダを作成することもできます.たとえば、関心領域(ROI)を作成するには、境界情報を含む情報ヘッダを作成するだけです.
マトリクスが複数のMatオブジェクトに属している場合、それが不要になった場合、誰がクリーンアップを担当しますか?簡単な答えは、最後に使用したオブジェクトです.カウントメカニズムを参照することによって実現される.いつMatオブジェクトの情報ヘッダをコピーした人がいても、マトリクスの参照回数が増加します.逆に、頭が解放されると、このカウントは1つ減少します.カウント値がゼロの場合、マトリクスはクリーンアップされます.しかし、マトリクス自体(情報ヘッダやマトリクスポインタだけでなく)をコピーしたい場合は、関数clone()やcopyTo()を使用します.
今は変わる
Fまたは
Gは影響しない
Mat情報ヘッダが指す行列.まとめると、覚えておきたいのは OpenCV関数で出力画像のメモリ割り当ては自動的に完了します(特に指定しない場合). OpenCVのC++インタフェースを使用する場合、メモリ解放の問題を考慮する必要はありません. 付与演算子およびコピーコンストラクション関数(ctor)は、情報ヘッダのみをコピーする. は、関数clone()またはcopyTo()を使用して、副画像のマトリクスをコピーする.
Matについては,まず,(1)手動で空間を開く必要がないこと(2)不要なときにすぐに空間を解放する必要がないことを知っておく必要がある.しかし、手動で行うことは可能です.ほとんどのOpenCV関数は、出力データに手動でスペースを開きます.既存のMatオブジェクトを渡すと、開いたマトリクス空間が再利用されます.つまり、私たちは毎回適切なサイズのメモリを使用してタスクを完了します.
基本的にMatはクラスであり、マトリクスヘッダ(マトリクスサイズ、格納方法、格納アドレスなどの情報を含む)と、すべての画素値を格納するマトリクス(選択した格納方法によって異なる次元であってもよい)を指すポインタとからなる.マトリクスヘッドのサイズは定数値ですが、マトリクス自体のサイズは画像によって異なり、通常はマトリクスヘッドのサイズより数桁大きいです.したがって、プログラム内で画像を転送し、コピーを作成する場合、大きなオーバーヘッドは、情報ヘッダではなくマトリクスによって生じる.OpenCVは画像処理ライブラリであり、大量の画像処理関数を網羅しているため、問題を解決するためにライブラリ内の複数の関数を使用することが多いため、関数に画像を渡すのは日常茶飯事である.同時に、計算量の大きい画像処理アルゴリズムについて議論していることを忘れないでください.そのため、やむを得ない限り、大きな画像をコピーすべきではありません.これはプログラム速度を低下させるからです.
この問題を解決するために,OpenCVは参照カウントメカニズムを用いる.Matオブジェクトごとに独自の情報ヘッダを持つが,同じマトリクスを共有することを考えた.これは、マトリクスポインタを同じアドレスに向けることによって実現される.コピーコンストラクション関数は、情報ヘッダとマトリクスポインタのみをコピーし、マトリクスをコピーしません.
Mat A, C; //
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); //
Mat B(A); //
C = A; //
上記のコードのすべてのMatオブジェクトは、最終的には同じデータ行列を指し、唯一のデータ行列を指します.情報ヘッダは異なりますが、いずれかのオブジェクトによって変更されると、他のオブジェクトにも影響します.実際には、異なるオブジェクトは同じデータにアクセスする異なる方法にすぎません.ここでは、データの一部のみを参照する情報ヘッダを作成することもできます.たとえば、関心領域(ROI)を作成するには、境界情報を含む情報ヘッダを作成するだけです.
1
2
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries
マトリクスが複数のMatオブジェクトに属している場合、それが不要になった場合、誰がクリーンアップを担当しますか?簡単な答えは、最後に使用したオブジェクトです.カウントメカニズムを参照することによって実現される.いつMatオブジェクトの情報ヘッダをコピーした人がいても、マトリクスの参照回数が増加します.逆に、頭が解放されると、このカウントは1つ減少します.カウント値がゼロの場合、マトリクスはクリーンアップされます.しかし、マトリクス自体(情報ヘッダやマトリクスポインタだけでなく)をコピーしたい場合は、関数clone()やcopyTo()を使用します.
1
2
3
Mat F = A.clone();
Mat G;
A.copyTo(G);
今は変わる
Fまたは
Gは影響しない
Mat情報ヘッダが指す行列.まとめると、覚えておきたいのは