2013-07-11 9 views
5

के क्लास आधारित कार्यान्वयन को बनाने में परेशानी होने के कारण शीर्षक के अनुसार, मुझे कक्षा आधारित सी ++ संरचना में ओपनसीवी के माउस कॉलबैक फ़ंक्शन को लागू करने में कुछ समस्याएं आ रही हैं। मुझे समझाने की अनुमति दें। मैंने BriskMatching नामक एक क्लास को परिभाषित किया है जिसमें मैंने ओपनसीवी की आवश्यकता वाले सही पैरामीटर के साथ माउसकॉलबैक नामक एक सदस्य फ़ंक्शन बनाया है (कृपया नीचे कोड स्निपेट देखें)।ओपनसीवी के माउस कॉलबैक फ़ंक्शन

**Briskmatching.h** 

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

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

यह सब ठीक है लेकिन मेरी समस्या पैदा होती है जब मैं OpenCV के cv::setMouseCallback समारोह के माध्यम से नामित माउस कॉलबैक समारोह के रूप में इस समारोह सेट करने का प्रयास करता है।

अपने मुख्य समारोह में, मैं BriskMatching briskMatcher कहा जाता है तो जब यह माउस कॉलबैक मैं बहुत तरह यह करने के लिए प्रयास करने के लिए सेट करने के लिए समय ... आता

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

दुर्भाग्य से, यह फेंकता वर्ग का एक उदाहरण बनाने एक त्रुटि।

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 

मैं mouseCallback समारोह की घोषणा के बाद से मैं mouseCallback समारोह में कई गैर स्थिर सदस्य चर का उल्लेख के रूप में BriskMatching.h में static लेकिन फिर मैं अन्य त्रुटियों की एक पूरी अजीब प्राप्त करके इस त्रुटि से छुटकारा पाने सकता है।

तो मेरे लिए आपका प्रश्न यह है। cv::setMouseCallback फ़ंक्शन में BriskMatching क्लास में घोषित मेरे माउस कॉलबैक फ़ंक्शन को सही तरीके से पास करने में सक्षम होने के लिए मैं अपने कोड को कैसे संशोधित कर सकता हूं?

उन्नत में आपकी सभी मदद के लिए धन्यवाद!

उत्तर

12

चूंकि सदस्य फ़ंक्शन this पॉइंटर लेता है, तो आपको एक स्थिर रैपर फ़ंक्शन की आवश्यकता होगी। आमतौर पर, आप param पैरामीटर का उपयोग वस्तु सदस्य समारोह के अंतर्गत आता है इस बात का पता होना करने के लिए है, तो आप कुछ इस तरह के साथ अंत:

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

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

और फिर 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

बिल्कुल सही, धन्यवाद! यह बहुत अच्छा काम करता है, लेकिन मैं इसके पीछे तर्क या यह कैसे काम करता है पूरी तरह से समझ में नहीं आता है। मैं अब कुछ वर्षों से सी ++ में कोडिंग कर रहा हूं, लेकिन मैंने हमेशा प्रकार का सेवन टाला है और इसलिए यह हमेशा मेरे लिए भूरे रंग का क्षेत्र रहा है। मैं अब उन पर पढ़ने जा रहा हूं, और यह समझने की कोशिश करता हूं कि यह सब कैसे काम करता है। – szakeri

0

मैं भी इस विधि का उपयोग कर रहा था, हालांकि मुझे एहसास हुआ कि स्थैतिक सहायक वर्ग काफी कठोर और प्रकार और विधिबद्ध था।

बस आगे के संदर्भ के लिए मैं एक टेम्प्लेटेड मुक्त समारोह है कि लग रहा है परिभाषित किया है की तरह:

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

और अब मैं

साथ वर्गों के अंदर मनमाने ढंग से कार्य (हस्ताक्षर मिलान, लेकिन नाम नहीं) कॉल कर सकते हैं
cv::setMouseCallback(WindowName, FreeOnMouseCallback<Calibrator, &Calibrator::OnMouseCallback>, this); 

शून्य * पीआरटी की आवश्यकता होने पर इसे बढ़ाया जा सकता है, लेकिन मैंने इसे यहां छोड़ दिया है।

संबंधित मुद्दे