J'ai réalisé une GUI sur Debian 6.0 permettant de faire du traitement d'images (Canny Edge) sur des images et un flux vidéo via OpenCV.
En ce qui concerne les images, tout marche bien mais pour la vidéo, à l'exécution la vidéo est distordue. Le plus génant est que ce bug n'est pas reproductible à chaque exécution, c'est aléatoire.
Voici un exemple de vidéo distordue :
Le problème ne vient pas de la webcam puisqu'un petit code purement en OpenCV affiche une bonne vidéo.
J'utilise dans le code une classe principale ImageViewer dérivée de QMainWindow.
Le boutton "start webcam" est relié au slot "start_webcam" via :
La fonction "start_webcam" est la suivante où j'utilise un QTimer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 startwebcamAct = new QAction(tr("&Start Webcam"), this); connect(startwebcamAct, SIGNAL(triggered()), this, SLOT(start_webcam()));
avec la fonction query_frame() ou j'utilise la fonction repaint() :
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 void ImageViewer::start_webcam() { webcam_on = 1; invertWebcam = 0; close_current(); updateStatusWebcam(webcam_on); // Init capture capture = cvCaptureFromCAM(0); first_image = cvQueryFrame(capture); // Init current qimage current_qimage = QImage(QSize(first_image->width,first_image->height),QImage::Format_RGB32); resize(first_image->width,first_image->height); // start QTimer timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(query_frame())); timer->start(0); }
La fonction repaint() appelle instantanément (du moins je pense) la fonction paintEvent :
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 void ImageViewer::query_frame() { webcam_off = 0; IplImage* frame = cvQueryFrame(capture); int w = frame->width; int h = frame->height; if (matrixMode) { current_image = cvCreateImage(cvGetSize(frame),8,3); cvCvtColor(frame,current_image,CV_BGR2RGB); int cvIndex = 0; int cvLineStart = 0; unsigned char red,green,blue; for(int j = 0; j < h; j++) { cvIndex = cvLineStart; for(int i = 0; i < w; i++) { red = 0; green = current_image->imageData[cvIndex+1]; blue = 0; current_qimage.setPixel(i,j,qRgb(red, green, blue)); cvIndex += 3; } cvLineStart += current_image->widthStep; } } gaussianfilter(webcam_off); border_detect(webcam_off); if (invertWebcam) invertvalues(webcam_off); cvReleaseImage(¤t_image); repaint(); }
A l'exécution, le fait que si je maximise la fenêtre de l'interface, la vidéo s'affiche correctement, me fait penser à un conflit de synchronisation entre la méthode paintEvent et la méthode repaint() que j'utilise dans la méthode query_frame ci-dessus.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 void ImageViewer::paintEvent(QPaintEvent*) { QPainter painter(this); painter.drawImage(QRect(0,0,current_qimage.width(),current_qimage.height()),current_qimage); }
Voici un exemple de ce cas là où la vidéo s'affiche correctement :
Quelqu'un pourrait-il me confirmer si le problème vient de ce conflit ?
et surtout que puis-je essayer pour le résoudre
Merci par avance
Partager