2011-08-25 16 views
7

C'è un modo per avere una matrice di tipo definito dall'utente in OpenCV 2.x? Qualcosa di simile:OpenCV Matrice di tipo definito dall'utente

cv::Mat_<KalmanRGBPixel> backgroundModel; 

So cv :: Mat <> è significato per l'immagine e matematica, ma voglio tenere i dati in una forma di matrice. Non ho intenzione di usare inversione, trasposizione, moltiplicazione, ecc., È solo per memorizzare i dati. Voglio che sia in forma di matrice perché il pixel_ij di ciascun fotogramma di un video sarà collegato a backgroundModel_ij.

So che esiste una classe DataType < _Tp> in core.hpp che deve essere definita per il mio tipo ma non sono sicuro di come farlo.

MODIFICA: KalmanRGBPixel è solo un wrapper per la classe cv :: KalmanFilter. Per ora, è l'unico membro.

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

Grazie per il vostro aiuto.

+0

potete inserire la vostra definizione di 'KalmanRGBPixel' struct/classe? –

+0

Perché vuoi usare un cv :: Mat per questo quando non userai nessuna delle funzionalità cv :: Mat? Potresti semplicemente utilizzare un array bidimensionale, ecc. – Sean

+0

@Sean: la funzionalità 'cv :: Mat' include operatori integrati per l'accesso agli elementi, oltre a una corretta pulizia. –

risposta

0

È possibile creare un tappetino CV che utilizzi la memoria allocata specificando l'indirizzo al costruttore. Se si desidera anche che la larghezza e l'altezza siano corrette, sarà necessario trovare un tipo di pixel openCV con lo stesso numero di byte.

+1

Non è un brutto scherzo? Voglio dire, finirai per avere un 'cv :: Mat ' che contiene le voci 'KalmanRGBPixel'. –

+0

@Andre - usando bene cv :: Mat è un hack ma se hai bisogno di usarlo allora funziona –

2

Se non si desidera utilizzare la funzionalità OpenCV, quindi Mat non è il tipo giusto per voi. Utilizzare invece std::vector<std::vector<Type> >. Si può dare la dimensione durante l'inizializzazione:

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

Poi si può accedere con [] -operator. Non c'è bisogno di girarsi con oscuri cv::Mat qui.

Se avresti davvero bisogno di andare per una OpenCV-Matrix, hai ragione nel fatto che devi definire il DataType. È fondamentalmente un insieme di caratteristiche. Puoi leggere i Tratti C++ sul web.

+1

Ok, questo in realtà non risponde alla mia domanda, ma immagino che sia quello che dovrei fare **. Grazie. – Nil

2

ho una risposta più lungo senza fiato per chiunque voglia creare una matrice di oggetti personalizzati, di qualsiasi dimensione.

È necessario specializzare il modello DataType, ma invece di disporre di 1 canale, si rendono i canali della stessa dimensione dell'oggetto personalizzato. Potrebbe anche essere necessario sostituire alcune funzioni per ottenere le funzionalità previste, ma torneremo in seguito.

In primo luogo, ecco un esempio di mia abitudine tipo di modello di specializzazione: la funzionalità

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), 
     }; 
    }; 
} 

Seconda .. si consiglia di ignorare alcune funzioni per ottenere attesi:

// 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); 
}; 

Il typedef di super non è richiesto ma aiuta con la leggibilità nel cpp. Avviso Ho ignorato il costruttore con i parametri larghezza/altezza.Questo perché dobbiamo istanziare il tappetino in questo modo se vogliamo una matrice 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); 
} 

Il < a _T>() per la modifica è solo per il codice più pulito:

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

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