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

OpenGL Discussion :

Chargement de textures issues d'une video


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2011
    Messages : 14
    Par défaut Chargement de textures issues d'une video
    Bonjour à tous !
    Je cherche à texturer ma scène 3d avec des images issues d'une vidéo.
    Ma scène représente cette même vidéo. En effet, pour chaque image de la vidéo, j'ai un nuage de points correspondant que je place correctement dans l'espace et que je maille par la suite. J'ai donc un tableau de triangle pour chaque image, et je veux plaquer mes textures sur chacun de ces triangles.

    voici un résumé mon code. Si vous avez des problème de compréhension, n'hésitez pas à m'écrire.

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    //p3d est une structure contenant toutes les données (points , triangles, pixels)
     
     
    /*dans main.c*/
     
    //variable globale
    p3d 3d;
    GLuint * tabTexture;
    CvCapture *input_video;
     
    //fonction de rendu
    void display(void) 
    {
    	...
     
    	//j'affiche une séquence
    	afficheSeq3D(3d,tabTexture,numseq);
     
    	glutSwapBuffers();
     
    	glFlush ();
    	glutPostRedisplay();
    }
     
     
     
    int main (int argc, char** argv) 
    {
    	...
    	glEnable(GL_DEPTH_TEST);
            glEnable(GL_TEXTURE_2D);
     
    	input_video=cvCaptureFromFile("video.avi");
     
    	tabTexture=(GLuint *) malloc(sizeof(GLuint)*nbImage);
    	loadAllTextures(input_video,tabTexture, nbImage);
    	...
     
    	return (0);
    }
     
     
    /*dans texture.c*/
     
    //variable globale
    GLuint idTexture = 0;
     
    void loadAllTextures(CvCapture *input_video, GLuint * tabTexture, int nbImage)
    {
    	int i;
    	IplImage *frame = NULL;
    	glGenTextures(nbImage, tabTexture);
    	for(i=0;i<nbImage;i++)
    	{
    		cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES, i);
    		frame = cvQueryFrame(input_video);
    		tabTexture[i]=loadTexture(frame);
    	}
    }
     
     
     
    GLuint loadTexture(IplImage * frame) 
    {
    	int i,j, p=0;
        GLubyte *tabTexturePixels;
    	CvScalar rgb;
    	idTexture++;
     
        tabTexturePixels = (GLubyte *) malloc(sizeof(GLubyte)*frame->width * frame->height * 3);
     
        for (i=0; i < frame->width; i++)
        {                     
    		for (j=0; j < frame->height; j++)
    		{ 
    			rgb = cvGet2D(frame, j, i);
                tabTexturePixels[p+0] = (GLubyte)rgb.val[2];
                tabTexturePixels[p+1] = (GLubyte)rgb.val[1];
                tabTexturePixels[p+2] = (GLubyte)rgb.val[0];
                p += 3;
    		}
        }
     
        glBindTexture(GL_TEXTURE_2D, idTexture);
     
     
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
        glTexImage2D(GL_TEXTURE_2D, 0, 3, frame->width, frame->height, 0, GL_RGB, GL_UNSIGNED_BYTE, tabTexturePixels);
     
        free(tabTexturePixels);
     
        return idTexture;
    }
     
     
     
    /*dans affiche.c*/
     
     
     
    void afficheSeq3D( p3d 3d, GLuint * tabTexture,int numSeq)
    {
    	int i;
    	for(i=3d->debutSequence[numSeq];i<=3d->finSequence[numSeq];i++)
    	{
    		//j'affiche toutes les images de la séquence
    		afficheImage(3d,i,tabTexture);
    	}
    }
     
     
    void afficheImage(p3D 3d,int img, GLuint * tabTexture)
    {
    	int i;
    	triangle *courant;
    	glBindTexture(GL_TEXTURE_2D,tabTexture[img]);
     
    	glBegin(GL_TRIANGLES);
    	courant=3d->triangle_list[img]->debut;
    	//pour chaque triangle de l'image img
    	for (i=0;i<3d->triangle_list[img]->taille;i++)
    	{
    		//glTexCoord2f(x du pixel correspondant au point 1 du triangle courant, et le y );
    		glTexCoord2f(3d->pixels[img][courant->p1*2],3d->pixels[img][courant->p1*2+1]);
    		//glVertex3f(x du point 1, y, z);
    		glVertex3f(3d->points[img][courant->p1*3],3d->points[img][courant->p1*3+1],3d->points[img][courant->p1*3+2]);
    		//de meme point 2
    		glTexCoord2f(3d->pixels[img][courant->p2*2],3d->pixels[img][courant->p2*2+1]);
    		glVertex3f(3d->points[img][courant->p2*3],3d->points[img][courant->p2*3+1],3d->points[img][courant->p2*3+2]);
    		//de meme point 3
    		glTexCoord2f(3d->pixels[img][courant->p3*2],3d->pixels[img][courant->p3*2+1]);
    		glVertex3f(3d->points[img][courant->p3*3],3d->points[img][courant->p3*3+1],3d->points[img][courant->p3*3+2]);
    		courant=courant->suiv;
    	}   
    	glEnd();
     
     
    	//cette fonction s'occupe du déplacement dans l'espace
    	transformation(3d,img);
    }
    Mon problème : Mon programme compile bien mais je n'obtiens pas le résultat escompté. En effet, j'obtiens une scène où tous mes triangles sont blancs. J'ai essayé de modifier plusieurs fois ma fonction de chargement de texture mais sans succès. Je ne sais plus quoi tenter donc je demande votre aide. Merci
    Fichiers attachés Fichiers attachés
    • Type de fichier : c dev.c (3,4 Ko, 60 affichages)

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Moi il y a un truc qui me chagrine, c'est que tu charges en RAM puis en mémoire GPU toutes les images de ta vidéo, ce qui n'est pas viable si ta vidéo est un tant soit peu grosse.
    Je te conseille de créer une texture qui contiendra la frame courante, puis de charger les frames au fur et à mesure que tu lis ta vidéo, tu fais un glTexSubImage2D pour mettre à jour la texture.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2011
    Messages : 14
    Par défaut
    Je suis d'accord pour dire que ma solution est loin d'être la plus efficace. Mais penses tu que ta solution résoudra mon problème? (c'est à dire l'affichage de triangles blancs en lieu et place des textures)
    Quoi qu'il en soit je vais essayer ta solution. Merci

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Je ne sais pas si ça résoudra ton problème, mais au moins ça réduira les risques de problèmes.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Je n'ai pas regardé ton code en détail car de toute façon je crois qu'on ne peut par faire gand chose sans savoir ce que font les fonctions cv_ mais ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    glutSwapBuffers();
    glFlush ();
    glutPostRedisplay();
    je pense que tu fais 3 fois la même chose car glutSwapBuffers() doit faire un appel à glFlush() et glutPostRedisplay() doit swapper les buffers. En revanche, cela ne devrait pas jouer sur les textures.

    Pour les textures essaie peut-être de n'en créer et charger qu'une seule pour tester, essaie également depuis un fichier image pour bien vérifier que ça marche. Si tu as une veille carte graphique tu es peut-être confronté au fameux problème des dimensions des textures en non puissance de deux qui ne sont pas pris en charge, quoique en général la résolution d'une vidéo est en puissance de deux. Essaie aussi d'afficher les valeurs de tabTexturePixels pour vérifier qu'elle sont comprises entre 0 et 255.
    Good luck

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2011
    Messages : 14
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Moi il y a un truc qui me chagrine, c'est que tu charges en RAM puis en mémoire GPU toutes les images de ta vidéo, ce qui n'est pas viable si ta vidéo est un tant soit peu grosse.
    Je te conseille de créer une texture qui contiendra la frame courante, puis de charger les frames au fur et à mesure que tu lis ta vidéo, tu fais un glTexSubImage2D pour mettre à jour la texture.

    J'ai remplacé ma fonction "loadTexture" par celle ci-dessous. En effet, cette méthode est beaucoup plus rapide mais j'obtiens toujours le même résultat. Si j'utilise mal glTexSubImage2D merci de me le dire.


    GLuint loadTexture(IplImage * frame)
    {
    idTexture++;
    glBindTexture(GL_TEXTURE_2D, idTexture);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,frame->width,frame->height,GL_RGB,GL_UNSIGNED_BYTE,frame->imageData);

    return idTexture;
    }

  7. #7
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    euh ... j'ai un problème avec ceci : idTexture++;. Comment as-tu créé tes id de texture ?
    Normalement tu devrais avoir un truc du genre :
    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 InitGL()
    {
       glGenTextures( 1, & idTexture);
    }
     
    void CleanupGL()
    {
       glDeleteTextures( 1, & idTexture);
    }
     
    void LoadTexture( IplImage * frame) 
    {
       glBindTexture(GL_TEXTURE_2D, idTexture);
       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
       glTexSubImage2D(GL_TEXTURE_2D,0,0,0,frame->width,frame->height,GL_RGB,GL_UNSIGNED_BYTE,frame->imageData);
    }
     
    void EnableTexture()
    {
       glActiveTexture( GL_TEXTURE0);
       glBindTexture( GL_TEXTURE_2D, idTexture);
       glEnable( GL_TEXTURE_2D)
    }
     
    void DisableTexture()
    {
       glActiveTexture( GL_TEXTURE0);
       glDisable( GL_TEXTURE_2D);
    }
     
    void DrawGL()
    {
       LoadTexture( <la frame de ta vidéo>);
       EnableTexture();
       // Dessin des éléments utilisant cette texture.
       DisableTexture();
    }
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2011
    Messages : 14
    Par défaut
    Citation Envoyé par Djakisback Voir le message
    Je n'ai pas regardé ton code en détail car de toute façon je crois qu'on ne peut par faire gand chose sans savoir ce que font les fonctions cv_
    Les fonctions cv_ sont issues de la bibliothèque OpenCV. Je les explique rapidement :
    input_video=cvCaptureFromFile("video.avi");
    - La fonction cvCaptureFromFile alloue et initialise la structure CvCapture pour lire la vidéo dont le nom est spécifié.

    cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES, i);
    - La fonction cvSetCaptureProperty permet de se placer au niveau de l'image i.
    frame = cvQueryFrame(input_video);
    - Enfin cette fonction permet de récupérer l'image courante.


    Citation Envoyé par Djakisback Voir le message
    Essaie aussi d'afficher les valeurs de tabTexturePixels pour vérifier qu'elle sont comprises entre 0 et 255.
    Good luck
    J'ai bien des valeurs comprises entre 0 et 255


    Citation Envoyé par Djakisback Voir le message
    Si tu as une veille carte graphique tu es peut-être confronté au fameux problème des dimensions des textures en non puissance de deux qui ne sont pas pris en charge, quoique en général la résolution d'une vidéo est en puissance de deux.
    La résolution de mes images n'est pas en puissance de deux. Elles font 2448x2050. Mais ma carte graphique est assez récente (ATI Mobility Radeon HD 5650) donc je ne pense pas que ça vienne de là.



    Citation Envoyé par Djakisback Voir le message
    Pour les textures essaie peut-être de n'en créer et charger qu'une seule pour tester, essaie également depuis un fichier image pour bien vérifier que ça marche.
    J'ai créé une seule texture(la première image de ma vidéo) et j'essaye de la plaquer partout, ça ne marche pas. j'ai toujours le même résultat, tout en blanc.
    Ensuite, j'ai essayé avec une image bmp que je charge avec int LoadBitmap(char *filename) (une fonction trouvée sur internet qui avait déja fonctionné dans d'autres programmes) et même comme ça tout est blanc. Pourtant ma fonction d'affichage me semble correcte. Donc je ne vois pas trop d'où ça peut venir

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2011
    Messages : 14
    Par défaut
    à dragonjoker59 :
    Merci pour ton bout de code, mais je pense qu'il vaut mieux que je charge toutes les textures avant de commencer à afficher si je veux pouvoir me déplacer de manière fluide dans la scène. J'ai des séquences d'images assez longues (>500 images), donc tout recalculer pour chaque tour d’affichage me parait pas être la solution la plus efficace.

    Sinon j'ai quand même essayé ta proposition :
    j'appelle simplement afficheSeq3D dans ma fonction de rendu et j'utilise tes fonctions:


    void afficheSeq3D(p3D 3d, int numSeq, CvCapture * input_video)
    {
    int i;
    IplImage *frame;
    for(i=3d->debutSequence[numSeq];i<=3d->finSequence[numSeq];i++)
    {
    cvSetCaptureProperty(input_video, CV_CAP_PROP_POS_FRAMES, i);
    frame = cvQueryFrame(input_video);
    afficheImage_Maillage_Texture(3d,i,frame);
    }
    }



    void afficheImage_Maillage_Texture(p3D 3d, int img, IplImage *frame)
    {
    int i;
    triangle *courant;
    glEnable( GL_TEXTURE_2D);
    InitGL();
    LoadTexture(frame);
    EnableTexture();


    glBegin(GL_TRIANGLES);
    courant=3d->triangle_list[img]->debut;

    for (i=0;i<3d->triangle_list[img]->taille;i++)
    {
    //dessin
    glTexCoord2f(...);
    glVertex3f(...);
    ...
    courant=courant->suiv;
    }
    glEnd();
    DisableTexture();
    CleanupGL();
    }



    Je n'avais encore jamais utilisé "glActiveTexture(GL_TEXTURE0);" et c'est sur cette ligne que j'ai un Access Violation et j'ai trouvé que peu d'exemples d'utilisation de cette fonction. Si je ne m'en sers pas correctement merci de me le dire. Merci quand même pour tout.

  10. #10
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Ta vidéo a des frames en 2448x2050. Tu as combien de frames ? (en RGB tes frames font donc 12Mo pour 8Mo en YUY2, c'est énorme)
    Si tu as une Access Violation au moment de l'utilisation de glActiveTexture c'est peut-être parce que la fonction n'est pas chargée (j'utilise généralement GLEW pour ce travail fastidieux).
    Dans ta boucle d'affichage tu ne dois pas faire InitGL et CleanupGL. Ces 2 fonctions sont à appeler l'une au lancement de l'appli, l'autre à la sortie de l'appli.
    Evidemment, on charge généralement toutes les textures dont on a besoin pour une scène avant d'afficher celle-ci (tant qu'il n'y a pas trop de textures et qu'elles ne sont pas trop grosses). Cependant les textures issues de vidéos sont particulières et on ne charge généralement pas toute la vidéo. A la limite on précharge 5 ou 10 frames d'avance, mais c'est tout.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 14/07/2009, 00h59
  2. Chargement d'image pour créer une texture
    Par sir_gcc dans le forum OpenGL
    Réponses: 2
    Dernier message: 29/12/2008, 22h49
  3. [Video] Traitement d'images issues d'une video? [JMF ?]
    Par HerQuLe dans le forum Multimédia
    Réponses: 0
    Dernier message: 23/09/2008, 21h56
  4. Réponses: 2
    Dernier message: 06/08/2007, 16h28
  5. [HTML] chargement d'une video
    Par azahord dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 11/11/2006, 23h33

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