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.
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
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 ?
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...)
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...
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
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
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é)
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...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.
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...)
"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
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...)
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?
Introduction à la théorie de l'information : l'information numérique7 chiffres décimaux (~20 millions de possibilités) et 2 chiffres pour positionner la virgule
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...)
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?
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.
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.
Ce n'est pas une question de victoire ; j'espère que tu comprends mieux, simplement.Bon je m'avoue vaincu
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...)
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 :
Bonne journéeEn fait, le nombre de bits est une mesure de la quantité d'information.
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 :
Pour ce qui est de créer l'image chacun a sa méthode pour ma part j'utilise des DataBufferByte samplemodel bufferedImage...
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();
Merci à tous pour votre aide !!!!
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager