C++ 对NaryMaterator中平面的理解

C++ 对NaryMaterator中平面的理解,c++,opencv,opencv3.0,C++,Opencv,Opencv3.0,我有三维矩阵: const int n_mat_size = 5; const int n_mat_sz[] = { n_mat_size , n_mat_size, n_mat_size }; cv::Mat m1(3, n_mat_sz, CV_32FC1); 现在我想迭代它的平面,并期望它应该是三个二维矩阵: const cv::Mat* arrays[] = { &m1, 0 }; cv::Mat planes[3]; cv::NAryMatIterator it(arrays

我有三维矩阵:

const int n_mat_size = 5;
const int n_mat_sz[] = { n_mat_size , n_mat_size, n_mat_size };
cv::Mat m1(3, n_mat_sz, CV_32FC1);
现在我想迭代它的平面,并期望它应该是三个二维矩阵:

const cv::Mat* arrays[] = { &m1, 0 };
cv::Mat planes[3];
cv::NAryMatIterator it(arrays, planes);
std::cout << it.nplanes << ", " << it.planes[0].rows << ", " << it.planes[0].cols;
const cv::Mat*数组[]={&m1,0};
cv::Mat平面[3];
cv::NaryMaterator it(阵列、平面);

std::cout因为矩阵
m1
是连续的,所以只有一个平面(或切片)

请参阅以下文档:

它遍历切片(或平面),而不是元素,其中“切片”是数组的连续部分

例如,以下代码中的矩阵
m2
不是连续的:

const int n_mat_size = 5;
const int n_mat_sz[] = { n_mat_size , n_mat_size, n_mat_size };
cv::Mat m1(3, n_mat_sz, CV_32FC1);

// Get plane 2 and 3 of m1
// and row 2, row 3 and row 4 of every selected plane
// m2 is not continuous
cv::Mat m2 = m1(cv::Range(2,4), cv::Range(2,5));

const cv::Mat* arrays[] = { &m2, 0 };
cv::Mat planes[3];
cv::NAryMatIterator it(arrays, planes);
std::cout << it.nplanes << ", " << it.planes[0].rows << ", " << it.planes[0].cols << std::end;
在函数
void NAryMatIterator::init
中,可在中找到

上面的语句设置平面的大小


要将给定的矩阵分隔为平面,可以使用
cv::InputArray::getMatVector

下面的代码显示了它的用法

int main()
{
  const int n_mat_size = 3;
  const int n_mat_sz[] = { n_mat_size , n_mat_size, n_mat_size };
  cv::Mat m1(3, n_mat_sz, CV_8U);

  cv::MatIterator_<uchar> it = m1.begin<uchar>();
  cv::MatIterator_<uchar> end = m1.end<uchar>();
  for (uchar i = 0; it != end; ++it, ++i)
  {
         *it = i;
  }

  cv::InputArray arr(m1);
  std::vector<cv::Mat> planes;
  arr.getMatVector(planes);
  for (size_t i = 0; i < planes.size(); ++i)
  {
    std::cout << "-------" << std::endl
    << planes[i] << std::endl << "******" << std::endl;
  }
}
****** 也许最简单的方法是使用方法
cv::Mat::row(int)
。相应的代码是:

int main()
{
  const int n_mat_size = 3;
  const int n_mat_sz[] = { n_mat_size , n_mat_size, n_mat_size };
  cv::Mat m1(3, n_mat_sz, CV_8U);

  cv::MatIterator_<uchar> it = m1.begin<uchar>();
  cv::MatIterator_<uchar> end = m1.end<uchar>();
  for (uchar i = 0; it != end; ++it, ++i)
  {
         *it = i;
  }

  int n = m1.size[0];
  for (int i = 0; i < n; ++i)
  {
     cv::Mat three_d_plane = m1.row(i);
     // three_d_plane has a size 1x3x3
     // std::cout supports only 2-d matrix. Therefore, we change it to 2-d here
     cv::Mat two_d_plane(three_d_plane.size[1], three_d_plane.size[2], three_d_plane.type(), three_d_plane.data);
     std::cout << two_d_plane << std::endl << "----" << std::endl;
  }
}

没有人想到在文档中会注意到这样一个事实,即每个平面总是被展平成一个向量,这是疯狂的。
-------
[  0,   1,   2;
   3,   4,   5;
   6,   7,   8]
******
-------
[  9,  10,  11;
  12,  13,  14;
  15,  16,  17]
******
-------
[ 18,  19,  20;
  21,  22,  23;
  24,  25,  26]
int main()
{
  const int n_mat_size = 3;
  const int n_mat_sz[] = { n_mat_size , n_mat_size, n_mat_size };
  cv::Mat m1(3, n_mat_sz, CV_8U);

  cv::MatIterator_<uchar> it = m1.begin<uchar>();
  cv::MatIterator_<uchar> end = m1.end<uchar>();
  for (uchar i = 0; it != end; ++it, ++i)
  {
         *it = i;
  }

  int n = m1.size[0];
  for (int i = 0; i < n; ++i)
  {
     cv::Mat three_d_plane = m1.row(i);
     // three_d_plane has a size 1x3x3
     // std::cout supports only 2-d matrix. Therefore, we change it to 2-d here
     cv::Mat two_d_plane(three_d_plane.size[1], three_d_plane.size[2], three_d_plane.type(), three_d_plane.data);
     std::cout << two_d_plane << std::endl << "----" << std::endl;
  }
}
[  0,   1,   2;
   3,   4,   5;
   6,   7,   8]
----
[  9,  10,  11;
  12,  13,  14;
  15,  16,  17]
----
[ 18,  19,  20;
  21,  22,  23;
  24,  25,  26]
----