如何使用 cv::Mat::at<double>(i,j,k) (访问多通道矩阵)?


#include <iostream>
#include <opencv2/highgui/highgui.hpp>
int main()
{
double m[1][4][3] =
{
{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}, {10.0, 11.0, 12.0}}};
cv::Mat M(1, 4, CV_64FC3, m);
for (int i = 0; i < 1; ++i)
for (int j = 0; j < 4; ++j)
for (int k = 0; k < 3; ++k)
std::cout << M.at<double>(i, j, k) << std::endl;

cv::namedWindow("Input", cv::WINDOW_NORMAL);
cv::imshow("Input", M);
cv::waitKey();
return 0;
}

预期输出

1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0

电流输出

1
8.10465e-320
5.31665e-315
4
8.11058e-320
2.122e-314  
7
8.11355e-320
-9.44163e+21
10
7.16685e-308
0

opencv将cv::Mat的每个元素中的通道数视为独立于

维度数在您的情况下,cv::Mat M(1, 4, CV_64FC3, m)2维阵列,其中每个元素都有3个通道

cv::Mat::at返回cv::Mat中的一个元素
为了在您的情况下使用它,您需要:

  1. 通过2个维度的2个索引
  2. 获取一个cv::Vec3d值,该值包含一个具有3个通道的doubles的元素
  3. 使用CCD_ 8的CCD_ 7在信道上进行迭代

完整示例:

#include <opencv2/core/core.hpp>
#include <iostream>
int main()
{
double m[1][4][3] = {{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}, {10.0, 11.0, 12.0}} };
cv::Mat M(1, 4, CV_64FC3, m);
for (int i = 0; i < M.rows; ++i)
{
for (int j = 0; j < M.cols; ++j)
{
cv::Vec3d const& elem = M.at<cv::Vec3d>(i, j);
for (int k = 0; k < 3; ++k)
{
std::cout << elem[k] << std::endl;
}
}
}
return 0;
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12

注意:

使用cv::Mat::at遍历大矩阵并不是最有效的方法(而且在调试构建中,它还会导致昂贵的有效性检查(
使用cv::Mat::ptr的一种更有效的方式,它使您可以直接访问行数据。

在您的情况下使用(产生相同的输出(:

#include <opencv2/core/core.hpp>
#include <iostream>
int main()
{
double m[1][4][3] = { {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}, {10.0, 11.0, 12.0}} };
cv::Mat M(1, 4, CV_64FC3, m);
for (int i = 0; i < M.rows; ++i)
{
//----------------------------vvv---------------
cv::Vec3d const* pRow = M.ptr<cv::Vec3d>(i);
for (int j = 0; j < M.cols; ++j)
{
cv::Vec3d const& elem = pRow[j];
for (int k = 0; k < 3; ++k)
{
std::cout << elem[k] << std::endl;
}
}
}
return 0;
}

最新更新