39

OpenCV Mat 要素の型に混乱しています。これはドキュメントからのものです:

There is a limited fixed set of primitive data types the library can operate on.
That is, array elements should have one of the following types:

8-bit unsigned integer (uchar) 
8-bit signed integer (schar)
16-bit unsigned integer (ushort)
16-bit signed integer (short)
32-bit signed integer (int)
32-bit floating-point number (float)
64-bit floating-point number (double)
...

For these basic types, the following enumeration is applied:
enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };

C++ 標準では基本型のサイズをバイト単位で定義していないことが知られています。そして、CV_32S としましょう。それは int32_t ですか、それとも int ですか?

4

6 に答える 6

7

Miki's answerから開発して、
OpenCV 3 の定義は modules/core/include/opencv2/core/ traits.hppに移動しました。

/** @brief A helper class for cv::DataType

The class is specialized for each fundamental numerical data type supported by OpenCV. It provides
DataDepth<T>::value constant.
*/
template<typename _Tp> class DataDepth
{
public:
    enum
    {
        value = DataType<_Tp>::depth,
        fmt   = DataType<_Tp>::fmt
    };
};



template<int _depth> class TypeDepth
{
    enum { depth = CV_USRTYPE1 };
    typedef void value_type;
};

template<> class TypeDepth<CV_8U>
{
    enum { depth = CV_8U };
    typedef uchar value_type;
};

template<> class TypeDepth<CV_8S>
{
    enum { depth = CV_8S };
    typedef schar value_type;
};

template<> class TypeDepth<CV_16U>
{
    enum { depth = CV_16U };
    typedef ushort value_type;
};

template<> class TypeDepth<CV_16S>
{
    enum { depth = CV_16S };
    typedef short value_type;
};

template<> class TypeDepth<CV_32S>
{
    enum { depth = CV_32S };
    typedef int value_type;
};

template<> class TypeDepth<CV_32F>
{
    enum { depth = CV_32F };
    typedef float value_type;
};

template<> class TypeDepth<CV_64F>
{
    enum { depth = CV_64F };
    typedef double value_type;
};

ほとんどの場合/コンパイラでは、 C ++ の正確なデータ型を使用しても問題ありません。C++ で明確に定義されCV_8Uているように、シングル バイト データ型 ( ->uint8_tおよびCV_8U-> int8_t)に問題はありません。float (32bit) と double (64bit)についても同じです。ただし、他のデータ型が正しいデータ型を使用していることを完全に確認するには (メソッドを使用する場合など)、次の例を使用する必要があります。at<>

typedef TypeDepth<CV_WHATEVER_YOU_USED_TO_CREATE_YOUR_MAT>::value_type access_type;
myMat.at<access_type>(y,x) = 0;

余談ですが、正確なデータ型を単純に使用するのではなく、このようなあいまいなアプローチを取ることにしたことに驚いています。

したがって、最後の質問に関して:

たとえば、どのタイプから期待する必要がありCV_32Sますか?

OpenCV 3 での最も正確な答えは次のとおりだと思います。

TypeDepth<CV_32S>::value_type
于 2016-05-27T13:36:38.737 に答える
4

ではcore.hpp、次の項目を見つけることができます。

/*!
  A helper class for cv::DataType

  The class is specialized for each fundamental numerical data type supported by OpenCV.
  It provides DataDepth<T>::value constant.
*/
template<typename _Tp> class DataDepth {};

template<> class DataDepth<bool> { public: enum { value = CV_8U, fmt=(int)'u' }; };
template<> class DataDepth<uchar> { public: enum { value = CV_8U, fmt=(int)'u' }; };
template<> class DataDepth<schar> { public: enum { value = CV_8S, fmt=(int)'c' }; };
template<> class DataDepth<char> { public: enum { value = CV_8S, fmt=(int)'c' }; };
template<> class DataDepth<ushort> { public: enum { value = CV_16U, fmt=(int)'w' }; };
template<> class DataDepth<short> { public: enum { value = CV_16S, fmt=(int)'s' }; };
template<> class DataDepth<int> { public: enum { value = CV_32S, fmt=(int)'i' }; };
// this is temporary solution to support 32-bit unsigned integers
template<> class DataDepth<unsigned> { public: enum { value = CV_32S, fmt=(int)'i' }; };
template<> class DataDepth<float> { public: enum { value = CV_32F, fmt=(int)'f' }; };
template<> class DataDepth<double> { public: enum { value = CV_64F, fmt=(int)'d' }; };
template<typename _Tp> class DataDepth<_Tp*> { public: enum { value = CV_USRTYPE1, fmt=(int)'r' }; };

ではなくCV_32Stype の値であることがわかります。intint32_t

于 2015-09-19T03:01:08.280 に答える
0

CV_8UC1、CV_32SC1 などに関連する OpenCV のコードでいくつかの #define を見つけました。列挙を機能させるために、OpenCV は追加のコードを配置して、単純な数値をパラメーターとしてまとめます (つまり、CV_8UC1、CV_16UC2... はすべて、それらのそれぞれの番号)、CvMat の定義で深度とチャネルを分割します (Mat はその定義に同様のコードを持っていると思います)。次に、create() を使用して、マトリックスにスペースを割り当てます。create() はインラインなので、malloc() か何かに似ているとしか思えません。
ソース コードは 2.4.9 から 3.0.0 に大幅に変更されるため、後でさらに証拠を投稿する必要があります。詳細を調べて回答を編集するため、少しお時間をください。

于 2015-09-22T03:39:15.170 に答える
-3

要するに、あなたが提供した表は正しいです。ピクセルに直接アクセスする場合は、右側の指定子に型キャストします。たとえば、CV_32S は符号付き 32 ビットです。S は常に符号付き整数 (signed char、signed short、signed int) を意味します。F は常に浮動小数点数 (float、double) を意味します。U は常に符号なし整数を意味します。

列挙は、Mat を作成または変換する場合にのみ使用されます。これは、テンプレートが使用されなかったときのCの前身であることを理解しているので、マットに目的のタイプを伝える方法です。

私は C 機能のみを使用しており、イメージを作成するために、次を渡すとエラーになります。

cvCreateImage(mySize,char, nChannels);

代わりに、次を渡します。

cvCreateImage(mySize, IPL_DEPTH_8U, nChannels);

ここで、IPL_DEPTH_8U は関数によって使用されるフラグです。関数自体には、フラグをチェックする switch 型のステートメントがあります。フラグの実際の値は、ほとんどの場合、代数ステートメントではなく条件付きステートメントによって制御されるため、意味がありません。

于 2013-03-06T12:30:21.227 に答える