IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

affichage de beaucoup d'images


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut affichage de beaucoup d'images
    Bonjour,

    je suis en train de dévellopez une interface graphique pour contrôler des caméras (2 en ce moment) et une des principales fonctions du programme consiste à afficher les images envoyées par les caméras. Sur mon interface graphique j'ai donc 3 zones d'affichages (ie trois QLabel) : une pour chaque caméra et une commune aux deux (chaque caméra ne filme qu'une couleur).
    Les images sont acquises dans deux threads secondaires (un thread par caméra) et sont ensuite émises vers leur affichage respectif.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //connection vers la zone d'affichage comune
    connect(cameraS[i], SIGNAL(hotImageC(QImage,int)), mergeScreen, SLOT(newImage(QImage,int)), Qt::UniqueConnection);
    //connection vers la zone d'affichage spécifique
    connect (myCamera, SIGNAL(hotImage(const QPixmap &)), this, SLOT(newImage(const QPixmap &)), Qt::UniqueConnection);
    j'ai utilisé Qt::UniqueConnection pour éviter l'engorgement de l'event loop.
    mais même malgré cela quand les deux caméras filment en même temps l'affichage finit (entre 1s et 30 sec de fluidité) et la mémoire utilisée par le programme monte en flèche.....

    Il faut savoir que chaque images a une résolution de 496*658 sen 16 bit. et que le frame rate est d'environ 17 à 24 fps.

    merci d'avance pour votre aide

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut.
    Il n'y as pas assez de code pour t'aider.
    Sinon, QLabel n'est absolument pas adpater à ton besion. Il faut mieux faire ton propre paint event.
    Sinon, Y as normalement une solution avec QtMultimedia, mais je ne connait pas
    http://qt.developpez.com/doc/latest/qtmultimedia/

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2004
    Messages : 33
    Par défaut
    Hello,


    Personellement j'ai pu tester 4 cameras à 30fps sans soucis particuliers. Les threads d'acquisitions emettant des signiaux via Qt::QueuedConnection à des Qlabel pour le display.

    Au niveau mémoire, cela fait plutôt penser à un leak dans ton code. Est-ce que la mémoire allouée dans thread d'acquisition pour récupérer les images est bin désallouée?

    ++

    Frantz

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    merci pour vos réponses.

    voila le code de la thread d'acquisition :
    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
    void camera::run()
    {
        QPixmap imPix(resX, resY);
        QImage image(resX, resY, QImage::Format_RGB16);
        QImage imageC(resX, resY, QImage::Format_ARGB32_Premultiplied);
        status = 20072;
        long first, last, pMin, pMax;
     
            while (status == 20072)
            {
     
                erreur = WaitForAcquisitionByHandle(handle);
                mutex->lock();
                SetCurrentCamera(handle);
     
    //récupération des données de l'image : imdata[resX*reY] 
     
                erreur = GetMostRecentImage16(imData, resX*resY);
                mutex->unlock();
     
                if (erreur == 20002)
                {
                    if (nbIm%50 == 0 || nbIm == 1)
                    {
                        normHisto (imData, resX, resY, &pMin, &pMax);
                    }
                    for (int j = 0 ; j<resY ; ++j )
                    {
                        for (int i = 0; i<resX ; ++i)
                        {
                            value = imData[j*resX+i];
                            value = 255*(value-pMin);
                            value = value/(pMax-pMin);
    //image noir et blanc
                            image.setPixel(i, j, qRgb(value, value, value));
    //selon la camera (identity) l'image est soit rouge soit bleu
                            if (identity == 0)
                            {
                                imageC.setPixel(i, j, qRgb(value, 0, 0));
                            }
                            else
                            {
                                imageC.setPixel(i, j, qRgb(0, value, 0));
                            }
                        }
                    }
                    imPix = QPixmap::fromImage(image);
                    emit hotImage (imPix);
                    if (mergeOn == true)
                    {
    //émission de l'image de couleur
                        emit hotImageC (imageC, identity);
                    }
                }
                mutex->lock();
                SetCurrentCamera(handle);
                GetStatus(&status);
                mutex->unlock();
            }
        }
    }
    la définition des signaux émis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	void hotImage (const QPixmap &im);
            void hotImageC (const QImage &im, int identity);
    les deux affichages respectifs des deux caméras sont trés simple : l'image émises pas le thread est transmises à un slot qui l'affiche dans un Qlabel

    pour la zone commune voici le slot auquel est connecté le signal hotImageC
    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
     
    void mergeWindow::newImage(QImage im, int color)
    {
    //les Qimages redImage greenImage et merge sont instanciées dans le //constructeur
        switch (color)
        {
        case 0 :
            redImage->fill (Qt::transparent);
            *redImage = im;
     
            break;
        case 1 :
            greenImage->fill (Qt::transparent);
            *greenImage = im;
     
            break;
        }
        mergeImage->fill(Qt::transparent);
        painter->begin(mergeImage);
            painter->setCompositionMode(QPainter::CompositionMode_DestinationOver);
        painter->drawImage(0, 0, *greenImage);
        painter->setCompositionMode(QPainter::CompositionMode_Plus);
        painter->drawImage(0, 0, *redImage);
     
        painter->end();
     
        screen->setPixmap(QPixmap::fromImage(*mergeImage));
     
    }
    @trop_wizz : j'ai aussi pensé à une fuite de mémoire mais si je supprime l'écran commun, je n'ai aucun problème. Et plus bizzarement si dans mergeWindow::newImage() je supprime juste l'affichage, ie les variables sont toujours transmises, les images mélangées etc l'augmentation de mémoire n'apparait qu'après un temps long d'acquisition : environ une minute.

    @yan merci pour le QtMultimedia je vais regarder ça.

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Qpixmap ne peut pas être utilisé dans un thread car il est basé sur les ressource de la GDI comme les widgets.
    Au lieu de faire des lock et unlock, regarde QMutexLocker
    et
    http://qt.developpez.com/faq/?page=T...pulation-mutex

    Sinon je n'ai rien vue qui pourrai provoquer une fuite mémoire.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    quand les images ne sont émises que vers l'écran commun, et sans être mélangées, l'affichage reste (relativement) fluide et la mémoire est stable. même topo quand les images sont envoyées sur leur écran respectif et pas sur le commun. je dois surcharger quelque chose.... mais je ne sais pas quoi.

    Par contre le mutex que j'utilise dans les threads d'acquisition est commun au deux caméras afin que les intructions ne soient pas mélangées (un boucle d'acquisition doit pouvoir bloquer momentanément l'autre). Seuleument pour qu'il soit partagé, le mutex est instancié dans la thread principale (seul un pointeur est passé thread secondaire). Ainsi quand je le lock (avec QMutexLocker merci yan ) je dois interrompre aussi l'exécution du main thread, je me trompe? Du coup la thread principale serait interompu trop souvent et ne pourrait plus suivre..... c'est crédible selon vous?
    Bonne soirée!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB6] Affichage centré d'une image
    Par Sophie2097 dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 12/05/2006, 14h28
  2. Erreur pour l'affichage aléatoire d'une image
    Par bellebiquette dans le forum Langage
    Réponses: 3
    Dernier message: 21/04/2006, 22h45
  3. [Conception] affichage aleatoire d'une image
    Par bellebiquette dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 24/02/2006, 22h58
  4. [WD5.5] Mode d'affichage d'un champs Image
    Par Herve_63 dans le forum WinDev
    Réponses: 2
    Dernier message: 17/02/2006, 14h06
  5. [Tableaux] Ajouter l'affichage dynamique d'une image
    Par leloup84 dans le forum Langage
    Réponses: 3
    Dernier message: 16/02/2006, 09h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo