无法访问16UC类型的6通道垫(6)

时间:2018-02-28 06:48:13

标签: opencv iteration mat opencv3.1

我无法访问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 ype和我试图获取价值的方式一定存在问题。任何人都可以帮助我解决问题。

1 个答案:

答案 0 :(得分:0)

你有:

grid.at<Vec2s>(i, j)[0] = (ushort)j;

Vec2s用于短路,但您有无符号短矩阵。你应该使用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::Vec2wcv::Vec2s分别只是typedef的cv :: Vec和cv :: Vec,如果你在整个代码中使用它,你也可以创建你的typedef。

using Vec6w = cv::Vec<ushort, 6>;

然后你可以在for循环中替换它:

...
for (auto it = b.begin<Vec6w>(); it != b.end<Vec6w>(); ++it)
...

并获得相同的结果