opencv treats the number of channels in each element of a cv::Mat as separate from the number of dimensions.
In your case cv::Mat M(1, 4, CV_64FC3, m) is a 2 dimensional array where each element has 3 channels.
cv::Mat::at returns an element in the cv::Mat.
In order to use it in your case you need to:
- Pass 2 indices for the 2 dimensions.
- Get a
cv::Vec3d value which holds an element with 3 channels of doubles .
- Iterate over the channels using
operator[] of cv::Vec3d.
Complete example:
#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;
}
Output:
1
2
3
4
5
6
7
8
9
10
11
12
Note:
Using cv::Mat::at for traversing a big matrix is not the most efficient way (and in debug builds it also incurs expensive validity checks).
A more efficient way it to use cv::Mat::ptr, which gives you direct access to row data.
Usage in your case (yields the same output):
#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;
}