无法访问类型为 16UC(6) 的 6 通道垫
Unable to access 6 channel Mat of type 16UC(6)
我无法访问 16UC(6) 类型的垫子。下面是用于迭代 Mat 的代码。
//6 channel Mat
int cols=1280, rows=720;
Mat mat1=Mat(cols, rows, CV_16UC(6), Scalar::all(0));
Mat grid(Size(cols, rows), CV_16UC2, Scalar::all(0));
//create a grid of numbers - the value of each pixel in the grid
contains the coordinate of the pixel
for (int i = 0; i < grid.rows; ++i) {
for (int j = 0; j < grid.cols; ++j) {
grid.at<Vec2s>(i, j)[0] = (ushort)j;
grid.at<Vec2s>(i, j)[1] = (ushort)i;
}
}
vector<Mat> imgs(2); //create copies of the grid for each image
for(int i=0;i<2;i++){
imgs[i] = grid.clone();
}
//Values in Mat1 are filled with values of imgs[0] and imgs[1] using
// some logic.
int rows=mat1.rows;
int channels=mat1.channels();
int cols=mat1.cols * channels;
uchar* p;
for(int i=0;i<rows;i++){
p=mat1.ptr<uchar>(i);
for(int j=0;j<cols;j+=6){
cout<<"Value 0 :"<<p[j]<<endl;
cout<<"Value 1 :"<<p[j+1]<<endl;
cout<<"Value 2 :"<<p[j+2]<<endl;
cout<<"Value 3 :"<<p[j+3]<<endl;
cout<<"Value 4 :"<<p[j+4]<<endl;
cout<<"Value 5 :"<<p[j+5]<<endl;
}
}
但我得到 ^E 和 ^@ 作为值。当尝试转换为 (int) 时,我得到的都是零。
我可以使用 MatIterator 正确访问 Mat。我不确定哪里出错了,Mat 类型和我尝试访问 value.Can 的方式肯定有问题,任何人都可以帮助我解决问题。
你有:
grid.at<Vec2s>(i, j)[0] = (ushort)j;
Vec2s
用于短裤,但您有 Unsigned Short 矩阵。您应该使用 Vec2w
(不知道是谁带了 w... 或为什么)用于无符号短。
这可以重写为:
grid.at<cv::Vec2w>(i, j)[0] = static_cast<ushort>(j);
然后,显示 16U 矩阵的 uchar 值...每个 uchar 为 8 位,每个像素为 16 位...
这是一个示例,说明如何使用 CV_16UC(6) 矩阵中的迭代器访问每个像素。
// create dummy 3x3 matrix
cv::Mat b(3,3,CV_16UC(6));
// use the templated functions begin and end (you may templated with <ushort>
// directly and it will represent the value of each channel of each pixel)
for (auto it = b.begin<cv::Vec<ushort, 6>>(); it != b.end<cv::Vec<ushort, 6>>(); ++it)
{
// assign some values (this part can be skipped if it is already filled)
(*it)[0] = 5;
(*it)[1] = 7;
(*it)[2] = 8;
(*it)[3] = 9;
(*it)[4] = 1;
(*it)[5] = 2;
// Print the Vec<ushort, 6>, OpenCV already has a way to print it
std::cout << *it << std::endl;
}
而这段小代码的结果是:
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
这是我们所期望的。您可能已经注意到,我使用 cv::Vec<ushort, 6>
,cv::Vec 可以用任意数量的通道(可能有限制)和任何类型(我只用原生数字类型测试过)进行模板化。实际上 cv::Vec2w
或 cv::Vec2s
分别只是 cv::Vec 和 cv::Vec 的 typedef
,如果你在整个代码中使用它,你也可以创建你的 typedef。
using Vec6w = cv::Vec<ushort, 6>;
然后你可以在for循环中替换它:
...
for (auto it = b.begin<Vec6w>(); it != b.end<Vec6w>(); ++it)
...
并取得相同的结果
我无法访问 16UC(6) 类型的垫子。下面是用于迭代 Mat 的代码。
//6 channel Mat
int cols=1280, rows=720;
Mat mat1=Mat(cols, rows, CV_16UC(6), Scalar::all(0));
Mat grid(Size(cols, rows), CV_16UC2, Scalar::all(0));
//create a grid of numbers - the value of each pixel in the grid
contains the coordinate of the pixel
for (int i = 0; i < grid.rows; ++i) {
for (int j = 0; j < grid.cols; ++j) {
grid.at<Vec2s>(i, j)[0] = (ushort)j;
grid.at<Vec2s>(i, j)[1] = (ushort)i;
}
}
vector<Mat> imgs(2); //create copies of the grid for each image
for(int i=0;i<2;i++){
imgs[i] = grid.clone();
}
//Values in Mat1 are filled with values of imgs[0] and imgs[1] using
// some logic.
int rows=mat1.rows;
int channels=mat1.channels();
int cols=mat1.cols * channels;
uchar* p;
for(int i=0;i<rows;i++){
p=mat1.ptr<uchar>(i);
for(int j=0;j<cols;j+=6){
cout<<"Value 0 :"<<p[j]<<endl;
cout<<"Value 1 :"<<p[j+1]<<endl;
cout<<"Value 2 :"<<p[j+2]<<endl;
cout<<"Value 3 :"<<p[j+3]<<endl;
cout<<"Value 4 :"<<p[j+4]<<endl;
cout<<"Value 5 :"<<p[j+5]<<endl;
}
}
但我得到 ^E 和 ^@ 作为值。当尝试转换为 (int) 时,我得到的都是零。 我可以使用 MatIterator 正确访问 Mat。我不确定哪里出错了,Mat 类型和我尝试访问 value.Can 的方式肯定有问题,任何人都可以帮助我解决问题。
你有:
grid.at<Vec2s>(i, j)[0] = (ushort)j;
Vec2s
用于短裤,但您有 Unsigned Short 矩阵。您应该使用 Vec2w
(不知道是谁带了 w... 或为什么)用于无符号短。
这可以重写为:
grid.at<cv::Vec2w>(i, j)[0] = static_cast<ushort>(j);
然后,显示 16U 矩阵的 uchar 值...每个 uchar 为 8 位,每个像素为 16 位...
这是一个示例,说明如何使用 CV_16UC(6) 矩阵中的迭代器访问每个像素。
// create dummy 3x3 matrix
cv::Mat b(3,3,CV_16UC(6));
// use the templated functions begin and end (you may templated with <ushort>
// directly and it will represent the value of each channel of each pixel)
for (auto it = b.begin<cv::Vec<ushort, 6>>(); it != b.end<cv::Vec<ushort, 6>>(); ++it)
{
// assign some values (this part can be skipped if it is already filled)
(*it)[0] = 5;
(*it)[1] = 7;
(*it)[2] = 8;
(*it)[3] = 9;
(*it)[4] = 1;
(*it)[5] = 2;
// Print the Vec<ushort, 6>, OpenCV already has a way to print it
std::cout << *it << std::endl;
}
而这段小代码的结果是:
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
[5, 7, 8, 9, 1, 2]
这是我们所期望的。您可能已经注意到,我使用 cv::Vec<ushort, 6>
,cv::Vec 可以用任意数量的通道(可能有限制)和任何类型(我只用原生数字类型测试过)进行模板化。实际上 cv::Vec2w
或 cv::Vec2s
分别只是 cv::Vec 和 cv::Vec 的 typedef
,如果你在整个代码中使用它,你也可以创建你的 typedef。
using Vec6w = cv::Vec<ushort, 6>;
然后你可以在for循环中替换它:
...
for (auto it = b.begin<Vec6w>(); it != b.end<Vec6w>(); ++it)
...
并取得相同的结果