你刚刚发现了OpenCV C++ API中的众多缺陷之一。
如果你查看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
是一个模板类,用于指定图像或矩形的大小,该类包括两个成员:宽度和高度。
"Template class for specifying the size of an image or rectangle. The class includes two members called width and height."
换句话说,Size
仅适用于二维矩阵。
幸运的是,您可以使用 cv::Mat::MSize::operator [](int i)
来获取沿着第i维度的矩阵大小。
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
cv::Mat
。如果你还不知道cv::Mat_<>
的存在,我建议你在这里看一下它(http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=mat_#Mat_)。它隐藏了`cv::Mat` API中最令人无法忍受的缺陷,并帮助我长时间使用OpenCV。 - brunocodutracv::Mat_<>
继承自cv::Mat
,因此可以无缝地替换cv::Mat
在大多数情况下使用。它的主要优点是静态类型化,也就是说编译器负责检查底层数据类型(不做更多的期望之外的事情)。这意味着不再需要像断言一样检查矩阵的底层数据类型、动态函数重载技术等等。任何已经使用过 OpenCV 的人都可以证明这些是最容易出错的注意事项。 - brunocodutracv::Mat
,因此我建议在合适的情况下应该优先选择静态类型的cv::Mat_<>
。 - brunocodutra