acceso a elementos de múltiples canales opencv

Estoy tratando de aprender a usar la nueva interfaz c ++ de openCV.

¿Cómo accedo a los elementos de una matriz multicanal? por ejemplo:

Mat myMat(size(3, 3), CV_32FC2); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { //myMat_at_(i,j) = (i,j); } } 

¿Cuál es la forma más fácil de hacer esto? Algo así como cvSet2D de la interfaz anterior
¿Cuál es la forma más eficiente? Similar al uso de punteros directos en la interfaz anterior.

Gracias

 typedef struct elem_ { float f1; float f2; } elem; elem data[9] = { 0.0f }; CvMat mat = cvMat(3, 3, CV_32FC2, data ); float f1 = CV_MAT_ELEM(mat, elem, row, col).f1; float f2 = CV_MAT_ELEM(mat, elem, row, col).f2; CV_MAT_ELEM(mat, elem, row, col).f1 = 1212.0f; CV_MAT_ELEM(mat, elem, row, col).f2 = 326.0f; 

Actualización: para OpenCV2.0

1. elija un tipo para representar el elemento

Mat (o CvMat) tiene 3 dimensiones: fila, col, canal.
Podemos acceder a un elemento (o píxel) en la matriz especificando la fila y col.

CV_32FC2 significa que el elemento es un valor de punto flotante de 32 bits con 2 canales.
Entonces, elem en el código anterior es una representación aceptable de CV_32FC2 .

Puedes usar otras representaciones que te gusten. Por ejemplo :

 typedef struct elem_ { float val[2]; } elem; typedef struct elem_ { float x;float y; } elem; 

OpenCV2.0 agrega algunos tipos nuevos para representar el elemento en la matriz, como:

 template class CV_EXPORTS Vec // cxcore.hpp (208) 

Entonces podemos usar Vec para representar CV_32FC2 , o usar:

 typedef Vec Vec2f; // cxcore.hpp (254) 

Vea el código fuente para obtener más tipo que pueda representar su elemento.
Aquí usamos Vec2f

2. acceder al elemento

La forma más fácil y eficiente de acceder al elemento en la clase Mat es Mat :: at.
Tiene 4 sobrecargas:

 template _Tp& at(int y, int x); // cxcore.hpp (868) template const _Tp& at(int y, int x) const; // cxcore.hpp (870) template _Tp& at(Point pt); // cxcore.hpp (869) template const _Tp& at(Point pt) const; // cxcore.hpp (871) // defineded in cxmat.hpp (454-468) // we can access the element like this : Mat m( Size(3,3) , CV_32FC2 ); Vec2f& elem = m.at( row , col ); // or m.at( Point(col,row) ); elem[0] = 1212.0f; elem[1] = 326.0f; float c1 = m.at( row , col )[0]; // or m.at( Point(col,row) ); float c2 = m.at( row , col )[1]; m.at( row, col )[0] = 1986.0f; m.at( row, col )[1] = 326.0f; 

3. interactuar con la interfaz anterior

Mat proporciona 2 funciones de conversión:

 // converts header to CvMat; no data is copied // cxcore.hpp (829) operator CvMat() const; // defined in cxmat.hpp // converts header to IplImage; no data is copied operator IplImage() const; // we can interact a Mat object with old interface : Mat new_matrix( ... ); CvMat old_matrix = new_matrix; // be careful about its lifetime CV_MAT_ELEM(old_mat, elem, row, col).f1 = 1212.0f; 

Vic debe usar Vec3b en lugar de Vec3i:

 for (int i=0; i(i,j)[0] = 0; image.at(i,j)[1] = 0; image.at(i,j)[2] = 0; } } } 

Puede acceder directamente a la matriz de datos subyacente:

 Mat myMat(size(3, 3), CV_32FC2); myMat.ptr(y)[2*x]; // first channel myMat.ptr(y)[2*x+1]; // second channel 

depende del tipo de datos de la Mat que está utilizando, si es numérico como CV_32FC1 puede usar:

 myMat.at(i, j) 

si es un tipo uchar, entonces puedes acceder a un elemento usando

 (symb.at(i, j)).val[k] 

donde k es el canal, eso es 0 para imágenes en escala de grises y 3 para color

La mejor manera de acceder a la matriz multicanal con la API api es creando un puntero a una fila específica utilizando el método ptr.

Por ejemplo;

type elem = matrix.ptr(i)[N~c~*j+c]

dónde

  • tipo : el tipo de datos (float, int, char ect ..)
  • i : fila que te interesa
  • Nc : la cantidad de canales
  • j : la columna que te interesa
  • c : la columna que le interesa (0-3)

Para obtener información sobre otras conversiones c-> c ++ consulte este enlace: Fuente