我在我的项目中使用opencv库,我在使用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 << "calibratedn";
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接受。我也不能在类之外定义那些数据成员因为它会给我错误,因为它们已经定义了。还有什么我可以试试的吗?谢谢。
我对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 ...
}
我不知道您的代码流程,以确定何时应该删除helper对象。所以我有delete Helper object
代码靠近delete img
,因为如果代码是正确的,那么这可能是delete
的正确位置,也就是助手对象。但是你需要检查一下。只有当您确定回调将在此之前完成该调用的运行时,才需要删除该对象。
好的,我知道了。你应该这么做。它已经成功了。
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。
我不知道怎么做的细节,但我有一个想法,如果我们可以
cvSetMouseCallback("Calibration", my_mouse_callback, (void *)img);
param
(object)是用户自定义的参数,传递给回调函数。因此,如果我们可以代替img
,使用pointer
来指向class
,也许我们可以使用this->
所有私有参数或class
所有公共函数。但我只是有一个想法,你应该尝试一下,也许会成功…
好运。告诉我你是否成功了。王。