Bonjour,
je voulais approfondir mes connaissances avec Qt, et comme je suis passionne de vision par ordinateur, je me suis lance dans un projet de GUI qui devrait integrer a terme des features cool, telles que: ajout d'options de debug dans l'algo du filtre de vision pour pouvoir visualiser les traitements intermediaires de traitement d'image, enregistrement, lecture de sources differente (webcm, avi, etc.)...
Pour le moment mon travail fonctionne "presque":
la conversion IplImage->QImage est ok, je peux utiliser certaines fonctions de OpenCV, mais avec d'autres, telles que cvCanny, j'ai un runtime error. Je ne vois vraiment pas pourquoi, et je ne suis pas tres bon pour debugger, c'est pourquoi je viens vous demander conseil
Mon code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include "MyCVFilter.h" MyCVFilter::MyCVFilter(IplImage* in) { dummy = cvCreateImage(cvSize(in->width,in->height), in->depth, in->nChannels); dummy1 = cvCreateImage(cvSize(in->width,in->height), in->depth, in->nChannels); dummy2 = cvCreateImage(cvSize(in->width,in->height), in->depth, in->nChannels); dummy3 = cvCreateImage(cvSize(in->width,in->height), in->depth, in->nChannels); dummy4 = cvCreateImage(cvSize(in->width,in->height), in->depth, in->nChannels); dummy5 = cvCreateImage(cvSize(in->width,in->height), in->depth, in->nChannels); cannyImg = cvCreateImage(cvSize(in->width,in->height), in->depth, 1); } void MyCVFilter::execute(IplImage* in, IplImage* out) { cvSmooth(in,dummy); cvCvtColor(dummy,dummy1,CV_BGR2HSV); cvCanny(dummy1,dummy2,20,40); cvSmooth(dummy2,out); } MyCVFilter::~MyCVFilter(){}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <C:\OpenCV2.1\include\opencv\cv.h> #include <C:\OpenCV2.1\include\opencv\cxcore.h> #include <C:\OpenCV2.1\include\opencv\cvaux.h> class MyCVFilter { public: MyCVFilter(IplImage* in); void execute(IplImage* in, IplImage* out=0); ~MyCVFilter(); private: IplImage* dummy; IplImage* dummy1; IplImage* dummy2; IplImage* dummy3; IplImage* dummy4; IplImage* dummy5; IplImage* cannyImg; };
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 #include "Window.h" Window::Window() : QWidget() { m_layout = new QVBoxLayout; m_buttonQuit = new QPushButton("Quit",this); m_buttonRandom = new QPushButton("Random",this); m_layout->addWidget(m_buttonQuit); m_layout->addWidget(m_buttonRandom); this->setLayout(m_layout); QObject::connect(m_buttonQuit,SIGNAL(clicked()),this,SLOT(quitDial())); QObject::connect(this,SIGNAL(Iquit()),qApp,SLOT(quit())); QObject::connect(m_buttonRandom,SIGNAL(clicked()),this,SLOT(randomDial())); } Window::Window(CvCapture* cam, IplImage* CVImage) : QWidget() { m_layout = new QVBoxLayout; m_buttonQuit = new QPushButton("Quit",this); m_buttonRandom = new QPushButton("Random",this); QtOut = new QOpenCVWidget(this); QtIn = new QOpenCVWidget(this); dude = new MyCVFilter(CVImage); in = cvCreateImage(cvSize(CVImage->width,CVImage->height), CVImage->depth, CVImage->nChannels); out = cvCreateImage(cvSize(CVImage->width,CVImage->height), CVImage->depth, CVImage->nChannels); camera = cam; m_layout->addWidget(QtIn); m_layout->addWidget(QtOut); m_layout->addWidget(m_buttonQuit); m_layout->addWidget(m_buttonRandom); this->setLayout(m_layout); resize(500, 400); startTimer(100); // 0.1-second timer QObject::connect(m_buttonQuit,SIGNAL(clicked()),this,SLOT(quitDial())); QObject::connect(this,SIGNAL(Iquit()),qApp,SLOT(quit())); QObject::connect(m_buttonRandom,SIGNAL(clicked()),this,SLOT(randomDial())); } void Window::quitDial() { int reponse = QMessageBox::question(this, "VisionEditor2", "Quit?", QMessageBox::Yes | QMessageBox::No); if(reponse == QMessageBox::Yes) emit Iquit(); } void Window::randomDial() { QString coucou = QInputDialog::getText ( this, "Pseudo", "Qui es-tu?"); if(coucou == "Stef") QMessageBox::information(this, "Pseudo", "Bonjour Stef, ça va ?"); else QMessageBox::information(this, "Pseudo", "Dude, qui es-tu ?"); } //appel toutes les .1 secondes avec startTimer(100) void Window::timerEvent(QTimerEvent*) { in=cvQueryFrame(camera); //Execute l'algo de vision dude->execute(in,out); QtIn->putImage(in); QtOut->putImage(out); } Window::~Window(){}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #ifndef DEF_WINDOW #define DEF_WINDOW #include <QApplication> #include <QWidget> #include <QPushButton> #include <QImage> #include <QSlider> #include <QProgressBar> #include <QMessageBox> #include <QInputDialog> #include <QVBoxLayout> #include <QDebug> #include "QOpenCVWidget.h" #include "Window.h" #include "MyCVFilter.h" #include <C:\OpenCV2.1\include\opencv\cv.h> #include <C:\OpenCV2.1\include\opencv\cxcore.h> #include <C:\OpenCV2.1\include\opencv\cvaux.h> #include <C:\OpenCV2.1\include\opencv\highgui.h> class Window : public QWidget { Q_OBJECT public: Window(); Window(CvCapture *cam, IplImage* CVImage); ~Window(); public slots: void quitDial(); void randomDial(); signals: void helloStef(); void Iquit(); private: QVBoxLayout* m_layout; QPushButton* m_buttonRandom; QPushButton* m_buttonQuit; QOpenCVWidget* QtIn; QOpenCVWidget* QtOut; CvCapture *camera; IplImage* in; IplImage* out; MyCVFilter* dude; protected: void timerEvent(QTimerEvent*); }; #endif
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 #include "QOpenCVWidget.h" // Constructor QOpenCVWidget::QOpenCVWidget(QWidget *parent) : QWidget(parent) { layout = new QVBoxLayout; imagelabel = new QLabel; QImage dummy(100,100,QImage::Format_RGB32); image = dummy; layout->addWidget(imagelabel); for (int x = 0; x < 100; x ++) { for (int y =0; y < 100; y++) { image.setPixel(x,y,qRgb(x, y, y)); } } imagelabel->setPixmap(QPixmap::fromImage(image)); setLayout(layout); } QOpenCVWidget::~QOpenCVWidget(void) { } void QOpenCVWidget::putImage(IplImage *cvimage) { int cvIndex, cvLineStart; // switch between bit depths switch (cvimage->depth) { case IPL_DEPTH_8U: switch (cvimage->nChannels) { case 3: if ( (cvimage->width != image.width()) || (cvimage->height != image.height()) ) { QImage temp(cvimage->width, cvimage->height, QImage::Format_RGB32); image = temp; } cvIndex = 0; cvLineStart = 0; for (int y = 0; y < cvimage->height; y++) { unsigned char red,green,blue; cvIndex = cvLineStart; for (int x = 0; x < cvimage->width; x++) { // DO it red = cvimage->imageData[cvIndex+2]; green = cvimage->imageData[cvIndex+1]; blue = cvimage->imageData[cvIndex+0]; image.setPixel(x,y,qRgb(red, green, blue)); cvIndex += 3; } cvLineStart += cvimage->widthStep; } break; default: printf("This number of channels is not supported\n"); break; } break; default: printf("This type of IplImage is not implemented in QOpenCVWidget\n"); break; } imagelabel->setPixmap(QPixmap::fromImage(image)); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #ifndef QOPENCVWIDGET_H #define QOPENCVWIDGET_H #include <C:\OpenCV2.1\include\opencv\cv.h> #include <C:\OpenCV2.1\include\opencv\highgui.h> #include <QPixmap> #include <QLabel> #include <QWidget> #include <QVBoxLayout> #include <QImage> class QOpenCVWidget : public QWidget { private: QLabel *imagelabel; QVBoxLayout *layout; QImage image; public: QOpenCVWidget(QWidget *parent = 0); ~QOpenCVWidget(void); void putImage(IplImage *); }; #endifDonc je recapitule pour que vous y voyiez plus clair, meme si le projet est simple et ne necessite pas que je vous fasse de l'UML:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <C:\OpenCV2.1\include\opencv\cv.h> #include <C:\OpenCV2.1\include\opencv\highgui.h> #include <stdio.h> #include <assert.h> #include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QPushButton> #include "Window.h" #include "QOpenCVWidget.h" int main(int argc, char **argv) { CvCapture* camera = cvCreateCameraCapture(0); assert(camera); IplImage* image=cvQueryFrame(camera); assert(image); QApplication app(argc,argv); Window window(camera,image); window.show(); int retval = app.exec(); cvReleaseCapture(&camera); return retval; }
MyCVFilter s'occupe excusivement du traitement d'image.
Window s'occupe du GUI (layout, boutons...) et execute le filtre de vision
QOpenCVWidget fait la conversion IplImage -> QImage.
Tel qu'il est poste le code fonctionne, mais des que je veux faire un Canny (ou un Hough... bref, toute fonction un peu elaboree), ca crash....
Je travail sous Windows 7 64, Visual Studio 2008.
Merci d'avance pour votre aide!!!
Je precise que le code n'est pas entierement de moi, par exemple l'algo de conversion d'image a ete glanne sur le web!
Stef
PS:desole pour le manque d'accent, j'ai fait un up de Windows a matin, et depuis impossible de switcher les languages...![]()
Partager