I'm confused by the OpenCV Mat element types. This is from the docs:
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 };
It's known that C++ standard doesn't define the size of basic types in bytes, so how do they use such assumptions? And what type should I expect from, let's say, CV_32S, is it int32_t or int?
The Mat class of OpenCV library is used to store the values of an image. It represents an n-dimensional array and is used to store image data of grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms, etc.
Buprenorphine, methadone, and naltrexone are used to treat opioid use disorders to short-acting opioids such as heroin, morphine, and codeine, as well as semi-synthetic opioids like oxycodone and hydrocodone. These MAT medications are safe to use for months, years, or even a lifetime.
CV_64F is the same as CV_64FC1 . So if you need just 2D matrix (i.e. single channeled) you can just use CV_64F. EDIT. More generally, type name of a Mat object consists of several parts.
Mat is basically a class with two data parts : the matrix header (containing information such as the size of the matrix, the method used for storing, at which address is the matrix stored, and so on) and a pointer to the matrix containing the pixel values (taking any dimensionality depending on the method chosen for ...
Developing from Miki's answer,
In OpenCV 3 definition has moved to modules/core/include/opencv2/core/traits.hpp, where you can find:
/** @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; };
In most of the cases/compilers you should be fine using C++ exact data types. You wouldn't have problems with single byte data types (CV_8U
-> uint8_t
and CV_8U
-> int8_t
) as unambiguously defined in C++. The same for float (32bit) and double (64bit). However, it is true that for other data types to be completely sure you use the correct data type (for example when using the at<>
method) you should use for example:
typedef TypeDepth<CV_WHATEVER_YOU_USED_TO_CREATE_YOUR_MAT>::value_type access_type; myMat.at<access_type>(y,x) = 0;
As a side note, I am surprised they decided to take such an ambiguous approach, instead of simply using exact data types.
Therefore, regarding your last question:
What type should I expect from, let's say,
CV_32S
?
I believe the most precise answer, in OpenCV 3, is:
TypeDepth<CV_32S>::value_type
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With