9

OpenCv2.4の使用

画像を読み込むには2つのオプションがあります。

  1- CvMat and Imread

  2- IpImage and CvLoadImage    

どちらを使用するのが良いですか?2つを混合してみたところ、セグメンテーション違反が発生しました。

4

4 に答える 4

14

imreadMatではなく を返しますCvMat。それらは 2 つの異なるインターフェースです ( C++ の場合はMat/ 、C インターフェースの場合はimreadIpl... および Cv.. )。

C++ インターフェースは、より良く、より安全で、使いやすくなっています。メモリを自動的に処理し、同じタスクのコードを少なくすることができます。OpenCV 関係者は、非常に特定のプロジェクト要件によって C が強制されない限り、C++ の使用を推奨しています。

例 (C++)

cv::Mat image = imread("path/to/myimage.jpg")
if(image.empty())
    return;

cv::imshow("Image", image);

cv::Mat bw = image > 128; // threshold image
cv::Mat crop = image(cv::Rect(0, 0, 100, 100)); // a 100px x 100px crop
crop= 0; // set image to 0

cv::waitKey();
// end code here

特に明記しない限り、すべての行列割り当ては同じデータを参照することに注意してください。上記の例では、crop行列は を指してimageおり、それをゼロに設定すると、 の特定の部分が 0 に設定されimageます。

データの新しいコピーを作成するには、Mat::copyTo または Mat::clone(); を使用します。

そしてCインターフェース

IplImage* pImg = CvLoadImage("path/to/myimage.jpg");
if(pImg == NULL)
    return;

// ... big bloat to do the same operations with IplImage    

CvShowImage("Image", pImg);
cvWaitKey();
CvReleaseImage(&pImg); // Do not forget to release memory.
// end code here
于 2012-06-20T08:38:04.550 に答える
0

IplImage と Mat はどちらも相互変換可能です。

Mat からデータを取得するのは非常に簡単なので、Mat と imread() を使用することをお勧めします。

Mat::data は、1D と値に簡単にアクセスできる実際の行列データへのポインターを返します。http://opencv.itseez.com/modules/core/doc/old_basic_structures.html?highlight=mat#union%20data

さまざまな追跡アルゴリズム (OpenTLD など) のために OpenCV に機械学習の概念を追加する場合は、Mat.data を使用してデータに簡単にアクセスし、実際の行列へのポインターを取得できます。

OpenCV のユーティリティ (CalcOpticalFlowPyrLK など) の多くは、Mat を必要とします。マットを使用することをお勧めします。IplImage は今では古いものです。

于 2012-06-20T10:23:32.990 に答える
0

OpenCV_2 クックブックから:

この構造は、IPL ライブラリー (Intel Image Processing Library) から継承され、現在は IPP ライブラリー (Intel Integrated Performance Primitive ライブラリー) に統合されています。古い C インターフェイスで作成されたコードとライブラリを使用する場合、それらの IplImage 構造を操作する必要がある場合があります。幸いなことに、IplImage を cv::Mat オブジェクトに変換する便利な方法があります。

IplImage* iplImage = cvLoadImage("c:\img.jpg"); cv::Mat image4(iplImage,false);

関数 cvLoadImage は、イメージをロードするための C インターフェイス関数です。cv::Mat オブジェクトのコンストラクターの 2 番目のパラメーターは、データがコピーされないことを示します (新しいコピーが必要な場合は true に設定しますが、false はデフォルト値であるため、省略されている可能性があります)。 IplImage と image4 は同じ画像データを共有します。ここでは、ダングリング ポインターを作成しないように注意する必要があります。このため、IplImage ポインターを OpenCV 2 によって提供される参照カウント ポインター クラスにカプセル化する方が安全です。

cv::Ptr iplImage = cvLoadImage("c:\img.jpg");

それ以外の場合、IplImage 構造体が指すメモリの割り当てを解除する必要がある場合は、明示的に行う必要があります: cvReleaseImage(&iplImage); この非推奨のデータ構造は使用しないでください。代わりに、常に cv::Mat を使用してください。

于 2015-07-08T23:03:48.527 に答える
0

これは、ポインターにどれだけ慣れているかによって異なります。IplImage では、次のようにデータにアクセスできます。

 data[i*widthstep+j*nchannels +k]

ここで、i、j、k はいくつかの整数であり、これは非常に簡単なアプローチです。3次元の通常の行列では、データにアクセスするのはそれほど簡単ではありません. 通常の行列データの場合、アクセスは a[i][j] です

  *(*(a + i) + j) is the value of jth element of ith row in matrix a
于 2012-06-20T11:09:35.390 に答える