cvSetMouseCallback в OpenCV 2.1 Managed C++ (CLI/C++)

Имя моего класса — HandMotionRecognition, и я вызываю метод getColorPixel в обратном вызове мыши. Это в OpenCV с использованием Visual Studio 2010, а тип проекта — c++ -> cli.

Стандартный код (если я не ошибаюсь) для обработки событий мыши:

cvSetMouseCallback( "CameraIn", getColorPixel, (void*) frameHSV);

Но при компиляции выдает ошибку времени компиляции

ошибка C3867: 'HandMotionRecognition::getColorPixel': в вызове функции отсутствует список аргументов; используйте '&HandMotionRecognition::getColorPixel' для создания указателя на элемент

Затем я делаю, как сказал, и помещаю код следующим образом...

cvSetMouseCallback( "CameraIn", &HandMotionRecognition::getColorPixel, (void*) frameHSV);

Но опять получаю ошибку компиляции..

ошибка C3374: невозможно получить адрес «HandMotionRecognition::getColorPixel», если не создан экземпляр делегата

Итак, я создаю делегата, подобного этому... [создание делегата.. Я не знаю, что это на 100% правильно]

  1. Я поставил delegate void MouseCallbackDelegate( int event, int x, int y, int flags, void *param ); в HandMotionRecognition.h

  2. Я поместил этот код в HandMotionRecognition.cpp вместо cvSetMouseCallback( "CameraIn", &HandMotionRecognition::getColorPixel, (void*) frameHSV);

    MouseCallbackDelegate ^StaticDelInst = gcnew MouseCallbackDelegate(this, &HandMotionRecognition::getColorPixel);
    

    cvSetMouseCallback("CameraIn", StaticDelInst, (void*)frameHSV);

Но затем он дает ошибку компиляции: (это единственная ошибка, которую я получаю)

ошибка C2664: «cvSetMouseCallback»: невозможно преобразовать параметр 2 из «HandMotionRecognition::MouseCallbackDelegate ^» в «CvMouseCallback»

(Насколько я вижу... это связано с использованием cli вместо win32)

Есть ли обходной путь или я что-то не так делаю???

Пожалуйста помоги...


person Sachira    schedule 27.06.2011    source источник
comment
Это довольно полный набор сообщений об ошибках. :-) К сожалению, кажется, что CV хочет использовать указатель функции (собственный) в качестве параметра. Эта функция никогда не может быть функцией-членом, управляемой или собственной.   -  person Bo Persson    schedule 27.06.2011
comment
Спасибо за информацию... Я не знал, что это не работает с функциями-членами... нужно снова заглянуть в opencv... Теперь это исправлено.. Удален getColorPixel() из класса и добавлен в тот же файл (сразу за пределами класса) .. теперь он работает   -  person Sachira    schedule 27.06.2011


Ответы (1)


Как вы обнаружили, метод обратного вызова должен быть статическим (или функцией, не являющейся членом). Стандартной идиомой в этом случае является передача указателя экземпляра класса в параметре void* param и использование функции static для вызова функции-члена. Поскольку в настоящее время вы используете param для хранения frameHSV, вам нужно передать это каким-то другим способом (например, сохранив его в своем экземпляре класса).

Пример:

class HandMotionRecognition { 
/* your code */
private:
  void getPixelColor(int event, int x, int y, int flags, void* param) {
  }
public:
  static void mouseCallback(int event, int x, int y, int flags, void* param) {
    static_cast<HandMotionRecognition*>(param)->getPixelColor(event, x, y, flags);       
  }
}

И для регистрации:

HandMotionRecognition* hmr = /* ... */
hmr->setFrameHSV(frameHSV);
cvSetMouseCallback("CameraIn", &HandMotionRecognition::mouseCallback, hmr);
person user786653    schedule 27.06.2011
comment
@Sachira На всякий случай, если это недостаточно очевидно, но оно должно быть как статическим, так и общедоступным. - person karlphillip; 27.06.2011