我在一個程序中使用函數setMouseCallback,它向我展示了一個華碩XITON PRO的圖像/深度圖。現在我想從深度圖中獲得信息,點擊點離華碩有多遠。 我試着使用setMousCallback像這樣的一些程序和它的工作原理:QT OpenCV setMouseCallback「參數類型不匹配」
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);
}
}
的問題是,如果我嘗試我PROGRAMM(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 /目錄/下載/ 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:錯誤:(-27)函數中的NULL窗口句柄cvSetMouseCallback
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
}