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

Java Discussion :

Conversion Image 32 bit virgule flottante en 8 bit niveaux gris


Sujet :

Java

  1. #21
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    de ta phrase "les données de départ, ce sont des pixels en couleurs codées sur 4 octets" avec le mot "couleurs" mais c'est une maldonne de ma part apparemment.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  2. #22
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2012
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    l'image est très grande et faire un getPixel(x,y) est impossible pour deux raisons:
    1 le fait de creer une BufferedImage de cette taille la c'est le OutOfMemory assuré
    2 faire 410 millions de modification pixel par pixel serait trop long

    de plus j'ai un programme en C qui le fait sans problème simplement par modification des valeurs float du fichier donc c'est tout à fait possible, le seul problème c'est la manière que Java a de récupérer les float du fichier alors que C à des valeurs parfaitement correct au vu des résultats, se pourrait t-il que la lecture du fichier soit différente entre java et C ?

  3. #23
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Euh, tu lis un pixel coloré, tu calcule le pixel gris, tu écris le pixel gris, au pif t'as besoin de 5 octets par pixel traité... Mais bon, apparemment tu ne comprends pas le problème.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  4. #24
    Membre actif
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Points : 255
    Points
    255
    Par défaut
    Citation Envoyé par JoeChip Voir le message
    Où vois tu que je parles de RGBA ???? il y a 4 octets, donc 32 bits, donc 2^32 couleurs possibles, quel que soit le codage...
    Heu c'est plus compliqué que ça avec un flottant de 32 bits, non ? Tu as une mantisse et un exposant. En fonction de la taille de la mantisse on obtient plus ou moins de valeurs possibles... A ça on doit combiner le nombre d'algorithmes possibles qui permettent de transformer le signal capturé par le satellite en pixel...

  5. #25
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Le fait est qu'en C et en Java on ne lit pas les fichiers binaires de la même manière.

    Tu pourrais pas simplement nous montrer comment tu lis et écris un float, au lieu de nous parler de couleurs ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #26
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2012
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    pour lire les float j'utilise la méthode readFully de FileImageInputStream et mais dans la description elle me dit qu'elle lit par rapport au standard IEEE 754 alors que moi je veux juste un float simple au lieu d'avoir 9,5*10^-45 moi je veux une valeur du genre 4561.000 comme en C mais le Java a une maniere etrange de lire les floats

  7. #27
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2012
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    j'ai testé avec des int a la place des float et le resultat est meilleur mais pas encore parfait on peut voir qu'il y a des pixels noirs un peu partout(image 2 zoomé)
    Images attachées Images attachées   

  8. #28
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Heu c'est plus compliqué que ça avec un flottant de 32 bits, non ? Tu as une mantisse et un exposant. En fonction de la taille de la mantisse on obtient plus ou moins de valeurs possibles.
    Euh, non... avec 32 bits, tu as 2^32 possibilités, un point c'est tout, c'est de la théorie de l'information élémentaire. En float tu en as même plutôt moins, puisqu'il y a plusieurs façons de représenter certains float...
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  9. #29
    Membre actif
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Points : 255
    Points
    255
    Par défaut
    Citation Envoyé par magid31 Voir le message
    pour lire les float j'utilise la méthode readFully de FileImageInputStream et mais dans la description elle me dit qu'elle lit par rapport au standard IEEE 754 alors que moi je veux juste un float simple au lieu d'avoir 9,5*10^-45 moi je veux une valeur du genre 4561.000 comme en C mais le Java a une maniere etrange de lire les floats
    "Java a une manière étrange de lire les float http://fr.wikipedia.org/wiki/IEEE_754

    Ce que je vois dans ton image, ce ne sont pas des pixels mais de grossières zones plus ou moins sombre... Si tu ne sais pas comment sont stockées les informations lues par le satellite (ce n'est peut-être même pas une photo), tu n'auras jamais une image.
    Bonne nouvelle, dans certains fichiers RAW, il existe une image en niveaux de gris décrite pixel par pixel (1 octet par pixel) et même, parfois, une miniature au format JPEG... mais mauvaise nouvelle, RAW n'est pas une norme.
    Donc avec un peu de chance, chaque plage de 32 bits de ton fichier contient un pixel en niveau de gris (1 octet) et 3 octets d'effets divers permettant de calculer le rendu des couleurs, de la luminosité, et peut-être même d'autres information comme la température locale, la pression, ou je ne sais ce qui a été mesuré par le satellite. Du coup ton algo en C applique un filtre à chaque octet pour ne garder que l'information qui l'intéresse. Et comme il connait la manière dont ont été stockées les données il sait qu'il restitue un entier à la fin...
    Maintenant, si tu nous donnes cet algo en C ou la spec de ton fichier RAW, on pourra peut-être aller plus loin

  10. #30
    Membre actif
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Points : 255
    Points
    255
    Par défaut
    Citation Envoyé par JoeChip Voir le message
    Euh, non... avec 32 bits, tu as 2^32 possibilités, un point c'est tout, c'est de la théorie de l'information élémentaire. En float tu en as même plutôt moins, puisqu'il y a plusieurs façons de représenter certains float...
    J'insiste : dans un float tu as une mantisse de 23 bits... ça te donne environ 6 à 7 chiffres significatifs en base 10, tu as en plus un bit de signe et la possibilité de décaler la virgule... Plus d'information, mais moins précise

  11. #31
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Euh. Bon. On a 32 bits. Ca donne 2^32 combinaisons possibles, pas une de plus.

    Tu codes comme tu veux, t'as 2^32 possibilités, quelle que soit la taille de la mantisse, que ce soient des entiers ou des pixels, ou des pointeurs ou ce que tu veux, tu n'auras pas plus de 2^32 possibilités. D'ailleurs, c'est ce que ça veut dire, "32 bits" : 2^32 possibilités, comme "4 chiffres décimaux" veut dire "10.000 possibilités"
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  12. #32
    Membre actif
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Points : 255
    Points
    255
    Par défaut
    Enfin c'est plus comme si tu avais 7 chiffres décimaux (~20 millions de possibilités) et 2 chiffres pour positionner la virgule entre 10^99 et 10^-99 ... Non?

  13. #33
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    7 chiffres décimaux (~20 millions de possibilités) et 2 chiffres pour positionner la virgule
    Introduction à la théorie de l'information : l'information numérique

    L'information numérique est "discrète", càd qu'elle n'est pas continue : elle représente un nombre fini de possibilités, qui dépend du nombre de position numériques disponibles.

    En base 10, avec un chiffre on a 10 possibilités (de 0 à 9), avec 2 chiffres on en a 100 (de 0 à 99), soit 10x10, avec 9 chiffres on a 10x10x10x10x10x10x10x10x10 possibilités, donc 10^9 ...

    Donc, 7 chiffres décimaux, ça fait 10 millions de possibilités. 2 chiffres pour positionner la virgule, ça fait 100 possibilités. Donc déjà un milliard de possibilités. Fois encore 2 (un bit, donc) pour le signe de la mantisse, et un autre bit pour le signe de l'exposant. Donc en tout, ça fait 4 milliard de possibilités. Soit 4x10^9...

    En base 2, même raisonnement, avec 32 chiffres binaires ("bits"), on a 2^32 possibilités maximum, soit 4 294 967 296 possibilités. Ah mince, quasiment 4x10^9, comme quoi ton évaluation était plutôt bonne...

    A chacune de ses possibilités, on peut donner un sens, par exemple :

    - l'ASCII : on va numéroter les caractères, en disant qu'il y en a 128; on a donc besoin de 7 bits par caractère, puis on va arbitrairement définir les correspondances, par exemple "65" c'est "A", "66" c'est "B", "32" c'est un espace, "10" c'est une nouvelle ligne, "13" c'est un retour chariot, "7" c'est un coup de sonnette, etc. Sympa, après on va pouvoir écrire des textes, et même faire sonner le télex à l'autre bout
    - le float : on va prendre par exemple 4 octets, une partie arbitraire des bits pour une mantisse signée, le reste pour un exposant signé, comme ça on aura en général une répartition satisfaisante des 2^32 valeurs entre un truc très grand et un truc très petit. En fait c'est pas mal, on aura toujours à peu près la même précision.
    - la couleur 24 bits : on va dire qu'on prend 3 octets, le premier c'est la composante rouge, le deuxième la verte, le troisième la bleu, c'est cool ça nous fait 2^24 couleurs possibles. Après si on veut on pourra utiliser ça pour savoir de quelle couleur on parle, héhé.
    -etc

    D'ailleurs, s'il y avait davantage de possibilités, comment ferait-on ? On peut commencer par mettre en correspondance chaque combinaison des 32 bits avec un float, ça ferait donc (maximum) 2^32 floats. Tu dis "on peut en représenter davantage". D'accord. Comment ? Toutes les combinaisons de bits sont déjà prises...

    En fait, le nombre de bits est une mesure de la quantité d'information.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  14. #34
    Membre actif
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Points : 255
    Points
    255
    Par défaut
    Bon je m'avoue vaincu, tu as raison. D'autant plus que le float, ici, à du être utilisé arbitrairement dans l'algorithme pour extraire et manipuler les informations par plages de 32bits... rien a voir avec aucune norme connue, je me trompe?

  15. #35
    Membre habitué
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2004
    Messages : 102
    Points : 156
    Points
    156
    Par défaut
    Pour revenir au débat initial, est ce que tu connais le format d'encodage des flottants du raw (style little endian/big endian ou autre )?

    Si je devais lire un fichier de flottants, je réécrirais/essaierais de trouver une librarie qui me permette de récupérer.

    Tu récupères le max et le min des valeurs de l'image alors qu'à mon avis, il s'agirait plutôt de la dynamique maximum (sur un APN ou les couleurs sont codées sur 12 bits, je prendrais comme max : 2^12).

    Enfin, il y a peut-être le gamma à réajuster (http://en.wikipedia.org/wiki/Gamma_correction), mais cela dépend du format d'affichage de ton image.

  16. #36
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    En fait, il n'y a aucune raison de penser qu'il s'agit de "flottants" : on a simplement 32 bits d'information sur chaque point, il faut en extraire 8 bits d'information sur la luminosité du point. Il faut donc connaitre l'encodage de départ, çàd quelles sont les spécifications de l'image de départ, comme on le dit depuis le début. "c'est des pixels en 32 bits", ça ne suffit pas, comme info.

    Bon je m'avoue vaincu
    Ce n'est pas une question de victoire ; j'espère que tu comprends mieux, simplement.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  17. #37
    Membre actif
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Points : 255
    Points
    255
    Par défaut
    J'aime bien la matière, donc j'ai été lire d'autres articles sur les sujet du coup, pour mieux comprendre mon erreur... Ce que je préfère dans ce que tu as dit c'est :
    En fait, le nombre de bits est une mesure de la quantité d'information.
    Bonne journée

  18. #38
    Membre à l'essai
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2012
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    j'ai fini par trouver la solution, en effet java lit par défaut les float en big endian donc une simple conversion en little endian par manipulation des octets m'a servit, pour ceux qui en auront besoin dans un futurs proche voila le 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
    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
     
    // création d'un tableau de byte de la taille de l'image multiplié par 4 etant donné que chaque pixel est codé sur 4 octet il nous faut donc un tableau //de byte 4 fois plus grand que le nombre total de pixel
    // et d'un tableau de float de la taille de l'image, peut créer un outOfmemory 
    // si l'image est trop grande mais j'ai déjà  créer un post sur comment 
    // gérer ce problème
    byte []tabPxl = new byte[largeur*hauteur*4];
    float[]tab1 = new float[largeur*hauteur];
    /** enregistrement de l'image à l'aide d'un FileImageInputStream dans le tableau de byte **/
    fichier.read(tabPxl);
    // création d'un float le ( little endian ^^) qui va stocker notre float convertit
    float le;
    // création d'un tableau de byte de taille 4 qui va nous servir pour remettre 
    // les octets  big endian dans l'ordre little endian
    byte[]be=new byte[4];
    //variable qui va nous servir a sauté 4 octet a chaque incremention de x //pour ne pas retravaillé sur les même octets (exemple je lis les octet 0 1 2 3 //mon pas augmente de 4 et donc je lis maintenant 4 5 6 7 et ainsi de //suite...)
    int pas=0;
    for(int x=0;x<tab1.length;x++)
    {
     
     // on convertit le big endian en little endian
     // il s'agit simplement de changer l'ordre des octets
    		be[0]=tabPxl[pas+3];
    		be[1]=tabPxl[pas+2];
    		be[2]=tabPxl[pas+1];
    		be[3]=tabPxl[pas];
    // on incremente notre pas (ou saut)
    		pas+=4;
    // on convertit notre tableau de byte en 1 float et on enregistre celui-ci //dans le tableau 
    		le = b2F(be);
                    tab1[x]=le;								
    }
    // on crée un tableau de byte de la taille du nombre de pixel
    datatab = new byte[hauteur*largeur];
    // on cherche le max et le min 
    double max=tab1[0], min= tab1[0];
    for(int x=0;x<tab1.length;x++)
    {
    	if(max < tab1[x])
            {
    	    max=tab1[x];
    	}
    	if(min > tab1[x])
            {
    	    min =tab1[x];
    	}
    }
     
    // on calcul le coefficient pour obtenir la valeur comprise entre 0 et //255						
    double scale=255.0F/(max-min);
    int valeur=0;
    for(int j = 0; j<datatab.length ;j++)
    {
    	// on ramène la valeur du pixel entre 0-255
    	valeur = (int) ((tab1[j]-min)*scale);
           // on ramène les valeur négative ou supérieur dans l'intervalle
           // inutile si vous ne disposez pas d'image ndvi
    	if( valeur<0)
           {
    		valeur= valeur*-1;
           }
           else if(valeur>255)
           {
    		valeur=255;
           }
           // on convertit notre valeur recalculer et ramener entre 0-255 en byte
           datatab[j]=(byte) valeur;
     
    }
    	// on ferme le flux 
    	fichier.close();
    Pour ce qui est de créer l'image chacun a sa méthode pour ma part j'utilise des DataBufferByte samplemodel bufferedImage...
    Merci à tous pour votre aide !!!!

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. conversion image 8 bit en image 2 bit
    Par colorid dans le forum Langage
    Réponses: 4
    Dernier message: 17/10/2013, 18h26
  2. Virgule flottante format IEEE 754 bit implicite
    Par scipionh dans le forum Sujets
    Réponses: 2
    Dernier message: 13/05/2013, 05h24
  3. Conversion virgule fixe - virgule flottante
    Par Doug0 dans le forum Débuter
    Réponses: 4
    Dernier message: 29/02/2012, 11h27
  4. Conversion nombre décimal en virgule flottante IEEE 754 (exprimé en hexa)
    Par vinssieux dans le forum Macros et VBA Excel
    Réponses: 36
    Dernier message: 15/05/2008, 09h40
  5. Réponses: 6
    Dernier message: 16/05/2004, 19h03

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