Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCV Mat元素类型及其大小_Opencv - Fatal编程技术网

OpenCV Mat元素类型及其大小

OpenCV Mat元素类型及其大小,opencv,Opencv,我被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 unsigne

我被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?

简言之,您提供的表格是正确的。 如果要直接访问像素,可以将其键入右侧的说明符,例如CV_32S是有符号的32位。 S始终表示有符号整数(有符号字符、有符号短字符、有符号整数) F始终表示浮点数(浮点,双精度) U始终表示无符号整数

枚举仅在创建或转换Mat时使用。这是一种告诉mat哪种类型是所需类型的方法,据我所知,这是未使用模板时的C前身

我专门使用C功能,为了创建图像,传递以下信息将是一个错误:

cvCreateImage(mySize,char, nChannels);
cvCreateImage(mySize, IPL_DEPTH_8U, nChannels);
/*!
  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' }; };
相反,我通过了以下内容:

cvCreateImage(mySize,char, nChannels);
cvCreateImage(mySize, IPL_DEPTH_8U, nChannels);
/*!
  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' }; };

这里,IPL_DEPTH_8U是函数使用的标志。函数本身有一个检查标志的开关类型语句。标志的实际值通常没有意义,因为它通常由条件语句而不是代数语句控制。

您可以在opencv的源代码中找到有关问题的所有定义


见文件

core.hpp
中,您可以找到以下内容:

cvCreateImage(mySize,char, nChannels);
cvCreateImage(mySize, IPL_DEPTH_8U, nChannels);
/*!
  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::DataType的帮助器类
该类专门用于OpenCV支持的每种基本数值数据类型。
它提供DataDepth::value常量。
*/
模板类数据深度{};
模板类DataDepth{public:enum{value=CV_8U,fmt=(int)'u'};};
模板类DataDepth{public:enum{value=CV_8U,fmt=(int)'u'};};
模板类DataDepth{public:enum{value=CV_8S,fmt=(int)'c'};};
模板类DataDepth{public:enum{value=CV_8S,fmt=(int)'c'};};
模板类DataDepth{public:enum{value=CV_16U,fmt=(int)'w'};};
模板类DataDepth{public:enum{value=CV_16S,fmt=(int)'s'};};
模板类DataDepth{public:enum{value=CV_32S,fmt=(int)'i'};};
//这是支持32位无符号整数的临时解决方案
模板类DataDepth{public:enum{value=CV_32S,fmt=(int)'i'};};
模板类DataDepth{public:enum{value=CV_32F,fmt=(int)'f'};};
模板类DataDepth{public:enum{value=CV_64F,fmt=(int)'d'};};
模板类DataDepth{public:enum{value=CV_USRTYPE1,fmt=(int)'r'};};
您可以看到,
CV_32S
是类型
int
的值,而不是
int32_t

,我在OpenCV的代码中找到了几个与CV#u 8UC1、CV#u 32SC1等相关的定义。为了使枚举有效,OpenCV将其他代码作为参数转换为普通数字(即,CV_8UC1、CV_16UC2……都由各自的数字表示),并在CvMat的定义中将深度和通道分开(我猜Mat的定义中可能有类似的代码)。然后,它使用create()为矩阵分配空间。由于create()是内联的,我只能猜测它类似于malloc()或其他东西。

随着源代码从2.4.9到3.0.0的变化,我需要稍后再发布更多的证据。请允许我花些时间来找出更多的内容并编辑我的答案。< /P> < P>。当C++没有定义元素的大小时,问题是假设的:对于OpenCV系统来说,系统的大小是已知的。
cv::Mat m(32,32,CV_32SC1, cv:Scalar(0));
std::cout << "size of the element in bytes: " << m.depth() << std::endl;
std::cout << "or " << m.step.p[ m.dims-1 ]/m.channels() << std::endl;
意志

其中左手通过
cv::Mat::flags
定义——在本例中,左手定义为
cv_32SC1
的预定义深度,等于

CV_DbgAssert( m.depth() == sizeof(int) )

因此,如果您成功了,那么只剩下endianness。这是在生成cvconfig.h(由CMake)时检查的

TL;DR,除了标题中给出的类型之外,您会没事的。

从,
在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;
};
顺便说一句,我很惊讶他们决定采用这种模棱两可的方法,而不是简单地使用精确的数据类型

因此,关于你的最后一个问题:

比如说,我应该期待什么类型的CV_32S

我相信OpenCV 3中最准确的答案是:

TypeDepth<CV_32S>::value_type
TypeDepth::value\u类型

openCV中的类型很容易理解。CV_numbitsType。因此CV_16S是一个16位长的有符号整数。那么为什么它们在文档中使用这样的名称(int、float等),而(例如)int可以是64位而不是32位?我真的不知道底层结构,但是当您使用CV_32S类型创建mat时:
mat myMat(10,10,CV_32S);
您可以使用
myMat.at(1,1)访问它=1; BTW,你所输入的表似乎是正确的,我的意思是,左边的每一种类型都使用括号中的C++类型来访问一个垫子,如上面的注释。@ Ruchir,你应该能够定义一个。但是,我怀疑你能将任何OpenCV函数应用到它上。这是不相关的。问题是OpenCV2和答案。OpenCV1的答案是非常感谢的。OpenCV在大多数情况下不遵循C++的诽谤。虽然它是一个很棒的计算机视觉库,但我讨厌在C++中处理它。它总是会制动我的代码,并让我编写代码,我感到羞愧。你如何访问ValueSype?你的例子在OpenCV 3中对我来说不起作用,因为它是M。余烬,不公开。@John:是的,只要用“struct”替换“class”,它就可以工作了。我的OpenCV 2.4.5版本没有hader,我必须手动将代码添加到源代码中。请注意Mat::elemSize1()方法,该方法还以字节为单位显示存储在Mat中的一个数字的大小。@karsten您不打算修改OpenCV头,是吗?不要这样做。如果我们得到
CV\u,无论您使用什么方法\u从数据创建\u Mat
?如果它不是一个常量值?m.depth()不在b中