Salut,
Je suis débutant et j'ai un problème d' "Exception non gérée à 0x00735ad8 dans Interface.exe*: 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000264". Malheureusement, je n'arrive pas à voir d'où cela provient... Mon débogueur m'affiche l'erreur à la ligne 43 du fichier Webcam.cpp
Le problème survient lorsque j'appuie sur mon bouton vidéo qui est censé m'ouvrir le flux de ma webcam (grâce à OpenCV) dans une fenêtre Qt. J'ai bien la fenêtre Qt qui s'ouvre et j'ai le voyant lumineux de ma webcam qui s'allume, mais après ça plante et m'affiche le message d'erreur.
Voici mes fichiers:
main.cpp
MyWidget.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include "MyWidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MyWidget widget; widget.show(); return app.exec(); }
MyWidget.cpp: ma fenêtre principale qui contient mes différents boutons dont vidéo.
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 #ifndef MYWIDGET_H #define MYWIDGET_H #include <QApplication> #include <QFont> #include <QPushButton> #include <QWidget> #include <QDesktopWidget> #include <QPainter> #include <opencv/cv.h> #include <opencv/highgui.h> #include <stdio.h> #include <assert.h> #include <QVBoxLayout> #include "NewFenetre.h" #include "Webcam.h" class MyWidget : public QWidget { Q_OBJECT public: MyWidget(QWidget *parent = 0); public slots: void Afficherwebcam(); }; #endif
NewFenetre.h
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 #include "MyWidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { // Taille fenêtre menu setFixedSize(600, 200); //Couleur fenêtre setStyleSheet("background-color: rgb(40,40,40)"); //Enlève les bordures setWindowFlags(Qt::FramelessWindowHint); QDesktopWidget bureau; // Le bureau QRect dimensionBeureau = bureau.screenGeometry(); // Les dimensions du bureau // La fenêtre est mise en haut à gauche. this->move(dimensionBeureau.topLeft().x(),dimensionBeureau.topLeft().y()); //Paramètres bouton quitter QPushButton *quit = new QPushButton(tr("Quitter"), this); quit->setGeometry(420, 120, 100, 35); quit->setFont(QFont("Times", 18, QFont::Bold)); quit->setStyleSheet("color : rgb(255,255,255); background-color: rgb(60,60,60)"); connect(quit, SIGNAL(clicked()), qApp, SLOT(quit())); //Paramètres bouton annuler QPushButton *cancel = new QPushButton(tr("Annuler"), this); cancel->setGeometry(420, 60, 100, 35); cancel->setFont(QFont("Times", 18, QFont::Bold)); cancel->setStyleSheet("color : rgb(255,255,255); background-color: rgb(60,60,60)"); //Paramètres bouton video QPushButton *vid = new QPushButton(tr("Vidéo"), this); vid->setGeometry(80, 70, 120, 60); vid->setFont(QFont("Times", 18, QFont::Bold)); vid->setStyleSheet("color : rgb(255,255,255); background-color: rgb(60,60,60)"); connect(vid, SIGNAL(clicked()), this, SLOT(Afficherwebcam())); //Paramètres bouton cerveau QPushButton *cer = new QPushButton(tr("Cerveau"), this); cer->setGeometry(240, 70, 120, 60); cer->setFont(QFont("Times", 18, QFont::Bold)); cer->setStyleSheet("color : rgb(255,255,255); background-color: rgb(60,60,60)"); //connect(quit, SIGNAL(clicked()), qApp, SLOT(quit())); } void MyWidget::Afficherwebcam() { NewFenetre *fenetre = new NewFenetre(); //fenetre->show(); }
NewFenetre.cpp
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 #ifndef NEWFENETRE_H #define NEWFENETRE_H #include <opencv/cv.h> #include <opencv/highgui.h> #include <stdio.h> #include <assert.h> #include <QApplication> #include <QWidget> #include <QVBoxLayout> #include "QtoCv.h" #include "Webcam.h" class NewFenetre : public QWidget { Q_OBJECT public: NewFenetre(QWidget *parent = 0); }; #endif
Webcam.h
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 #include "NewFenetre.h" // Constructor NewFenetre ::NewFenetre (QWidget *parent) : QWidget(parent) { //On creer les objets provenant des classes fournies //par openCV permettant de capturer le flux de la camera CvCapture * camera = cvCreateCameraCapture(0); assert(camera); IplImage * image=cvQueryFrame(camera); assert(image); // On passe l'objet camera à notre class MyCameraWindow Webcam *win = new Webcam(camera); win->show(); // les objets provenant de la bibliothèque openCV ne profitent pas du // garbage collector de Qt cvReleaseCapture(&camera); }
Webcam.cpp
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 #ifndef WEBCAM_H #define WEBCAM_H #include <QWidget> #include <QPushButton> #include <QVBoxLayout> // On reconnait ici notre Widget personnalisé #include "QtoCV.h" #include <opencv/cv.h> #include <opencv/highgui.h> #include "stdio.h" #include <iostream> #include <cstdio> #include <QDebug> using namespace std; using namespace cv; class Webcam : public QWidget { Q_OBJECT private: CvCapture *camera; bool m_standalone; QtoCV *m_cvwidget;// Cet objet permet de traiter le flux de la camera public: // Le constructeur reçoit l'objet cam pour gerer le flux video Webcam(CvCapture *cam, QWidget *parent=0); protected: // c'est dans cette methode qu'on affichera l'image provenant de l'objet camera void timerEvent(QTimerEvent*); }; #endif
QtoCV.h
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 #include "Webcam.h" Webcam::Webcam(CvCapture *cam, QWidget *parent) : QWidget(parent) { if(cam) { camera=cam; m_standalone=false; } else { camera=cvCreateCameraCapture(CV_CAP_ANY); cvSetCaptureProperty(camera ,CV_CAP_PROP_FRAME_WIDTH, 1280); cvSetCaptureProperty(camera ,CV_CAP_PROP_FRAME_HEIGHT, 720); cvSetCaptureProperty(camera ,CV_CAP_PROP_FPS, 10); m_standalone=true; } if(!camera) { qDebug() << "Error: can't find camera"; } QVBoxLayout *layout = new QVBoxLayout; m_cvwidget = new QtoCV(this); layout->addWidget(m_cvwidget); setLayout(layout); resize(800, 600); startTimer(25); } void Webcam::timerEvent(QTimerEvent*) { m_cvwidget->putImage(cvQueryFrame(camera)); }
QtoCV.cpp
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 #ifndef QTOCV_H #define QTOCV_H // Penser à inclure les headers d'openCV #include <opencv/cv.h> #include <QPixmap> #include <QLabel> #include <QWidget> #include <QVBoxLayout> #include <QImage> #include "stdio.h" class QtoCV : public QWidget { private: // Le label permet l'affichage d'image le plus rapide dans Qt // c'est dans ce label que vont apparaitre les images de la camera QLabel *imagelabel; // De objets pour la mise en page QVBoxLayout *layout; QHBoxLayout *hLayout; // Image reçue de la camera QImage image; public: QtoCV(QWidget *parent = 0); ~QtoCV(void); // Convertir IplImage en QImage QImage IplImage2QImage(const IplImage *iplImage); // Convertir QImage en IplImage IplImage* qImage2IplImage(const QImage& qImage); // Cette fonction permettra de donner l'image à afficher par le label void putImage(IplImage *); }; #endif
Merci par avance pour votre aide.
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
81
82 #include "QtoCV.h" // Constructor QtoCV::QtoCV(QWidget *parent) : QWidget(parent) { layout = new QVBoxLayout; imagelabel = new QLabel; hLayout = new QHBoxLayout; // initialisation du label avec une image créée de toute pièce 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)); hLayout->addLayout(layout); setLayout(hLayout); } QtoCV::~QtoCV(void) { } void QtoCV::putImage(IplImage *cvimage) { QImage tmpImage; // On transforme l'image passée en parametre // en QImage tmpImage = this->IplImage2QImage(cvimage); // pour l'afficher dans notre label imagelabel->setPixmap(QPixmap::fromImage(tmpImage)); } // Convertir IplImage en QImage QImage QtoCV::IplImage2QImage(const IplImage *iplImage) { int height = iplImage->height; int width = iplImage->width; if(iplImage->depth == IPL_DEPTH_8U && iplImage->nChannels == 3) { const uchar *qImageBuffer = (const uchar*)iplImage->imageData; QImage img(qImageBuffer, width, height, QImage::Format_RGB888); return img.rgbSwapped(); } else{ return QImage(); } } // Convertir QImage en IplImage IplImage* QtoCV::qImage2IplImage(const QImage& qImage) { int width = qImage.width(); int height = qImage.height(); // Creates a iplImage with 3 channels IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); char * imgBuffer = img->imageData; //Remove alpha channel int jump = (qImage.hasAlphaChannel()) ? 4 : 3; for (int y=0;y<img->height;y++){ QByteArray a((const char*)qImage.scanLine(y), qImage.bytesPerLine()); for (int i=0; i<a.size(); i+=jump){ //Swap from RGB to BGR imgBuffer[2] = a[i]; imgBuffer[1] = a[i+1]; imgBuffer[0] = a[i+2]; imgBuffer+=3; } } return img; }
Partager