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
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.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
#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
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
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.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
#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
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
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.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
#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
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
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.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
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
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
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;
}
Merci par avance pour votre aide.