opencv — Предоставление функции обратного вызова доступа к членам класса данных в переполнении стека

Я использую библиотеку opencv в C ++ в своем проекте, и у меня возникают проблемы с использованием MouseCallback.

У меня есть класс BoardCalibration, который имеет два элемента данных, которые мне нужны, чтобы использовать их внутри функции обратного вызова. Вы можете увидеть этот класс ниже:

class BoardCalibration{
private:
Rect _box;  <-- data members i need to upadte inside the callback function
bool _drawingBox; <--

public:
BoardCalibration();
static void my_mouse_callback(int event, int x, int y, int flags, void* param);
Rect calibrate(Mat& image);
void drawBox(IplImage* img);
};

В методе calibrate () я вызываю функцию, которая получает функцию обратного вызова my_mouse_callback. Код:

Rect BoardCalibration::calibrate(Mat& image){
IplImage * img = new IplImage(image);

namedWindow("Calibration");

IplImage *temp = cvCloneImage(img);
cvSetMouseCallback("Calibration", my_mouse_callback, (void *)img);

while (1){

imshow("Calibration", Mat(img));
cvCopyImage(img,temp);

if( _drawingBox ){
drawBox(temp);
}

imshow("Calibration", Mat(temp));

if (waitKey(1)>=0)
break;
}

cout << "calibrated\n";

delete img;
return _box;
}

А при реализации my_mouse_callback есть:

static void my_mouse_callback(int event, int x, int y, int flags, void* param){

IplImage* image = (IplImage*) param;

switch( event ) {
case CV_EVENT_MOUSEMOVE: {
if( _drawingBox ) {
_box.width  = x-_box.x;
_box.height = y-_box.y;
}
}
break;
case CV_EVENT_LBUTTONDOWN: {
_drawingBox = true;
_box = Rect( x, y, 0, 0 );
}
break;
case CV_EVENT_LBUTTONUP: {
_drawingBox = false;
if( _box.width<0 ) {
_box.x+=_box.width;
_box.width *=-1;
}
if( _box.height<0 ) {
_box.y+=_box.height;
_box.height*=-1;
}

//drawBox(image, box);  // keep draw on screen
// display rectangle coordinates
cout << "TopLeft: (" << _box.x << "," << _box.y << "), BottomRight: ("<< _box.x+_box.width << "," << _box.y+_box.height << ")" << endl;
}
break;
}
}

Как вы можете видеть, я пытаюсь добраться до членов _box и _drawingBox, но, поскольку это статический метод, он не распознает их.
Как я могу решить эту проблему?? Я не могу изменить прототип my_mouse_callback, иначе он не будет принят cvSetMouseCallback.
Я также не могу определить эти данные за пределами класса, потому что это дает мне ошибку, которую они уже определили.
Есть что-нибудь еще, что я могу попробовать ???
Благодарю.

0

Решение

Я ничего не знаю о opencv, но как насчет этого

struct Helper
{
IplImage * pI;
BoardCalibration * pObj;
};Rect BoardCalibration::calibrate(Mat& image)
{
.... stuff ....

Helper * p = new Helper;
p->pI = img;
p->pObj = this;

cvSetMouseCallback("Calibration", my_mouse_callback, (void *)p);

.... stuff ...delete p;
delete img;
return _box;

}static void BoardCalibration::my_mouse_callback(int event, int x, int y, int flags, void* param)
{
Helper * p = (Helper *)param;
IplImage* image = p->pI;
BoardCalibration * pBC = p->pObj;

switch( event )
{
case CV_EVENT_MOUSEMOVE:
{
if( pBC->_drawingBox )  // use the pBC pointer

... stuff ...}

... stuff ...

}

Я не знаю поток вашего кода, чтобы выяснить, когда именно вспомогательный объект должен быть удален. Итак, у меня есть delete Helper object код рядом с delete img потому что, если этот код был правильным, то это, вероятно, было бы правильным местом для delete вспомогательный объект тоже. Но вы должны это проверить. Вы должны удалять эти объекты только тогда, когда вы уверены, что обратный вызов завершит работу для этого вызова к тому времени.

6

Другие решения

Ладно, я понял. Вы должны сделать это. Это уже было успешно.

1) cvSetMouseCallback("Calibration", my_mouse_callback, (void *)this); // Callback function to give it a this pointer.
2) BoardCalibration* ptr = (BoardCalibration*) param; // ptr pointer to your class.
3) e.g ptr->  _box oder ptr-> _drawingBox //all the private parameters,that you need to use, do this:

удачи. Я надеюсь, что это поможет вам решить проблему.
Битте сэр.
Qiuyue Ван.

1

Я не знаю, как детали сделать это, но у меня есть идея, что если бы мы могли

cvSetMouseCallback("Calibration", my_mouse_callback, (void *)img);

param (объект) — это определяемый пользователем параметр, который передается в функцию обратного вызова.
Так что, если бы мы могли вместо img, использовать pointer указать class, может быть, мы могли бы использовать this-> все приватные параметры или class. все публичные функции.
но у меня просто есть идея, вы должны попробовать, может быть, удачно …

удачи.
скажи мне, если ты сделал это.
ван.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector