Доступ к элементу матрицы в объекте "Mat" (не в объекте CvMat) в OpenCV C ++ - PullRequest
29 голосов
/ 04 декабря 2009

Как получить доступ к элементам по строкам, столбцам в новом классе Mat для OpenCV 2.0? Документация связана ниже, но я не смог понять это. http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat

Ответы [ 4 ]

49 голосов
/ 04 декабря 2009

По документации:

http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat

Там написано:

(...) если вы знаете матричный элемент тип, например это поплавок, тогда вы можете использовать в методе <> ()

То есть вы можете использовать:

Mat M(100, 100, CV_64F);
cout << M.at<double>(0,0);

Может быть, проще использовать класс Mat_. Это шаблонная оболочка для Mat. Mat_ перегружен operator() для доступа к элементам.

10 голосов
/ 17 августа 2015

Идеи, представленные выше, хороши. Для быстрого доступа (если вы хотите создать приложение в реальном времени) вы можете попробовать следующее:

//suppose you read an image from a file that is gray scale
Mat image = imread("Your path", CV_8UC1);
//...do some processing
uint8_t *myData = image.data;
int width = image.cols;
int height = image.rows;
int _stride = image.step;//in case cols != strides
for(int i = 0; i < height; i++)
{
    for(int j = 0; j < width; j++)
    {
        uint8_t val = myData[ i * _stride + j];
        //do whatever you want with your value
    }
}

Доступ к указателю намного быстрее, чем к Mat.at <>. Надеюсь, это поможет!

4 голосов
/ 27 октября 2017

На основании чего @J. Каллеха сказала, у вас есть два варианта

Способ 1 - произвольный доступ

Если вы хотите получить произвольный доступ к элементу Mat, просто используйте

Mat.at<data_Type>(row_num, col_num) = value;

Метод 2 - Непрерывный доступ

Если вы хотите непрерывный доступ, OpenCV предоставляет итератор Mat, совместимый с STL iterator, и его стиль C++

MatIterator_<double> it, end;
for( it = I.begin<double>(), end = I.end<double>(); it != end; ++it)
{
    //do something here
}

или

for(int row = 0; row < mat.rows; ++row) {
    float* p = mat.ptr(row); //pointer p points to the first place of each row
    for(int col = 0; col < mat.cols; ++col) {
         *p++;  // operation here
    }
}

Если вам трудно понять, как работает метод 2, я заимствую картинку из поста в блоге в статье Динамические двумерные массивы в C , которая гораздо более интуитивна и понятна.

См. Рисунок ниже.

enter image description here

1 голос
/ 17 марта 2015

OCV старается изо всех сил, чтобы убедиться, что вы не можете сделать это, не зная тип элемента, но если вы хотите легко кодируемый, но не очень эффективный способ читать его независимо от типа, вы можете использовать что-то вроде

double val=mean(someMat(Rect(x,y,1,1)))[channel];

Чтобы сделать это хорошо, вы должны знать тип, хотя. Метод at <> является безопасным способом, но прямой доступ к указателю данных обычно быстрее, если вы делаете это правильно.

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