OpenCV Mat для доступа к массиву

У меня проблема с доступом к данным из Mat.data. Я выполняю операции над изображением, и мне нужен доступ к каждому пикселю в отдельности. Я должен обязательно работать с простыми типами (float, int и т. Д.). То, как я получаю данные, показано ниже:

for (int idx = 0; idx < image.rows; idx++) {
        for (int idy = 0; idy < image.cols; idy++) {
            int color_tid = idx * image.cols * image.channels() + idy * image.channels();
            uint8_t blue = image.data[color_tid];
            uint8_t green = image.data[color_tid + 1];
            uint8_t red = image.data[color_tid + 2];
            float pixelVal = (int) blue + (int) green + (int) red;
            (...)
        }
    }

Этот подход работает правильно только для квадратных изображений (NxN пикселей), но для NxM есть аномалии за пределами квадратной области (меньший край). Кто-нибудь знает какой-либо другой способ доступа к данным картины мат? Пример изображения (правильный результат):

аномалии (моя проблема)

2 ответа

Решение

Я рекомендую следовать макету данных в Mat

так что ваш цикл становится:

for (int r = 0; r < img.rows; ++r)
{
    for (int c = 0; c < img.cols; ++c)
    {
        uchar* ptr  = img.data + img.step[0] * r + img.step[1] * c;
        uchar blue  = ptr[0];
        uchar green = ptr[1];
        uchar red   = ptr[2];

        float pixelVal = blue + green + red;
    }
}

В конечном итоге вы можете выполнить немного меньше операций, таких как:

for (int r = 0; r < img.rows; ++r)
{
    uchar* pt = img.data + img.step[0] * r;
    for (int c = 0; c < img.cols; ++c)
    {
        uchar* ptr  = pt + img.step[1] * c;
        uchar blue  = ptr[0];
        uchar green = ptr[1];
        uchar red   = ptr[2];

        float pixelVal = blue + green + red;
    }
}

Код в вашем вопросе содержит несколько недостатков:

  • строки и столбцы меняются местами (строка Y, столбец X)
  • размер шага между строками (он же "шаг") не всегда равен количеству столбцов

С помощью Mat::at<> делает код намного проще:

 for(int row = 0; row < image.rows; ++row)
 {
     for(int col = 0; col < image.cols; ++col)
     {
         const Vec3b& pt = image.at<Vec3b>(row, col);
         float pixelVal = pt[0] + pt[1] + pt[2];
         ...    
     }   
 } 
Другие вопросы по тегам