Acceso a un elemento de matriz en el objeto “Mat” (no el objeto CvMat) en OpenCV C ++
Pregunta
¿Cómo acceder a los elementos por fila, columna en OpenCV nueva clase "de ratón" de 2.0? La documentación está vinculada a continuación, pero no he sido capaz de hacer cualquier sentido de la misma. http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat
Solución
En la documentación:
http://docs.opencv.org/2.4/ módulos / core / doc / basic_structures.html # estera
Se dice:
(...) si se conoce el elemento de matriz tipo, por ejemplo, es flotante, entonces se puede utilizar a <> () método
Es decir, se puede utilizar:
Mat M(100, 100, CV_64F);
cout << M.at<double>(0,0);
Tal vez sea más fácil de utilizar la clase Mat_
. Es un envoltorio plantilla para Mat
.
Mat_
tiene la operator()
sobrecargada con el fin de acceder a los elementos.
Otros consejos
Las ideas proporcionadas anteriormente son buenas. Para acceder rápidamente (en caso de que quiera hacer una aplicación en tiempo real) puede probar 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
}
}
Acceso puntero es mucho más rápido que el Mat.at <> acceder. Espero que ayude!
Sobre la base de lo que @J. Calleja dicho, tiene dos opciones
Método 1 - acceso aleatorio
Si desea acceso aleatorio elemento de Mat, simplemente use
Mat.at<data_Type>(row_num, col_num) = value;
Método 2 - Acceso continuo
Si desea un acceso continuo, OpenCV proporciona iterador Mat compatible con STL iterator
y es más estilo C++
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
}
}
Si tiene alguna dificultad para entender cómo funciona el método 2, tomo prestada la imagen de una entrada de blog en el artículo Las matrices de dos dimensiones dinámico en C , que es mucho más intuitivo y comprensible.
Vea el cuadro abajo.
OCV se sale de su camino para asegurarse de que no se puede hacer esto sin conocer el tipo de elemento, pero si quieres una manera fácilmente codificable, pero no muy eficiente para leerlo tipo-agnóstico, se puede usar algo como
double val=mean(someMat(Rect(x,y,1,1)))[channel];
Para hacerlo bien, usted tiene que saber el tipo embargo. El método en <> es la manera segura, pero el acceso directo al puntero de datos es generalmente más rápido si lo haces correctamente.