3

こんにちは、opencv について基本的な質問があります。cv::Mat クラスでメモリを割り当てようとすると、次のことができます。

cv::Mat sumimg(rows,cols,CV_32F,0);
float* sumimgrowptr = sumimg.ptr<float>(0);

しかし、その後、不良ポインター (Null) が返されます。インターネットでは、これを使用する人がいます:

cv::Mat* ptrsumimg = new cv::Mat(rows,cols,CV_32F,0);
float* sumimgrowptr = ptrsumimg->ptr<float>(0);

また、ここで Null ポインターが返されます。しかし、私が最終的にこれを行うと:

            cv::Mat sumimg;
            sumimg.create(rows,cols,CV_32F);
            sumimg.setTo(0);
            float* sumimgrowptr = sumimg.ptr<float>(0);

その後、すべてが大丈夫です!だから、私がやっていることの何が悪いのか知りたいですか?

4

2 に答える 2

24

一番の問題はここ

cv::Mat sumimg(rows,cols,CV_32F,0);

OpenCV は、行列の複数のコンストラクターを提供します。そのうちの 2 つは、次のように宣言されています。

cv::Mat(int rows, int cols, int type, SomeType initialValue);

cv::Mat(int rows, int cols, int type, char* preAllocatedPointerToData);

ここで、次のように Mat を宣言すると:

cv::Mat sumimg(rows,cols,CV_32F,5.0);

5.0 で割り当てられ、初期化された float の行列を取得します。呼び出されるコンストラクターは最初のものです。

しかし、ここで

cv::Mat sumimg(rows,cols,CV_32F,0);

送信するのは で0、これは C++ では有効なポインター アドレスです。そのため、コンパイラは事前に割り当てられたデータのコンストラクターを呼び出します。何も割り当てません。また、そのデータ ポインターにアクセスする場合は、当然のことながら、0 または NULL です。

解決策は、4 番目のパラメーターが float であることを指定することです。

cv::Mat sumimg(rows,cols,CV_32F,0.0);

しかし、最善の方法は、cv::Scalar() を使用して初期化することにより、このような状況を回避することです。

cv::Mat sumimg(rows,cols,CV_32F, cv::Scalar::all(0) );
于 2012-07-06T12:15:53.953 に答える
2

と. _ Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP)_cv::Mat sumimg(rows,cols,CV_32F,0);cv::Mat* ptrsumimg = new cv::Mat(rows,cols,CV_32F,0);

ドキュメントを参照してください: http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat

つまり、マトリックスの値を作成していません。つまり、マトリックス内の値にスペースを割り当てていないため、実行NULL時にポインターを受け取ります。

ptrsumimg->ptr<float>(0);

于 2012-07-06T12:10:56.433 に答える