Класс OpenCV Mat: доступ к элементам многоканальной матрицы - PullRequest
1 голос
/ 17 июня 2011

В настоящее время я хочу прочитать некоторые значения в 3-канальную матрицу 480 на 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 на 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*;

        }
     }

Теперь я хочу использовать только одну матрицу для этих операций, так как необходимость отслеживания трех отдельных переменных приведет кутомительно через некоторое время.У меня такое ощущение, что у меня нет доступа к нужной точке памяти для трехканальной матрицы.Кто-нибудь знает, как я могу сделать то, что я сделал во второй части кода, но используя одну трехканальную матрицу вместо трех отдельных одноканальных матриц?

Спасибо.

Ответы [ 4 ]

4 голосов
/ 14 июля 2014

Есть много способов сделать это, например:

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;
3 голосов
/ 20 сентября 2013

Очень просто, используя Vec3b - для uchar, Vec3i - для int, Vec3f - для поплавка, Vec3d - для двойного

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;



    }
 }
3 голосов
/ 18 июня 2011

Извините, я не вижу ваш код, так как пишу с iPhone. Когда вы используете 3-канальную матрицу, вы можете получить пиксель, используя:

Vec3b pix = rgbMatrix.at (строка, столбец);

Теперь вы можете получить доступ к каналу, используя: pix [0] = 255; pix [1] + = pix [2];

P.s. Обычно пиксель rgbMatrix имеет тип vec3b или vec3d. Всегда приводите image.at <> с соответствующим типом

0 голосов
/ 26 мая 2017
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...