【问题标题】:OpenCV Mat class: Accessing elements of a multi-channel matrixOpenCV Mat 类:访问多通道矩阵的元素
【发布时间】:2011-09-17 06:35:06
【问题描述】:

我目前想将一些值读入一个 3 通道、480 行 x 640 列的 8 位无符号整数值矩阵。我正在像这样初始化矩阵:

声明:

rgbMatrix = Mat::zeros(480,640,CV_8UC3);

当我尝试遍历整个矩阵时,我无法使用以下方法分配/获取值。值保持为 0。我的代码如下所示:

    for (int i = 0; i < rgbMatrix.rows; i++)
    {
        for (int j = 0; j < rgbMatrix.cols; j++)
        {
           (rgbMatrix.data + rgbMatrix.step * i)[j * rgbMatrix.channels() + 0] = *value0*;
           (rgbMatrix.data + rgbMatrix.step * i)[j * rgbMatrix.channels() + 1] = *value1*;
           (rgbMatrix.data + rgbMatrix.step * i)[j * rgbMatrix.channels() + 2] = *value2*;

        }
     }

但是,当我声明三个单独的 1 通道矩阵(也是 480 行 x 640 列的 8 位无符号整数值)并尝试访问这些矩阵的元素时,以下代码有效:

声明:

rgbMatrix0 = Mat::zeros(480,640,CV_8UC1);
rgbMatrix1 = Mat::zeros(480,640,CV_8UC1);
rgbMatrix2 = Mat::zeros(480,640,CV_8UC1);

    for (int i = 0; i < rgbMatrix0.rows; i++)
    {
        for (int j = 0; j < rgbMatrix0.cols; j++)
        {
           (rgbMatrix0.data + rgbMatrix0.step * i)[j] = *value0*;
           (rgbMatrix1.data + rgbMatrix1.step * i)[j] = *value1*;
           (rgbMatrix2.data + rgbMatrix2.step * i)[j] = *value2*;

        }
     }

现在,我只想对这些操作使用一个矩阵,因为一段时间后必须跟踪三个单独的变量会让人厌烦。我有一种感觉,我没有为三通道矩阵访问正确的内存点。有谁知道我如何完成我在第二部分代码中所做的,但使用一个三通道矩阵而不是三个单独的单通道矩阵?

谢谢。

【问题讨论】:

    标签: opencv matrix


    【解决方案1】:

    有很多方法可以做到,例如:

    cv::Mat rgbMatrix(480,640,CV_8UC3);
    for (int i = 0; i < rgbMatrix.rows; i++)
      for (int j = 0; j < rgbMatrix.cols; j++)
        for (int k = 0; k < 3; k++)
          rgbMatrix.at<cv::Vec3b>(i,j)[k] = value;
    

    [k] 这里是通道值。

    要将所有矩阵元素设置为特定值,例如 5,您可以这样做:

    cv::Mat rgbMatrix2(cv::Size(480,640), CV_8UC3, cv::Scalar(5,5,5));
    std::cout << rgbMatrix2 << std::endl;
    

    【讨论】:

      【解决方案2】:

      抱歉,由于我是从 iPhone 编写的,所以我看不到您的代码。当您使用 3 通道矩阵时,您可以使用以下方法获取像素:

      Vec3b pix = rgbMatrix.at(row,col);

      现在您可以使用以下方式访问频道: 像素[0] = 255; pix[1] += pix[2];

      附:通常 rgbMatrix 像素的类型为 vec3b 或 vec3d。始终使用相关类型投射 image.at

      【讨论】:

        【解决方案3】:

        非常简单地使用 Vec3b - for uchar, Vec3i - for int, Vec3f - for float, Vec3d - for double

        Mat rgbMatrix = Mat::zeros(480,640,CV_8UC1);
        
        
        for (int i = 0; i < rgbMatrix.rows; i++)
        {
            for (int j = 0; j < rgbMatrix.cols; j++)
            {
               rgbMatrix.at<Vec3b>(i,j)[0] = *value0;
               rgbMatrix.at<Vec3b>(i,j)[1] = *value1;
               rgbMatrix.at<Vec3b>(i,j)[2] = *value2;
        
        
        
            }
         }
        

        【讨论】:

          【解决方案4】:
          vector<cv::Point3f> xyzBuffer;
          cv::Mat xyzBuffMat = cv::Mat(307200, 1, CV_32FC3);
          for (int i = 0; i < xyzBuffer.size(); i++) {
              xyzBuffMat.at<cv::Vec3f>(i, 1, 0) = xyzBuffer[i].x;
              xyzBuffMat.at<cv::Vec3f>(i, 1, 1) = xyzBuffer[i].y;
              xyzBuffMat.at<cv::Vec3f>(i, 1, 2) = xyzBuffer[i].z;
          }
          

          这里的0、1、2分别是存储x、y、z值的通道。

          【讨论】:

            猜你喜欢
            • 2015-08-07
            • 1970-01-01
            • 1970-01-01
            • 2012-09-02
            • 2010-12-21
            • 2014-02-01
            • 2023-04-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多