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

 C Discussion :

Creation d'images TIFF


Sujet :

C

  1. #1
    Membre confirmé Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut Creation d'images TIFF
    Bonjour,

    J'ai une nouvelle fois besoin de vos lumières avisées...

    J'ai un tableau 2D (600*600) contenant des températures en centièmes de Kelvin (donc des nombres à 5 chiffres) que je récupère castées en unsigned short int. Je souhaite enregistrer ce tableau sous forme d'une image tiff en niveau de gris, pour cela j'essaye de convertir mes données codées sur 16 bits en données codées sur 8 bits, puis j'utilise les fonctions TIFFOpen, TIFFWriteScanline et TIFFClose de la librairie tifflib.

    Le problème c'est que l'image que j'obtiens est toute noire... Il semblerait donc que je me sois trompé quand je veux passer des données codées sur 16 bits aux données codées sur 8 bits... Ou alors lors de l'utilisation de TIFFWriteScanline...

    et voici un bout de mon code :

    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
    /*NBLIG et NBCOL sont des constantes valant 600 et temperature est un tableau 2D casté en unsigned short int contenant mes températures*/
          unsigned char ** temp8bit = malloc (NBLIG *sizeof(unsigned char *));
          if (temp8bit == NULL)
             {
             free(temp8bit);
             printf("erreur lors de l'allocation memoire 4");
             }
          else
             {
             for (i=0;i<NBLIG;i++)
                {
                temp8bit[i]= malloc(NBCOL * sizeof(unsigned char));
                if (temp8bit[i] == NULL)
                   {
                   free(temp8bit[i]);
                   printf("erreur lors de l'allocation memoire 5");
                   }
                for (j=0; j<NBCOL; j++)
                   {
                   temp8bit[i][j]=temperature[i][j]*(255/65535);
                   }
                }
             TIFF* imgTIFF = TIFFOpen("toto.tif","w");
             if (imgTIFF == NULL)
                {
                printf("erreur à la creation du tiff");
                }
             else
                { 
                TIFFSetField(imgTIFF,TIFFTAG_IMAGEWIDTH,NBLIG);
                for (i=0; i<NBLIG; i++)
                   {
                   TIFFWriteScanline(imgTIFF,temp8bit[i],i,0);
                   }            
                TIFFClose(imgTIFF);  
                }
             free(temp8bit);   
             }

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    A mon avis, mets directement ceci comme conversion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp8bit[i][j]=(unsigned char)((temperature[i][j]>>8) & 0xFF) ;
    Le résultat de ta division, dont j'avoue ne pas comprendre réellement le but, est évalué à zéro => pixel à zéro => image noire.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 085
    Par défaut
    Pour completer la reponse de MacLak :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    temp8bit[i][j]=temperature[i][j]*(255/65535);
    Ceci est une division d'entier (egalement connu sous le nom de "division euclidienne"). Cela signifie "combien de fois on peut mettre 65535 dans 255 ?".

    Pour palier a ce probleme (car tu veux faire une division de reel et non d'entier), il faut faire en sorte qu'au moins une des deux valeurs mise en jeu ne soit pas de type "entier" (donc pas long, int short ...), mais de type "réel" (double, float ...).
    La mauvaise solution serait d'appliquer un cast. La bonne solution serait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    temp8bit[i][j]=temperature[i][j]*(255/65535.0);

  4. #4
    Membre confirmé Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Arf désolé je me suis trompé de bout de code à vous montrer :/
    Ca c'est quand j'ai essayé de faire un réetalement de la dynamique, car vu que mes températures ne varient pas entre 0 et 65535, c'est le meilleur moyen pour avoir du contraste sur l'image (réaffecter 0 à la plus basse température et 256 à la plus élevée). Mais j'ai préféré laisser ça de côté tant que je n'arrive pas à créer mon image tiff.

    Donc j'ai essayé la solution de Mac LAK, mais malheureusement ça ne fonctionne pas. L'image obtenue n'est pas bonne (cf miniature on devrait avoir une sorte de photos avec des nuages...). C'est donc que j'ai du me tromper dans la création de l'image avec tifflib, y'a t'il une horreur/erreur qui vous saute aux yeux quand vous voyez cela ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
             TIFF* imgTIFF = TIFFOpen("toto.tif","w");
             if (imgTIFF == NULL)
                {
                printf("erreur à la creation du tiff");
                }
             else
                { 
                TIFFSetField(imgTIFF,TIFFTAG_IMAGEWIDTH,NBLIG);
                for (i=0; i<NBLIG; i++)
                   {
                   TIFFWriteScanline(imgTIFF,temp8bit[i],i,0);
                   }            
                TIFFClose(imgTIFF);  
                }
    Merci de votre aide !

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Flaherty Mc Coillean Voir le message
    (réaffecter 0 à la plus basse température et 256 à la plus élevée)
    Attention : 256 n'est PAS une valeur autorisée dans une image 8 bits, c'est 255 le maximum !!!
    La solution que je te donne (via un décalage binaire) est la meilleure approximation possible de ce que tu cherches, considérant bien sûr que la dynamique de base est bien sur l'échelle 0..65535. Si elle est plus courte que ça, un changement d'échelle sera nécessaire avant d'appliquer la moindre formule si tu désires obtenir systématiquement une image avec une dynamique 8 bits maximale.
    Citation Envoyé par Flaherty Mc Coillean Voir le message
    y'a t'il une horreur/erreur qui vous saute aux yeux quand vous voyez cela ?
    Je ne connais hélas pas cette librairie, donc difficile de t'aider à ce sujet.
    Par contre, tu peux éventuellement sauvegarder ton image dans un format plus simple afin de mieux voir ce qu'il se passe : je ne saurais trop te conseiller soit un format RAW, soit un format TGA pour les tests (afin de vérifier si l'image est correcte).
    Si tu utilises TGA, il te suffit de sauver les valeurs R, G et B comme étant égales entre elles, et valant ta couleur 8 bits calculée.

    Si ton image RAW/TGA est bonne, c'est que ton utilisation de la librairie TIFF est foireuse. Si l'image RAW/TGA est foireuse, c'est ton algo qui est en cause. Au pire, ça t'aidera à trouver plus rapidement la localisation de l'erreur.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    Membre confirmé Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Salut,

    J'ai retravaillé dessus, et j'ai progressé, en fait je n'avais pas suffisamment paramétré mon tiff. J'arrive désormais a créer une image tiff qui est presque bonne. Je dis presque parce qu'il y'a un sérieux problème de déformation...

    En fait ce qui devrait être des colonnes, forme des diagonales (cf les miniatures). Le premier pixel qui devrait se trouver en haut à gauche de l'image se retrouve en haut à droite... Pourtant théoriquement TIFFTAG_ORIENTATION précise bien qu'il faut qu'il soit en haut à gauche :/

    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
             TIFF* imgTIFF = TIFFOpen("toto.tif","w");
             if (imgTIFF == NULL)
                {
                printf("erreur à la creation du tiff");
                }
             else
                {
                int SamplesPerPixel = 1, BitsPerSample = 8;
     
                TIFFSetField(imgTIFF, TIFFTAG_BITSPERSAMPLE, BitsPerSample);
                TIFFSetField(imgTIFF, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
                TIFFSetField(imgTIFF, TIFFTAG_IMAGELENGTH, NBLIG); 
                TIFFSetField(imgTIFF, TIFFTAG_IMAGEWIDTH, NBCOL);
                TIFFSetField(imgTIFF, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
                TIFFSetField(imgTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
                TIFFSetField(imgTIFF, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 
                TIFFSetField(imgTIFF, TIFFTAG_SAMPLESPERPIXEL, SamplesPerPixel);
     
                for (i=0; i<NBLIG; i++)
                   {
                   TIFFWriteScanline(imgTIFF,temp8bit[i],i,0);
                   }            
                TIFFClose(imgTIFF);
                }
    Voilà des idées pour corriger ce petit problème ?

  7. #7
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 317
    Par défaut
    J'ai l'impression que ça correspond plus à un décalage de pixel, non ?

    La diagonale (bas-gauche => haut-droit) de la seconde image correspond au bord gauche de la première image

    La première ligne du bas serait bien remplie mais avec au moins 1 pixel en trop ou en moins => les lignes suivantes reporteraient ce décalage...

    Les dimensions de l'image finale (NBLIG et NBCOL) sont-elles bonnes ?

  8. #8
    Membre confirmé Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Arf merci Dut ! C'était effectivement un problème de décalage plus en amont dans mon code...

    Le problème est réglé, merci beaucoup à tous !

  9. #9
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 317
    Par défaut
    J'espère ne pas trop dire de bêtises mais je pense qu'il y a un problème avec ton allocation de mémoire en cas d'échec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (i=0;i<NBLIG;i++)
    {
        temp8bit[i]= malloc(NBCOL * sizeof(unsigned char));
        if (temp8bit[i] == NULL)
        {
            free(temp8bit[i]);
            printf("erreur lors de l'allocation memoire 5");
        }
        for (j=0; j<NBCOL; j++)
            temp8bit[i][j]=temperature[i][j]*(255/65535);
    }
    Si temp8bit[i] ne peut pas être alloué, tu continues quand même ton code...

    Dans un premier temps sépare l'allocation de mémoire du calcul proprement dit .
    Ensuite, il faut désallouer la mémoire de tous les éléments précédemment alloués et pas seulement du dernier.
    Enfin, il faut sortir du programme si l'allocation échoue

    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
    for (i=0;i<NBLIG;i++)
    {
        temp8bit[i] = malloc(NBCOL * sizeof(unsigned char));
        if (temp8bit[i] == NULL)
        {
            for(j=0;j<i;j++)
            {   
                free(temp8bit[j]);
                temp8bit[j] = NULL;
            }
     
            printf("erreur lors de l'allocation memoire 5");
     
            return; /* A modifier suivant le type de retour de ton code */
        }
     
    }
     
    for (i=0;i<NBLIG;i++)
        for (j=0; j<NBCOL; j++)
            temp8bit[i][j]=temperature[i][j]*(255/65535);

  10. #10
    Membre confirmé Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    ah merci je n'avais pas vu...

    En fait pour toutes les autres allocations mémoire j'ai fait ça :

    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
       unsigned short int ** temperature = malloc (NBLIG * sizeof(unsigned short int*));
       if (temperature == NULL)
          {
          free(temperature);
          printf("erreur lors de l'allocation memoire 2");
          }
       else
          {
          for(i=0;i<NBLIG;i++)
             {
             temperature[i]=malloc(NBCOL * sizeof(unsigned short int));
             if(temperature[i] == NULL)
                {
                free(temperature[i]);
                printf("erreur lors de l'allocation memoire 3");
                }
             else
                {
                /*bout de code*/
                }
             }
          }
       free(temperature)
    Ce qui fait qu'en cas d'échec d'allocation on quitte le code et on arrive sur free(temperature). Est ce que free(temperature) suffit pour désallouer entièrement la mémoire où il faut absolument désallouer temperature[i] pour tous les i ?

  11. #11
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Flaherty Mc Coillean Voir le message
    Est ce que free(temperature) suffit pour désallouer entièrement la mémoire où il faut absolument désallouer temperature[i] pour tous les i ?
    En C, tu dois avoir une égalité stricte entre le nombre de malloc et le nombre de free, il n'y a pas de concept de destructeur comme en C++ qui se charge de détruire les entités possédées.

    Donc, si tu as fait une boucle de NBLIG itérations pour allouer, il te faut une boucle de NBLIG itérations pour libérer.

    EDIT : Inutile de faire un free sur un malloc qui a échoué, par contre. Si malloc échoue, il n'y a rien à libérer car rien n'a été alloué.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  12. #12
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 317
    Par défaut
    Citation Envoyé par Flaherty Mc Coillean Voir le message
    Ce qui fait qu'en cas d'échec d'allocation on quitte le code et on arrive sur free(temperature). Est ce que free(temperature) suffit pour désallouer entièrement la mémoire où il faut absolument désallouer temperature[i] pour tous les i ?
    => http://rperrot.developpez.com/articl...llocationC/#L3

  13. #13
    Membre confirmé Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Par défaut
    Merci pour vous réponses, je vais régler tout ça de suite!

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

Discussions similaires

  1. Problème de traitement d'image tiff
    Par Galkir dans le forum C++Builder
    Réponses: 2
    Dernier message: 29/06/2006, 10h05
  2. [image]Création d'image dynamique
    Par Booyakha dans le forum Struts 1
    Réponses: 24
    Dernier message: 07/06/2006, 19h01
  3. Réponses: 2
    Dernier message: 06/02/2006, 10h12
  4. Lire une image Tiff en C/cpp avec Lib tiff
    Par syn_42 dans le forum MFC
    Réponses: 4
    Dernier message: 04/01/2006, 22h28
  5. Rotation d'une image TIFF
    Par Tub-95 dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 14/10/2005, 21h56

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