2013-07-11 12 views
5

Jak sugeruje tytuł, mam pewne problemy z implementacją funkcji mouseCallback OpenCV w klasowej strukturze C++. Pozwól mi wyjaśnić. Zdefiniowałem klasę o nazwie BriskMatching, w której utworzyłem funkcję członkowską o nazwie mouseCallback z poprawnymi parametrami wymaganymi przez OpenCV (zobacz poniższy fragment kodu).Masz problemy z tworzeniem opartej na klasach implementacji funkcji mouseCallback OpenCV

**Briskmatching.h** 

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

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

To wszystko jest w porządku, jednak mój problem pojawia się, gdy próbuję ustawić tę funkcję wyznaczonej funkcji zwrotnej mysz poprzez cv::setMouseCallback funkcji OpenCV jest.

W moim głównej funkcji, utworzyć instancję klasy BriskMatching zwanego briskMatcher wtedy, gdy przychodzi czas, aby ustawić zwrotnego myszy staram się robić to jak tak ...

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

Niestety, ten wyrzuca błąd.

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 

mogę pozbyć się tego błędu deklarując funkcję mouseCallback jak static w BriskMatching.h ale potem dostaję całe pomazane innych błędów ponieważ odnoszą się do wielu non-statycznych zmiennych składowych w funkcji mouseCallback.

Moje pytanie do was jest takie. Jak zmodyfikować mój kod, aby móc poprawnie przekazać moją funkcję mouseCallback zadeklarowaną w klasie BriskMatching do funkcji cv::setMouseCallback?

Dzięki za pomoc w zaawansowanej!

Odpowiedz

12

Ponieważ funkcja składowa przyjmuje wskaźnik this, potrzebna jest funkcja owijania statycznego. Zazwyczaj użyć parametru param być adres obiektu, że funkcja członkiem należy, więc możesz skończyć z czymś takim:

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

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

A potem wewnątrz 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

Doskonale, dzięki! Działa wspaniale, ale nie rozumiem całkowicie logiki stojącej za tym i jak działa. Od kilku lat koduję w C++, ale zawsze unikałem rzutowania typu, więc zawsze było dla mnie trochę szarej strefy. Przeczytam je teraz i spróbuję zrozumieć, jak to wszystko działa. – szakeri

0

Używałem również tej metody, jednak zdałem sobie sprawę, że statyczna klasa pomocnicza była dość sztywna, a typ i metoda powiązane.

Tylko dla dalszego odniesienia Mam zdefiniowano szablonie bezpłatną funkcję, która wygląda tak:

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

I mogę teraz nazywamy dowolne funkcje (dopasowanie podpis, ale nie nazwy) wewnątrz klas z

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

Może on zostać przedłużony, jeśli wymagana jest również pustka * ptr, ale tutaj ją pominięto.

Powiązane problemy