【OpenCV&4を逐次漸進的に習得する】2.0のAPIを使用して画像を表示し、OpenCVの自動メモリ管理を行う


1.0表示画像と2.0表示画像の比較
【OpenCV&2】画像を表示するOpenCVの「起手式」という文章では、OpenCV 1.0のAPIを使用してディスクからファイルを読み取り、表示します.以下はコードです.
#incldue "cv.h"
#include "highgui.h"

int main(int argc, char** argv)
{
    IplImage* img = cvLoadImage(argv[1]);
    cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE);
    cvShowImage("Example1", img);
    cvWaitKey(0);
    cvReleaseImage(&img);
    cvDestroyWindow("Example1");
}

上から明らかなCスタイルのコードであることがわかります.まず、ポインタを割り当てられたメモリデータに向け、cvReleaseImageのようなメモリを解放します.しかし、2.0のAPIでは、Open CV 2のため、そう書かなくてもいいです.0バージョンでは、メモリ管理を自動化できます.
次に、2.0のAPIを使用して、画像の表示を実現します.
#include "highgui.h"
#include "cv.h"
using namespace cv;

int main() {
 char* name = "fruits.jpg";
 char* window = "    ";
 //        Mat
 Mat mat = imread(name);
 //       
 namedWindow(window);
 //     
 imshow(window, mat);
 //           
 waitKey(0);
 return 0;
}

効果図は貼らないで、もちろん成功しました.コードのロジックと1.0の差は多くありませんが、メモリを解放するコードが少なくなっただけです.2.0のOpenCVは自動化メモリ管理を実現しているからです.
OpenCV 2.0の自動メモリ管理
OpenCVはすべてのメモリに対して自動化管理を実施する.まず、std::vector、Mat、その他のデータ構造には、必要に応じて最下位のメモリバッファを解放する独自の構造関数があります.これは、構造関数が常にキャッシュを解放するわけではないことを意味します.
Matを例にとると、2つのデータ部分、マトリクスヘッダ、およびすべての画素値を格納するマトリクスへのポインタを含むクラスです.マトリクスヘッドの大きさは定数値であり、マトリクスの大きさは画像の大きさに関係し、一般的にマトリクスヘッドより数桁大きい.OpenCVでは、大量の画像処理を行うため、関数にMatを渡すこともしばしばありますが、この場合、転送ごとに画像マトリクスが占有するメモリを1枚ずつコピーすると、処理速度が遅くなります.したがって、特別な要求がない限り、画像データを伝達すべきではない.
したがって、MatをコピーするときにOpenCVは、画像マトリクスに新しいメモリを割り当てるのではなく、Matにポインタを作成します.そしてカウントメカニズムを引用し、Matが同じ画像マトリクスへの参照を追加するたびに、カウントに1を加える.リリース後、カウントが1減少します.カウントが0の場合、ポインタがないことを示し、メモリを解放します.したがって、OpenCV 2.0メモリを自動的に管理できます.
次に例を示します.
void mat() {
 //     8M    
 Mat A(1000, 1000, CV_64F);
 //            
 //          ,           .
 Mat B = A;
 //        ,    A    ;          
 Mat C = B.row(3);
 // clone        ,            
 Mat D = B.clone();
 // copyTo         ,   A、B、C            
 //             5      3 
 B.row(5).copyTo(C);
 //    A D    ;   A     B C   
 A = D;
 //   B (        ),
 //  A        C    ,  C      
 B.release();
 //   ,    C     , C       ;  , A          ,
 //       ,          
 C = C.clone();
}

Ptr紹介
上のMatはOpenCVで自動メモリ管理を実現しているので使いやすいです.しかし、高レベルのクラスとユーザー定義のクラスに対して、自動化メモリ管理を実現するにはどうすればいいのでしょうか.OpenCVは、これらのクラスにもC++STL標準ライブラリに似たPtr<>テンプレートクラスを提供します.元のポインタの代わりに使用するだけでいいです.
T* ptr = new T(...);
//   :
Ptr<T> ptr = new T(...);