2013-07-11 3 views
5

Come suggerisce il titolo, sto avendo qualche problema nell'implementare la funzione mouseCallback di OpenCV in una struttura C++ basata su classi. Permettimi di spiegare. Ho definito una classe chiamata BriskMatching in cui ho creato una funzione membro chiamata mouseCallback con i parametri corretti richiesti da OpenCV (vedere il frammento di codice sotto).Problemi nella creazione di un'implementazione basata sulla classe della funzione mouseCallback di OpenCV

**Briskmatching.h** 

class BriskMatching 
{ 
public: 
    BriskMatching(); 
    ~BriskMatching(); 

public: 
    void mouseCallback(int event, int x, int y, int flags, void *param); 
}; 

Questo è tutto bene, ma il mio problema si pone quando si tenta di impostare questa funzione come la funzione del mouse di callback designato attraverso la funzione di OpenCV cv::setMouseCallback.

Nella mia funzione principale, ho creare un'istanza della classe BriskMatching chiamato briskMatcher poi quando arriva il momento di impostare la richiamata del mouse tento di farlo in questo modo ...

cv::setMouseCallback("Matches", BriskMatching::mouseCallback, &matchesImg); 

Purtroppo, questo getta un errore.

Error 3 error C3867: 'BriskMatching::mouseCallback': function call missing argument list; use '&BriskMatching::mouseCallback' to create a pointer to member c:\users\mobilef\documents\visual studio 2010\projects\opencv_objtracking\opencv_briskmatching\main.cpp 54 1 OpenCV_BriskMatching 

ho potuto liberarmi di questo errore dichiarando la funzione mouseCallback come static in BriskMatching.h ma poi ho un intero botta di altri errori da quando mi riferisco a molte variabili membro non statici nella funzione mouseCallback.

Quindi la mia domanda per voi ragazzi è questa. Come dovrei modificare il mio codice per poter passare correttamente la mia funzione mouseCallback dichiarata nella classe BriskMatching alla funzione cv::setMouseCallback?

Grazie per tutto il vostro aiuto in anticipo!

risposta

12

Poiché una funzione membro utilizza un puntatore this, è necessaria una funzione di wrapper statico. In genere, si utilizza il parametro param essere l'indirizzo dell'oggetto che la funzione di membro appartiene, così si finisce con qualcosa di simile:

... 
static void mouseCallback(int event, int x, int y, int flags, void *param); 

void doMouseCallback(int event, int x, int y, int flags); 

E poi all'interno del mouseCallback:

void BriskMatching::mouseCallback(int event, int x, int y, int flags, void *param) 
{ 
    BriskMatching *self = static_cast<BriskMatching*>(param); 
    self->doMouseCallback(event, x, y, flags); 
} 
+0

Perfetto, grazie! Funziona alla grande, ma non capisco completamente la logica alla base o come funziona. Sono stato codificato in C++ per alcuni anni, ma ho sempre evitato i cast di tipo e quindi è sempre stato un po 'area grigia per me. Ora vado a leggerli e cerco di capire come funziona tutto questo. – szakeri

0

Stavo usando anche questo metodo, tuttavia mi sono reso conto che la classe di helper statica era piuttosto rigida e il tipo e il metodo vincolati.

Solo per ulteriore riferimento ho definito una funzione libera su modelli che assomiglia:

template<typename TClass, void (TClass::*MouseClickType)(int, int, int, int)> 
void FreeOnMouseCallback(int event, int x, int y, int flags, void* ptr) 
{ 
    auto* mcPtr = static_cast<TClass*>(ptr); 
    if(mcPtr != NULL) 
    { 
     (mcPtr->*MouseClickType)(event, x, y, flags); 
    } 
} 

E ora posso chiamare funzioni arbitrarie (corrispondente alla firma, ma non il nome) all'interno delle classi con

cv::setMouseCallback(WindowName, FreeOnMouseCallback<Calibrator, &Calibrator::OnMouseCallback>, this); 

Potrebbe essere esteso se è richiesto anche il void * ptr, ma l'ho omesso qui.

Problemi correlati