c++ - recorrer - get value from mat opencv
Accediendo a un elemento de matriz en el objeto "Mat"(no el objeto CvMat) en OpenCV C++ (4)
Basado en lo que @J. Calleja dijo, tienes dos opciones
Acceso aleatorio
Si quieres acceder aleatoriamente al elemento de Mat, simplemente usa
at<data_Type>(row_num, col_num) = value;
Acceso continuo
Si desea un acceso continuo, OpenCV proporciona Mat iterator compatible con STL iterator
MatIterator_<double> it, end;
for( it = I.begin<double>(), end = I.end<double>(); it != end; ++it)
{
//do something here
}
o
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
}
}
Pido prestada la foto de una publicación de blog en matrices dinámicas de dos dimensiones en C
¿Cómo acceder a los elementos por fila, col en la nueva clase "Mat" de OpenCV 2.0? La documentación está vinculada a continuación, pero no he podido encontrarle sentido. http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat
En la documentación:
http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat
Dice:
(...) si conoce el tipo de elemento de matriz, por ejemplo, es flotante, puede usar el método <> ()
Es decir, puedes usar:
Mat M(100, 100, CV_64F);
cout << M.at<double>(0,0);
Tal vez es más fácil usar la clase Mat_
. Es un envoltorio de plantilla para Mat
. Mat_
tiene el operator()
sobrecargado para acceder a los elementos.
Las ideas proporcionadas arriba son buenas. Para un acceso rápido (en caso de que desee hacer una solicitud en tiempo real), puede intentar lo siguiente:
//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
}
}
El acceso al puntero es mucho más rápido que el acceso Mat.at <>. ¡Espero eso ayude!
OCV hace todo lo posible para asegurarse de que no puede hacer esto sin conocer el tipo de elemento, pero si desea una forma fácil de codificar pero no muy eficiente para leerlo de manera independiente, puede usar algo como
double val=mean(someMat(Rect(x,y,1,1)))[channel];
Para hacerlo bien, tienes que saber el tipo sin embargo. El método at <> es la manera segura, pero el acceso directo al puntero de datos generalmente es más rápido si lo haces correctamente.