web-dev-qa-db-ja.com

多次元cv :: Matのサイズを取得するにはどうすればよいですか? (マット、またはマットND)

多次元MATオブジェクトを作成していて、オブジェクトのサイズを取得したい-たとえば、

const int sz[] = {10,10,9};
Mat temp(3,sz,CV_64F);
std::cout << "temp.dims = " << temp.dims << " temp.size = " << temp.size() << " temp.channels = " << temp.channels() << std::endl;

結果のMATは10x10x9であると思います。確認したいのですが、COUTステートメントでは次のようになります。

temp.dims = 3 temp.size = [10 x 10] temp.channels = 1

私はどちらかを見たいと思っていました:

temp.dims = 3 temp.size = [10 x 10 x 9] temp.channels = 1

または:

temp.dims = 3 temp.size = [10 x 10] temp.channels = 9

このMatオブジェクトの次元を取得するにはどうすればよいですか? Mat :: MatまたはMatNDにはメソッドがありませんでした

20
Pete

OpenCV C++ APIの多くの欠陥の1つであることがわかりました。

OpenCVバージョン2.4.6.1のソースコードを見ると、_cv::Mat::size_が_cv::Mat::MSize_型のメンバーオブジェクトであることがわかります。

_struct CV_EXPORTS MSize
{
    MSize(int* _p);
    Size operator()() const;
    const int& operator[](int i) const;
    int& operator[](int i);
    operator const int*() const;
    bool operator == (const MSize& sz) const;
    bool operator != (const MSize& sz) const;

    int* p;
};
_

したがって、cv::Mat::size()は実際にはcv::Mat::MSize::operator ()()を参照し、その戻り値の型Sizeは次のように定義されます

_typedef Size_<int> Size2i;
typedef Size2i Size;
_

OpenCVマニュアル から引用すると、Size

"画像または長方形のサイズを指定するためのテンプレートクラス。クラスには、幅と高さという2つのメンバーが含まれます。"

つまり、Sizeは2D行列にのみ適しています。

幸い、すべての希望が cv::Mat::MSize::operator [](int i)を使用してi-th次元

_const int sz[] = {10,10,9}; 
cv::Mat temp(3,sz,CV_64F); 
std::cout << "temp.dims = " << temp.dims << "temp.size = [";
for(int i = 0; i < temp.dims; ++i) {
    if(i) std::cout << " X ";
    std::cout << temp.size[i];
}
std::cout << "] temp.channels = " << temp.channels() << std::endl;
_

temp.dims = 3 temp.size = [10 x 10 x 9] temp.channels = 1

31
brunocodutra

OpenCV 2.4.9は多次元サイズを問題なく処理します。 structcv::Mat::MSizeは、複数の次元を格納して返すことができます。データメンバーcv::Mat::sizeはタイプcv::Mat::MSize。このコードはあなたのために次元を列挙します:

const int sz[] = {3, 4, 3, 6};
cv::Mat bigm(4, sz, CV_8UC1);
cout << bigm.dims << '\t';
for (int i=0; i<bigm.dims; ++i)
  cout << bigm.size[i] << ',';
cout << endl;

出力は次のとおりです。

4       3,4,3,6,
14
Sameer
std::vector<size_t> getMatDims(const cv::Mat& m)
{
    std::vector<size_t> dims(m.dims);
    std::partial_sum(&m.step[0],&m.step[0]+m.dims,dims.begin(),[](size_t a,size_t b){ return a/b; });
    return dims;
}
1
Steve132