2013-07-11 23 views
5

Başlığın önerdiği gibi, sınıf tabanlı bir C++ yapısında OpenCV'nin mouseCallback işlevini uygulamakta sorun yaşıyorum. Açıklamama izin ver. OpenCV'nin gerektirdiği doğru parametrelerle mouseCallback adında bir üye işlevi oluşturduğum BriskMatching adında bir sınıf tanımladım (lütfen aşağıdaki kod parçacığına bakın). OpenCV'nin mouseCallback işlevinin sınıf tabanlı bir uygulamasını oluşturmada sorun yaşanıyor

**Briskmatching.h** 

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

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

Bu

Ben OpenCV en cv::setMouseCallback işlevi aracılığıyla belirlenen fare geri arama fonksiyonu olarak bu fonksiyonu ayarlamak çalıştığınızda ancak benim sorun doğar, tüm gayet iyi. benim ana işlevinde

, bunu o kadar gibi yapmak girişiminde fare geri arama ayarlamak için zaman ... geldiğinde ardından

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

Maalesef bu atar briskMatcher denilen BriskMatching sınıfının bir örneğini oluşturmak bir hata.

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 

ben mouseCallback fonksiyonunda birçok statik olmayan üye değişkenleri ifade beri diğer hatalar bütün bir Patlat olsun staticBriskMatching.h içinde ama sonra olarak mouseCallback fonksiyonunu ilan ederek bu hatanın kurtulmak başladı.

Bu yüzden size sorum şu ki. BriskMatching sınıfında bildirilen mouseCallback işlevimi cv::setMouseCallback işlevine doğru şekilde iletebilmek için kodumu nasıl değiştirmeliyim?

Gelişmiş tüm yardımlarınız için teşekkürler!

cevap

12

Bir üye işlevi bir this işaretçisini aldığından, bir statik sarmalayıcı işlevine ihtiyacınız olacaktır. Genellikle, üye işlev ait olduğu nesnenin adresi olması param parametresini kullanın, bu nedenle böyle bir şey ile sonuna kadar: mouseCallback içindeki ardından

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

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

Ve:

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

Mükemmel, teşekkürler! Harika çalışıyor, ancak arkasındaki mantığı veya nasıl çalıştığını tam olarak anlamıyorum. C++ 'da birkaç yıldır kod yazıyordum, ama ben her zaman tip kadrajlardan kaçındım ve bu yüzden her zaman benim için biraz gri alan oldum. Şimdi onları okuyacağım ve bunların nasıl çalıştığını anlamaya çalışacağım. – szakeri

0

Ben de bu yöntemi kullanıyordum, ancak statik yardımcı sınıfın oldukça katı ve tip ve yöntemin bağlı olduğunu fark ettim. Ben görünen bir şablonu ücretsiz işlevi tanımladığınız Sadece daha fazla referans için

gibi:

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

Ve şimdi

ile sınıflar içindeki keyfi fonksiyonlar (imza eşleşen ancak ad) çağırabilir
cv::setMouseCallback(WindowName, FreeOnMouseCallback<Calibrator, &Calibrator::OnMouseCallback>, this); 

Eğer void * ptr de gerekliyse uzatılabilir, ama ben onu burada ihmal ettim.

İlgili konular