0

プロジェクトで C++ の opencv ライブラリを使用していますが、MouseCallback の使用に問題があります。

コールバック関数内で使用する必要がある 2 つのデータ メンバーを持つクラス 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);
};

calibration() メソッドで、コールバック 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 によって受け入れられません。また、それらが既に定義されているというエラーが発生するため、クラスの外部でこれらのデータメンバーを定義することもできません。他に試すことができるものはありますか?ありがとう。

4

3 に答える 3

6

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。そのコードが正しければ、これはおそらくdeleteHelperオブジェクトにとっても適切な場所になるからです。しかし、それを確認する必要があります。このオブジェクトを削除する必要があるのは、それまでにそのコールのコールバックの実行が終了したことが確実な場合のみです。

于 2012-12-27T23:21:38.347 に答える
1

はい、分かりました。あなたはそうするべきです.それはすでに成功しています.

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:

幸運を。問題の解決に役立つことを願っています。Bitte sehr。王秋月。

于 2013-01-04T14:54:32.963 に答える
0

詳細な方法はわかりませんが、アイデアはあります。

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

param(オブジェクト) は、コールバック関数に渡されるユーザー定義のパラメーターです。imgしたがって、 の代わりに を使用してpointerを指すことができればclass、おそらくthis->すべてのプライベート パラメータまたはclass.all パブリック関数を使用できます。しかし、私にはアイデアがあります。試してみてください。おそらく成功するでしょう...

幸運を。できたか教えて。王。

于 2013-01-04T13:38:54.777 に答える