QT OpenCV setMouseCallback“参数类型不匹配”

时间:2014-02-21 16:48:53

标签: c++ qt opencv

我在一个程序中使用函数setMouseCallback,它在GUI中显示了ASUS XITON PRO的图像/深度图。现在我想从深度图中获取点击点远离华硕的信息。 我已经尝试过像这样使用setMousCallback的一些程序,它可以工作:

namedWindow("Tiefe",1);
setMouseCallback( "Tiefe", onMouse,0);

功能:

void onMouse( int event, int x, int y, int flags, void* param )
{
    if( event == CV_EVENT_LBUTTONUP)
    {
        distancePt   = Point(x,y);
        Vec3f s = world.at<Vec3f>(distancePt.y, distancePt.x);
        float dx = s[0];
        float dy = s[1];
        float dz = s[2];
        dist = sqrt(dx*dx + dy*dy + dz*dz);
            }
}

问题是,如果我尝试在我的程序(GUI)中使用此功能,我总是会收到错误:

/home/eye/Desktop/firstTry/GUI4DEPTHCAM/mainwindow.cpp:509: Fehler:argument of type 'void (MainWindow::)(int, int, int, int, void*)' does not match 'cv::MouseCallback {aka void (*)(int, int, int, int, void*)}'

像这样使用setMouseCallback:

setWindowTitle("Tiefe");
setMouseCallback("Tiefe",onMouse,0);

GUI(QLabel)中的窗口称为lblshow。 但如果我在setMouseCallback中将名称更改为“lblshow”,我会得到同样的错误。


感谢您的帮助,我已经尝试过这种方式......但现在我得到了这个错误:

OpenCV错误:cvSetMouseCallback中的空指针(NULL窗口处理程序),文件/home/eye/Downloads/opencv-2.4.6.1/modules/highgui/src/window_QT.cpp,第652行 在抛出'cv :: Exception'的实例后终止调用   what():/ home / eye / Downloads / opencv-2.4.6.1 / modules / highgui / src /window_QT.cpp:652:error:( - 27)函数cvSetMouseCallback中的NULL窗口处理程序

mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QWidget>
    #include <iostream>
    #include <QTimer>
    #include <QImage>
    #include <string>
    #include <cstdlib>
    #include <cstdio>

    /***************OPENCV_Headers*************/
    #include "opencv2/core/core.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/opencv.hpp"
    #include "opencv2/imgproc/imgproc.hpp"

    /***************Namespaces****************/
    using namespace cv;
    using namespace std;


    void mouseWrapper( int event, int x, int y, int flags, void* param );


    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
        Q_OBJECT

    public:


        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();

        void colorizeDisparity( const Mat &gray, Mat &rgb);

        void onMouse( int event, int x, int y, int flags, void* param );

        public slots:
        void RefreshImage();
        void Start();
        void Grauwert();
        void Bilateral();
        void Gaussian();
        void Median();
        void Canny();
        void Sobel();
        void Video();
        void Tief();
        void Cam();
        void adaptBilateral();
        void scharr();
        void Fil2D();
        void Tief_Farbe();
        void Tiefenmessung();


    private:
        Ui::MainWindow *ui;
        bool bilateral_f;
        bool Gaussian_f;
        bool Grauwert_f;
        bool Sobel_f;
        bool Canny_f;
        bool Median_f;
        bool Tief_Farbe_f;
        bool Video_f;
        bool cam;
        bool adapt_bil_f;
        bool scharr_f;
        bool zweiD_f;
        bool Tief_f;
        bool Tiefenmessung_f;
        bool einmalig;
        float *dist;

        QTimer *timer;
        VideoCapture *cap;
        Mat *image;
        Mat *Hilf;
        Mat *Hilf2;
        Mat *Hilf3;
        Mat *Hilf4;
        Mat *Hilf5;
        Mat *Hilf6;
        Mat *Hilf7;
        Mat *world;

        QImage *qimage;
        VideoWriter *writer;
        QString *Ordner;
        String Ordnerstring;
        char *buffer;
        QString *Info_Cam;
        QString *Info_Grau;
        QString *Info_Bil;
        QString *Info_Gau;
        QString *Info_Med;
        QString *Info_Can;
        QString *Info_Sob;
        QString *Info_Tief;
        QString *Info_Auf;
        QString *Info_Adapt_Bil;
        QString *Info_Scharr;
        QString *Info_zweiD;
        QString *Info_Tief_Farbe;


    };

#endif // MAINWINDOW_H

main.ccp

#include "mainwindow.h"
#include <QApplication>


/**************Main***********************/
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show(); 

   //while(1);    
   return a.exec();
}

mainwindow.ccp

#include "mainwindow.h"
#include "ui_mainwindow.h"    

void mouseWrapper( int event, int x, int y, int flags, void* param )
{
    MainWindow * mainWin = (MainWindow *) (param);
    if(mainWin != NULL)
    mainWin->onMouse(event,x,y,flags,0);
}

MainWindow::MainWindow(QWidget *parent) ://Konstruktor
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    timer = new QTimer();
    timer->setInterval(1);

    cap = new VideoCapture(0);
    cap->set(CV_CAP_PROP_OPENNI_REGISTRATION,1);    

    cout << "Gerät wird vorbereitet..." << endl;

    // Print some avalible device settings.
    cout << "\nDepth generator output mode:" << endl <<

    cout <<"\n REGISTRATION     " << cap->get( CV_CAP_PROP_OPENNI_REGISTRATION ) << endl<<
            "FRAME_WIDTH " << cap->get( CV_CAP_PROP_FRAME_WIDTH ) << endl <<
            "FRAME_HEIGHT " << cap->get( CV_CAP_PROP_FRAME_HEIGHT ) << endl <<
            "FRAME_MAX_DEPTH " << cap->get( CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH ) << " mm" << endl <<
            "FPS " << cap->get( CV_CAP_PROP_FPS ) << endl <<
            "REGISTRATION " << cap->get( CV_CAP_PROP_OPENNI_REGISTRATION ) << endl;

    if( cap->get( CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) )
    {
        cout <<"\nImage generator output mode:" << endl <<
            "FRAME_WIDTH " << cap->get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH ) << endl <<
            "FRAME_HEIGHT " << cap->get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT ) << endl <<
            "FPS " << cap->get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ) << endl;
    }


    image = new Mat;
    Hilf = new Mat;
    Hilf2 = new Mat;
    Hilf3 = new Mat;
    Hilf4 = new Mat;
    Hilf5 = new Mat;
    Hilf6 = new Mat;
    Hilf7 = new Mat;
    world = new Mat;
    dist = new float;


    qimage = new QImage;
    Ordner = new QString;
    buffer = new char;
    Info_Cam = new QString;
    Info_Grau = new QString;
    Info_Bil = new QString;
    Info_Gau = new QString;
    Info_Med = new QString;
    Info_Can = new QString;
    Info_Sob = new QString;
    Info_Tief_Farbe = new QString;
    Info_Auf = new QString;
    Info_Adapt_Bil = new QString;
    Info_Scharr = new QString;
    Info_zweiD = new QString;
    Info_Tief = new QString;

    writer = new VideoWriter;

    connect(timer, SIGNAL(timeout()), this, SLOT(RefreshImage()));
    connect(ui->Grau_Button,SIGNAL(clicked()),this,SLOT(Grauwert()));
    connect(ui->Bilateral_Button,SIGNAL(clicked()),this,SLOT(Bilateral()));
    connect(ui->Gaussian_Button,SIGNAL(clicked()),this,SLOT(Gaussian()));
    connect(ui->Median_Button,SIGNAL(clicked()),this,SLOT(Median()));
    connect(ui->Canny_Button,SIGNAL(clicked()),this,SLOT(Canny()));
    connect(ui->Sobel_Button,SIGNAL(clicked()),this,SLOT(Sobel()));
    connect(ui->pushButtonStart,SIGNAL(clicked()),this,SLOT(Start()));
    connect(ui->VideoButton,SIGNAL(clicked()),this,SLOT(Video()));
    connect(ui->Tief_Farbe_Button,SIGNAL(clicked()),this,SLOT(Tief_Farbe()));
    connect(ui->CameraButton,SIGNAL(clicked()),this,SLOT(Cam()));
    connect(ui->Adapt_Bilateral_Button,SIGNAL(clicked()),this,SLOT(adaptBilateral()));
    connect(ui->Scharr_Button,SIGNAL(clicked()),this,SLOT(scharr()));
    connect(ui->ZweiD_Button,SIGNAL(clicked()),this,SLOT(Fil2D()));
    connect(ui->Tief_Button,SIGNAL(clicked()),this,SLOT(Tief()));
    connect(ui->Tiefenmessung_Button,SIGNAL(clicked()),this,SLOT(Tiefenmessung()));

    bilateral_f=false;
    Gaussian_f=false;
    Grauwert_f=false;
    Sobel_f=false;
    Canny_f=false;
    Median_f=false;
    Tief_f=false;
    Video_f=false;
    cam = false;//entspricht cam 0
    adapt_bil_f=false;
    scharr_f=false;
    zweiD_f=false;
    Tief_Farbe_f=false;
    Tiefenmessung_f = false;
    einmalig = true;

    *Info_Cam = "Cam 0 gewählt";
    *Info_Grau = "inaktiv";
    *Info_Bil = "inaktiv";
    *Info_Gau = "inaktiv";
    *Info_Med = "inaktiv";
    *Info_Can = "inaktiv";
    *Info_Sob = "inaktiv";
    *Info_Tief = "inaktiv";
    *Info_Auf = "inaktiv";
    *Info_Adapt_Bil = "inaktiv";
    *Info_Scharr = "inaktiv";
    *Info_zweiD = "inaktiv";
    *Info_Tief_Farbe = "inaktiv";
}



MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::Start()
{
    timer->start();

}

void MainWindow::Bilateral()
{
    if(bilateral_f)
    {
        bilateral_f=false;
        *Info_Bil = "inaktiv";
    }
    else
    {
        bilateral_f=true;
        *Info_Bil = "aktiv";
    }
}

void MainWindow::adaptBilateral()
{
    if(adapt_bil_f)
    {
     adapt_bil_f=false;
     *Info_Adapt_Bil = "inaktiv";
    }
    else
    {
        adapt_bil_f=true;
        *Info_Adapt_Bil = "aktiv";
    }
}

void MainWindow::scharr()
{
    if(scharr_f)
    {
        scharr_f=false;
        *Info_Scharr = "inaktiv";
    }
    else
    {
        scharr_f=true;
        *Info_Scharr = "aktiv";
    }
}
void MainWindow::Fil2D()
{
    if(zweiD_f)
    {
        zweiD_f=false;
        *Info_zweiD = "inaktiv";
    }
    else
    {
        zweiD_f=true;
        *Info_zweiD = "aktiv";
    }
}

void MainWindow::Grauwert()
{
    if(Grauwert_f)
    {
        Grauwert_f=false;
        *Info_Grau = "inaktiv";
    }
    else
    {
        Grauwert_f=true;
        *Info_Grau = "aktiv";
    }
}
void MainWindow::Gaussian()
{
    if(Gaussian_f)
    {
        Gaussian_f=false;
        *Info_Gau = "inaktiv";
    }
    else
    {
        Gaussian_f=true;
        *Info_Gau = "aktiv";
    }
}
void MainWindow::Median()
{
    if(Median_f)
    {
        Median_f=false;
        *Info_Med = "inaktiv";
    }
    else
    {
        Median_f=true;
        *Info_Med = "aktiv";
    }
}
void MainWindow::Canny()
{
    if(Canny_f)
    {
        Canny_f=false;
        *Info_Can = "inaktiv";
    }
    else
    {
        Canny_f=true;
        *Info_Can = "aktiv";
    }
}
void MainWindow::Sobel()
{
    if(Sobel_f)
    {
        Sobel_f=false;
        *Info_Sob = "inaktiv";
    }
    else
    {
        Sobel_f=true;
        *Info_Sob = "aktiv";
    }
}

void MainWindow::Tief()
{
    if(Tief_f)
    {
        Tief_f=false;
        *Info_Tief = "inaktiv";
    }
    else
    {
        Tief_f=true;
        *Info_Tief = "aktiv";
    }
}

void MainWindow::Tief_Farbe()
{
    if(Tief_Farbe_f)
    {
        Tief_Farbe_f=false;
        *Info_Tief_Farbe = "inaktiv";
    }
    else
    {
        Tief_Farbe_f=true;
        *Info_Tief_Farbe = "aktiv";
    }
}
void MainWindow::Video()
{
    if(Video_f)
    {
        Video_f=false;
        einmalig = true;
        *Info_Auf = "inaktiv";
    }
    else
    {
        Video_f=true;
        einmalig = false;
        *Info_Auf = "aktiv";
    }
}

void MainWindow::Tiefenmessung()
{
    if(Tiefenmessung_f)
    {
        Tiefenmessung_f=false;

    }
    else
    {
           Tiefenmessung_f=true;
    }
}


void MainWindow::Cam()
{
    if(cam)
    {

        cap->release();
        *cap=VideoCapture(1);
        *Info_Cam = "Cam 1 gewählt";
        cam = false;
    }
    else
    {
        cap->release();
        *cap=VideoCapture(0);
        *Info_Cam = "Cam 0 gewählt";
        cam = true;
    }
}




void MainWindow::colorizeDisparity( const Mat &gray, Mat &rgb)
{
    //Checks a condition at runtime and throws exception if it fails (0)
    CV_Assert( !gray.empty() && gray.type() == CV_8UC1 );
    //Wenn der Inhalt von gray ein 8-bit single-channel array ist und es gefüllt ein Wert übergeben wurde

    double maxDisp=-1.f;
        float S=1.f;
        float V=1.f;

        if( maxDisp <= 0 )
        {
            maxDisp = 0;
            minMaxLoc( gray, 0, &maxDisp );
        }

    rgb.create( gray.size(), CV_8UC3 );
    rgb = Scalar::all(0);
    if( maxDisp < 1 )
        return;

    for( int y = 0; y < gray.rows; y++ )
    {
        for( int x = 0; x < gray.cols; x++ )
        {
            uchar d = gray.at<uchar>(y,x);
            unsigned int H = ((uchar)maxDisp - d) * 240 / (uchar)maxDisp;

            unsigned int hi = (H/60) % 6;
            float f = H/60.f - H/60;
            float p = V * (1 - S);
            float q = V * (1 - f * S);
            float t = V * (1 - (1 - f) * S);

            Point3f res;

            if( hi == 0 ) //R = V, G = t, B = p
                res = Point3f( p, t, V );
            if( hi == 1 ) // R = q, G = V, B = p
                res = Point3f( p, V, q );
            if( hi == 2 ) // R = p, G = V, B = t
                res = Point3f( t, V, p );
            if( hi == 3 ) // R = p, G = q, B = V
                res = Point3f( V, q, p );
            if( hi == 4 ) // R = t, G = p, B = V
                res = Point3f( V, p, t );
            if( hi == 5 ) // R = V, G = p, B = q
                res = Point3f( q, p, V );

            uchar b = (uchar)(std::max(0.f, std::min (res.x, 1.f)) * 255.f);
            uchar g = (uchar)(std::max(0.f, std::min (res.y, 1.f)) * 255.f);
            uchar r = (uchar)(std::max(0.f, std::min (res.z, 1.f)) * 255.f);

            rgb.at<Point3_<uchar> >(y,x) = Point3_<uchar>(b, g, r);
        }
    }
}


void MainWindow::onMouse( int event, int x, int y, int flags, void* param )

{
    Point distancePt(0,0);

    if( event == CV_EVENT_LBUTTONUP)
    {
        distancePt   = Point(x,y);
        Mat i;

        i= *world;

        Vec3f s = i.at<Vec3f>(distancePt.y, distancePt.x);
        float dx = s[0];
        float dy = s[1];
        float dz = s[2];
        *dist =sqrt(dx*dx + dy*dy + dz*dz);

            }
}


void MainWindow::RefreshImage()
{
    cap->grab();
    cap->open(CV_CAP_OPENNI);
    //cap->set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ );

    cap->retrieve( *image, CV_CAP_OPENNI_BGR_IMAGE);

        if (Grauwert_f)
        {

            cap->retrieve(*image,CV_CAP_OPENNI_GRAY_IMAGE);
            //cvtColor(*image,*image,CV_BGR2GRAY); //src,dst,Farbraumwandlung(,dstCn)
        }
        if(bilateral_f)
        {
            bilateralFilter(*image,*Hilf,9,9,9); //src,dst,sigmaColor,sigmaSpace(,bordeType)
            *image=*Hilf;
        }
        if(adapt_bil_f)
        {
            //adaptiveBilateralFilter(*image,*Hilf2,Size(3,3),2);//src,dst,ksize,sigmaSpace,sigmaMax(,borderType)
            //*image=*Hilf2; MUSS NOCH EINGEBUNDEN WERDEN
        }
        if(scharr_f)
        {
            Scharr(*image,*Hilf3,image->depth(),1,0);//src,dst,ddepth,dx,dy(,ksize,scale,delta,borderType)
            *image=*Hilf3;
        }
        if(zweiD_f)
        {
            sepFilter2D(*image,*Hilf4,image->depth(),1.5,1.5);//src,dst,ddepth,dx,dy(,ksize,scale,delta,borderType)
            *image=*Hilf4;
        }
        if (Gaussian_f)

        {
            int kernelsize = 5;

            GaussianBlur(*image,*image,Size(kernelsize,kernelsize), 1.5, 1.5); //src,dst,ksize,sigmaX,sigmaY(,borderType)
        }
        if (Median_f)
        {

            medianBlur(*image,*image,9); //src,dst,ksize
        }
        if (Sobel_f)
        {
            cv::Sobel(*image,*image,image->depth(),1,0,3); //src,dst,ddepth,dx,dy(,ksize,scale,delta,borderType)
        }
        if (Canny_f)
        {
            cv::Canny(*image,*image, 0, 50, 3); //src,dst,threshold1,threshold2(,apertureSize,L2gradient)
        }

        if(Tief_f)
        {

             Mat depthMap;
             cap->retrieve( depthMap, CV_CAP_OPENNI_DEPTH_MAP);
             const float scaleFactor = 0.05f;
             depthMap.convertTo( *image, CV_8UC1, scaleFactor );

             if(Tief_Farbe_f)
             {
                 Mat disparityMap;
                 Mat colorDisparityMap;

                 cap->retrieve( disparityMap, CV_CAP_OPENNI_DISPARITY_MAP );

                 colorizeDisparity(disparityMap,*image);

            }


             if (Tiefenmessung_f)
             {

                 cap->retrieve(*world, CV_CAP_OPENNI_POINT_CLOUD_MAP);

                 setWindowTitle("Tiefe");
                 setMouseCallback("Tiefe",mouseWrapper,this);

                 putText(*image,format("distance: %f m",*dist),Point(5,15),FONT_HERSHEY_PLAIN,1,Scalar(255));
                 putText(*image,format("Framerate: %f",cap->get(CV_CAP_PROP_FPS)),Point(5,30),FONT_HERSHEY_PLAIN,1,Scalar(255));
             }
        }



        if(!einmalig)
        {

            *Ordner = ui->Speicherort->text();
            Ordnerstring = Ordner->toStdString();

        *writer = VideoWriter (Ordnerstring.data() ,
                                     CV_FOURCC('D','I','V','X'),
                                     30,
                                     cv::Size(cap->get(CV_CAP_PROP_FRAME_WIDTH),cap->get(CV_CAP_PROP_FRAME_HEIGHT)));
            einmalig = true;
            }


        //BGR abfangen und in RGB wandeln
        if((image->type() == CV_8UC3) || (image->type() == CV_32FC3))
        {

            cvtColor(*image,*Hilf5,CV_BGR2RGB);
            *image = *Hilf5;

        }

            //Wenn Bild in Grauwerten
        if((image->type() == CV_8UC1) || (image->type() == CV_32FC1))
        {
            cvtColor(*image,*Hilf6,CV_GRAY2RGB);
            *image = *Hilf6;
            *qimage=QImage((uchar*)(image->data),image->cols,image->rows,QImage::Format_Indexed8);
        }

        if(Video_f)
        {

            cvtColor(*image,*Hilf7,CV_RGB2BGR);//Umwandlung muss erfolgen, da writer ein BGR Bild innerhalb seiner Klasse in ein RGB umwandelt
            writer->write(*Hilf7);//write *image into the file
        }


         *qimage=QImage((uchar*)(image->data),image->cols,image->rows, QImage::Format_RGB888);//The image is stored using a 24-bit RGB format (8-8-8).

        ui->lblshow->setPixmap(QPixmap::fromImage(*qimage,Qt::AutoColor));
        ui->lblshow->resize(ui->lblshow->pixmap()->size());


        ui->Info_Bil->setText(*Info_Bil);
        ui->Info_Auf->setText(*Info_Auf);
        ui->Info_Cam->setText(*Info_Cam);
        ui->Info_Can->setText(*Info_Can);
        ui->Info_Gaus->setText(*Info_Gau);
        ui->Info_Grau->setText(*Info_Grau);
        ui->Info_Med->setText(*Info_Med);
        ui->Info_Sob->setText(*Info_Sob);
        ui->Info_Tief->setText(*Info_Tief);
        ui->Info_Adapt_Bil->setText(*Info_Adapt_Bil);//neu
        ui->Info_Scharr->setText(*Info_Scharr);//neu
        ui->Info_ZweiD->setText(*Info_zweiD);//neu
        ui->Info_Tief_Farbe->setText(*Info_Tief_Farbe);//neu

}

2 个答案:

答案 0 :(得分:1)

setMouseCallback想要一个静态函数,你给它一个非静态的类成员。

可能最好的方法是使用静态回调函数,重定向到类方法。

void mouseWrapper( int event, int x, int y, int flags, void* param ); // forward decl needed here

struct MainWindow
{
    void onMouse( int event, int x, int y, int flags, void* param )
    {
        if( event == CV_EVENT_LBUTTONUP)
        //....
    }

    void init() 
    {
        setWindowTitle("Tiefe");
        setMouseCallback("Tiefe",mouseWrapper,this);
    }


};


void mouseWrapper( int event, int x, int y, int flags, void* param )
{
    MainWindow * mainWin = (MainWindow *)(param);
    mainWin->onMouse(event,x,y,flags,0);
}

答案 1 :(得分:0)

我也有同样的问题,我检查了github和stackoverflow,没有人解决这个问题。

所以我尝试将“ setWindowTitle(” Tiefe“)”更改为“ cv :: nameWindow(” Tiefe“)”,然后解决该错误。

也许这样可以帮助您解决问题