3

C ++でクラスを操作するときに、OpenCVでトラックバーのコールバックを定義する方法について質問があります。

トラックバーを定義するとき、.cppクラスのコンストラクターメソッドでコールバックを定義するにはどうすればよいですか?

関数ポインタを操作しようとしましたが、うまくいきません。私は何か非常に間違ったことをしているに違いないと思います:-)

これは私のヘッダーファイルです:

class SliderwithImage {

public:
    SliderwithImage(void);
    ~SliderwithImage(void); 

    void sliderCallBack(int pos);
};

これは実装ファイルです:

#include "SliderwithImage.h"

void SliderwithImage::sliderCallBack(int pos) {


}

SliderwithImage::SliderwithImage(void)  {

    const char* windowName = "window";
    int lowvalue  =1;

    namedWindow(windowName,  CV_GUI_EXPANDED);

    createTrackbar("mytrackbar", windowName, &lowvalue, 255, sliderCallBack);

}

SliderwithImage::~SliderwithImage(void) {

}

明らかに、createTrackbarメソッドはsliderCallBackを認識しません...スコープの問題だと思います。しかし、私はこれを解決する方法がわかりませんか?

どんな助けでもいただければ幸いです。

どうもありがとうございます。

4

3 に答える 3

6

コールバック関数は静的またはグローバルである必要がありますが、操作するオブジェクトへの参照を渡すことができます(OpenCVユーザーメーリングリストのこの投稿を参照してください)。

createTrackbarメソッドには、呼び出し元の関数に渡されるパラメーターがありますCには、で定義されuserdataている文書化されていない メソッドがあり、同じ機能があります。cvCreateTrackbar2highgui_c.h

CVAPI(int) cvCreateTrackbar2( const char* trackbar_name, const char* window_name,
    int* value, int count, CvTrackbarCallback2 on_change,
    void* userdata CV_DEFAULT(0));

これらのメソッドを使用すると、そのクラスのオブジェクトへのポインターを受け取る静的コールバック関数を使用してクラスを作成できます。次のようにトラックバーを作成できます。

cv:createTrackbar("Label", "Window" &variable, MAX_VAL, &MyClass::func, this);

コールバックは次のようになります。

void MyClass:func(int newValue, void * object) {
    MyClass* myClass = (MyClass*) object;
    // ...do stuff.
}

トラックバーの作成時に変数へのポインターを指定している限り、変数を自分で明示的に更新する必要はありませんが(上記のように)、最初に変数を処理する必要がある場合は、コールバック関数で明示的に設定することをお勧めします。

于 2012-05-10T05:25:16.707 に答える
3

コールバック関数は、グローバル関数または静的メンバー関数として実装する必要があります。よりOOPに見えるようにするには、静的メンバー関数として実装することをお勧めします:)

于 2011-12-26T15:05:08.537 に答える
0

別のソリューションを使用して、クラス変数のスライダー値を取得しています(私の場合、ライブビデオストリームの選択された回転角度を取得します)。int* valuecreateTrackbar関数のはパブリッククラス変数であり、ループ内で使用されます(ビデオの取得中ですが、これは単一の画像を繰り返し再描画する際に混乱する可能性があります)。

最善の解決策ではありませんが、それは私にとってはうまくいきます。

cv::createTrackbar("Rotation Angle(deg)", "Preview", &rotationAngle, 
alpha_slider_max, NULL);

    for(;;)
    {
        int rotAngle = this -> rotationAngle;
        cv::Mat frame;
        cv::Mat rot_frame;
        this -> capture >> frame;
        rot_frame = rotateVideo (frame, rotAngle);  
        imshow("Preview", rot_frame);
        if(cv::waitKey(30) >= 0) break;
    }
于 2013-01-17T15:52:48.517 に答える