Bonsoir,
j'essaie d'intégrer des méthodes de la librairie opencv dans qt4 afin de faire via une gui, du traitement d'images sur le flux vidéo de ma webcam. Mon problème actuel se situe par rapport à l'affichage en niveau de gris du flux vidéo initialement en couleur.
Le code en C suivant marche très bien. La transformation du flux en niveau de gris se fait grâce à la méthode cvCvtColor(img2,img3,CV_BGR2GRAY); où img2 est l'image en couleur et im3 celle en niveau de gris. Voici le code :
Maintenant, voici le code c++ qui est censé faire la même chose que ci-dessus mais en passant par les QImages.Code:
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 #include <stdlib.h> #include <stdio.h> #include <math.h> #include <cv.h> #include <highgui.h> int main(int argc, char *argv[]) { IplImage *img = 0, *img2 = 0, *img3 = 0; int height,width,step,channels; uchar *data; int i,j,k; CvScalar scalaire, scalaire2, scalaire3; cvNamedWindow("Fenetre_test", CV_WINDOW_AUTOSIZE); cvMoveWindow("Fenetre_test", 100, 100); // Initialise la capture CvCapture* capture = cvCaptureFromCAM(0); while(cvWaitKey(20)!='q') { img2 = cvQueryFrame(capture); img3 = cvCreateImage(cvGetSize(img2), 8, 1); cvCvtColor(img2,img3,CV_BGR2GRAY); cvShowImage("Fenetre_test", img3 ); } // release the image cvReleaseImage(&img2 ); cvReleaseImage(&img3 ); cvReleaseCapture(&capture); return 0; }
Tout d'abord le constructeur :
et la méthode queryFrame() :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 IplImageWidget::IplImageWidget() { capture = cvCaptureFromCAM(0); im1 = cvQueryFrame( capture ); m_i = QImage(QSize(im1->width,im1->height),QImage::Format_RGB32); this->setMinimumSize(im1->width,im1->height); this->setMaximumSize(im1->width,im1->height); m_timer = new QTimer(this); connect(m_timer,SIGNAL(timeout()),this,SLOT(queryFrame())); m_timer->start(50); }
avecCode:
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 void IplImageWidget::queryFrame() { IplImage* frame = cvQueryFrame( capture ); im2 = cvCreateImage(cvGetSize(frame),8,1); cvCvtColor(frame,im2,CV_BGR2GRAY); // conversion de IplImage en Qimage const int pixels = im2->width * im2->height; uchar *imageData = new unsigned char[4*pixels]; for(int i = 0; i < pixels;i++) { imageData[i*4+3] = 0xFF; } uchar* src = (uchar*)(im2->imageData); uchar* srcEnd = src + (3*pixels); uchar* dest = imageData; do { memcpy(dest, src, 3); dest += 4; src += 3; } while(src < srcEnd); QImage m_i_new(imageData,im2->width,im2->height, QImage::Format_RGB32); m_i=m_i_new.copy(); this->repaint(); }
Tout compile bien mais à l'exécution, j'obtiens un résultat étrange qui est visible en pièce jointe (cf "es.jpg"). On voit qu'il y a 3 fenetres du flux plus une autre partie étrange. Comme vous l'avez vu dans le code c++, je convertis par l'intermédiaire de memcpy une IplImage en QImage. Le problème est qu'une IplImage est codée sur 3 octets et une QImage sur 4, je fixe donc le quatrième octet à une valeur fixe pour tous les pixels :Code:
1
2
3
4
5
6
7
8 void IplImageWidget::paintEvent(QPaintEvent*) { QPainter painter(this); painter.drawImage(QRect(0,0,im1->width,im1->height),m_i); }
Ensuite j'invoqueCode:
1
2
3 (uchar *imageData = new unsigned char[4*pixels]; for(int i = 0; i < pixels;i++) { imageData[i*4+3] = 0xFF; }
pour obtenir ma QImage que l'essaie d'afficher par :Code:
1
2
3 QImage m_i_new(imageData,im2->width,im2->height, QImage::Format_RGB32); m_i=m_i_new.copy();
Mais voilà visiblement, il y a un probleme de taille du flux affiché comme on le voit sur l'image en pièce jointe. je peux obtenir une taille correcte en multipliant par 3 "im2->width" et "im2->height" mais c'est du bricolage et puis même, la résolution n'est pas bonne. D'ou vient ce facteur 3 ?Code:
1
2
3 QPainter painter(this); painter.drawImage(QRect(0,0,im1->width,im1->height),m_i);
Vous auriez une piste ?
Merci par avance.