2011-08-25 6 views
7

¿Hay alguna forma de tener una matriz del tipo definido por el usuario en OpenCV 2.x? Algo así como:Matriz OpenCV de tipo definido por el usuario

cv::Mat_<KalmanRGBPixel> backgroundModel; 

Sé cv :: Mat <> es para la imagen y la matemática, pero quiero mantener los datos en forma de matriz. No planeo usar inversa, transposición, multiplicación, etc., es solo para almacenar datos. Quiero que esté en forma de matriz porque el pixel_ij de cada fotograma de un video se vinculará a backgroundModel_ij.

Sé que hay una clase DataType < _Tp> en core.hpp que debe definirse para mi tipo, pero no estoy seguro de cómo hacerlo.

EDITAR: KalmanRGBPixel es solo un contenedor para la clase cv :: KalmanFilter. Por ahora, es el único miembro.

... some functions ... 
private: 
    cv::KalmanFilter kalman; 

Gracias por su ayuda.

+0

Se puede publicar definición de su estructura 'KalmanRGBPixel'/clase? –

+0

¿Por qué quiere usar un cv :: Mat para esto cuando no va a utilizar ninguna de las funciones de cv :: Mat? Solo podría usar una matriz bidimensional, etc. – Sean

+0

@Sean: la funcionalidad 'cv :: Mat' incluye operadores incorporados para acceder a los elementos, así como una limpieza adecuada. –

Respuesta

0

Puede crear una estera de CV que los usuarios tengan su propia memoria asignada especificando la dirección al constructor. Si también desea que el ancho y el alto sean correctos, deberá encontrar un tipo de píxel de C abierta que tenga el mismo número de bytes.

+1

¿No es esto un hack desagradable? Quiero decir, terminarás teniendo un 'cv :: Mat ' que contiene las entradas 'KalmanRGBPixel'. –

+0

@Andre - bien usando cv :: Mat es un truco pero si necesitas usarlo funciona –

2

Si no desea utilizar la funcionalidad de OpenCV, entonces Mat no es el tipo correcto para usted. Use std::vector<std::vector<Type> > en su lugar. Se puede dar el tamaño durante la inicialización:

std::vector<std::vector<Type> > matrix(42, std::vector<Type>(23)); 

A continuación, se puede acceder con [] -operator. No es necesario atornillar con cv::Mat oscuro aquí.

Si realmente necesitas un OpenCV-Matrix, tienes razón en que tienes que definir el DataType. Básicamente es un montón de rasgos. Puede leer sobre Rasgos de C++ en la web.

+1

Ok, esto realmente no responde mi pregunta, pero supongo que es lo que ** debo ** hacer. Gracias. – Nil

2

tengo una respuesta más largo aliento para aquellos que se quieran crea una matriz de objetos personalizados, de cualquier tamaño.

Deberá especializar la plantilla de tipo de datos, pero en lugar de tener 1 canal, los hará del mismo tamaño que su objeto personalizado. También es posible que deba sobrescribir algunas funciones para obtener la funcionalidad esperada, pero volvamos a eso más adelante.

primer lugar, aquí es un ejemplo de mi costumbre plantilla del tipo de especialización: funcionalidad

typedef HOGFilter::Sample Sample; 
namespace cv { 
    template<> class DataType<Sample> 
    { 
    public: 
     typedef HOGFilter::Sample  value_type; 
     typedef HOGFilter::Sample  channel_type; 
     typedef HOGFilter::Sample  work_type; 
     typedef HOGFilter::Sample  vec_type; 

     enum { 
      depth = CV_8U, 
      channels = sizeof(HOGFilter::Sample), 
      type = CV_MAKETYPE(depth, channels), 
     }; 
    }; 
} 

En segundo lugar .. es posible que desee para anular algunas funciones para obtener espera:

// Special version of Mat, a matrix of Samples. Using the power of opencvs 
// matrix manipulation and multi-threading capabilities 
class SampleMat : public cv::Mat_<Sample> 
{ 
    typedef cv::Mat_<Sample> super; 
public: 
    SampleMat(int width = 0, int height = 0); 
    SampleMat &operator=(const SampleMat &mat); 

    const Sample& at(int x, int y = 0); 
}; 

El typedef de súper no es necesario, pero ayuda con la legibilidad en el cpp. Observe que he anulado el constructor con parámetros de ancho/alto.Esto se debe a que tenemos que instanciar el tapete de esta manera si queremos una matriz 2D.

SampleMat::SampleMat(int width, int height) 
{ 
    int count = width * height; 

    for (int i = 0; i < count; ++i) 
    { 
     HOGFilter::Sample sample; 
     this->push_back(sample); 
    } 

    *dynamic_cast<Mat_*>(this) = super::reshape(channels(), height); 
} 

El al < _T>() de la redefinición es sólo para un código más limpio:

const Sample & SampleMat::at(int x, int y) 
{ 
    if (y == 0) 
     return super::at<Sample>(x); 

    return super::at<Sample>(cv::Point(x, y)); 
} 
Cuestiones relacionadas