2009-11-11 19 views
14

Imagínese Tengo el siguiente:¿Cuál es la estructura de memoria de cvMat de OpenCV?

CvMat* mat = cvCreateMat(3,3,CV_16SC3) 

Esta es una matriz 3x3 de enteros de canal 3.

Ahora bien, si nos fijamos en la documentación OpenCV se encuentra el siguiente como la desaceleración para cvMat:

typedef struct CvMat { 

int type; 
int step; 

int* refcount; 

union 
{ 
    uchar* ptr; 
    short* s; 
    int* i; 
    float* fl; 
    double* db; 
} data; 

union 
{ 
    int rows; 
    int height; 
}; 

union 
{ 
    int cols; 
    int width; 
}; 
} CvMat; 

Ahora, quiero jugar con el data.ptr, que es el puntero a los datos almacenados en cvMat. Sin embargo, estoy teniendo dificultades para entender cómo se presenta la memoria. Si tengo una matriz de 3 canales, ¿cómo funciona esto? Para un canal es simple porque es solo una matriz simple de MxN donde M es filas y N es cols. Sin embargo, para 3 canales, ¿hay 3 de estas matrices MxN? ¿Puede alguien mostrarme cómo iría sobre la integración de una matriz de 3 canales a través de data.ptr y cómo acceder a estos valores, por favor? Gracias.

+0

Básicamente, ¿a qué se reduce esta pregunta? ¿Cómo puedo acceder? Digamos el canal 2 de la fila 2, columna 1. –

Respuesta

19

This webpage es una excelente introducción a OpenCV 1.1. Recomendaría utilizar la última versión, Open CV 2.0 que tiene una clase general Mat que maneja imágenes, matrices, etc. a diferencia de OpenCV 1.1.

La página web ha detallado anteriormente los métodos de acceso siguientes elementos en las imágenes de varios canales:

acceso indirecto: (general, pero ineficiente, el acceso a cualquier tipo de imagen)

Para una multi- flotador canal (o byte) imagen:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 
CvScalar s; 
s=cvGet2D(img,i,j); // get the (i,j) pixel value 
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]); 
s.val[0]=111; 
s.val[1]=111; 
s.val[2]=111; 
cvSet2D(img,i,j,s); // set the (i,j) pixel value 

acceso directo: (acceso eficiente, pero propenso a errores)

una imagen multi-canal de flotador para:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B 
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G 
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R 

Acceso directo usando un puntero: (simplificado y acceso eficiente bajo supuestos limitantes)

una imagen multi-canal de flotador para (suponiendo una 4 alineación -byte):

IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 
int height  = img->height; 
int width  = img->width; 
int step  = img->widthStep/sizeof(float); 
int channels = img->nChannels; 
float * data = (float *)img->imageData; 
data[i*step+j*channels+k] = 111; 

acceso directo usando un envoltorio de C++: (acceso simple y eficiente)

Definir un ++ envoltorio c para las imágenes de un solo canal de bytes, imágenes de bytes de múltiples canales, y las imágenes de flotación multicanal:

template<class T> class Image 
    { 
    private: 
    IplImage* imgp; 
    public: 
    Image(IplImage* img=0) {imgp=img;} 
    ~Image(){imgp=0;} 
    void operator=(IplImage* img) {imgp=img;} 
    inline T* operator[](const int rowIndx) { 
     return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));} 
    }; 

    typedef struct{ 
    unsigned char b,g,r; 
    } RgbPixel; 

    typedef struct{ 
    float b,g,r; 
    } RgbPixelFloat; 

    typedef Image<RgbPixel>  RgbImage; 
    typedef Image<RgbPixelFloat> RgbImageFloat; 
    typedef Image<unsigned char> BwImage; 
    typedef Image<float>   BwImageFloat; 

una imagen multicanal flotador para:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 
RgbImageFloat imgA(img); 
imgA[i][j].b = 111; 
imgA[i][j].g = 111; 
imgA[i][j].r = 111; 
+1

gracias por esta respuesta completa – user261002

+2

Esta respuesta debería haber cubierto algunos detalles sobre cvMat. cvMat no se menciona en absoluto – vishal

Cuestiones relacionadas