Page 2 sur 2

Re: trouver le nombre le plus proche parmi plusieurs

Publié : mer. 15/nov./2017 10:41
par Mesa
@blendman
Au cas où les nombres seraient des couleurs, il faut faire attention à prendre des quad surtout quand on compare des couleurs ! ! !
Voir la doc à la rubrique rgba()
Remarques

Resultat varie de 0 à 4 294 967 295 teintes. Il est donc conseillé d'utiliser un 'quad', (Resultat.q) et de mettre à zéro les octets inutilisés. En effet, sur un système d'exploitation 32 Bits, Resultat est un integer de type Long (par défaut) dont la plage d'utilisation va de - 2 147 483 648 à + 2 147 483 647.

Utiliser les commandes suivantes Red(), Green(), Blue() et Alpha() pour extraire la valeur d'une des composantes 'Rouge', 'Verte', 'Bleue' ou 'Alpha'.

Un tableau représentant les couleurs les plus communes est disponible ici. Ces fonctions sont utiles lors des opérations de dessin 2D.
Exemple

Couleur.q = RGBA(255, 255, 255, 255) ; Blanc totalement opaque
Debug LSet(Hex(Couleur, #PB_Quad), 16, "0")
Couleur = Couleur & $FFFFFFFF ; mise à zéro des octets inutilisés,
; utile pour la comparaison de couleur
Debug LSet(Hex(Couleur, #PB_Quad), 16, "0")


ou alors il faut utiliser les fonctions purebasic, comme red(), etc...

M.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : jeu. 16/nov./2017 8:56
par blendman
Merci pour vos commentaires

@Falsam & MLD : je vais tester votre nouveau code ;)

@Celtic88 : J'ai testé ton code et c'est pas mal en fait ;)

@Zorro : c'est une bonne idée de détecter les couleurs les plus proches comme ça.
J'aimerai faire une palette intelligente, c'est à dire de choisir parmi les couleurs non pas les plus utilisées, mais celles qui sont très différentes (tout en étant parmi les plus utilisées), pour garder les contrastes par exemple ^^.
Mais ça ce n'est pas évident.

@Mesa : tu as raison pour les quad, j'avais oublié ça.
Je vais l'intégrer pour voir si ça me permet de conserver mieux les couleurs.

Donc, pour stocker la couleur du pixel, je dois faire ça ?

Code : Tout sélectionner

color.q = Point(i,j) & $FFFFFFFF 




encore merci à vous, je continue mes tests.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : jeu. 16/nov./2017 19:19
par Mesa
mmm, oui mais j'ai un doute.
Par précaution je ferai

Code : Tout sélectionner

color.q = Point(i,j)
color = color & $FFFFFFFF 
pour être sûr que le "and" se fasse sur le quad et pas sur le point(i,j) qui est un integer.

M.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : jeu. 16/nov./2017 20:32
par Zorro
blendman a écrit : J'aimerai faire une palette intelligente, c'est à dire de choisir parmi les couleurs non pas les plus utilisées, mais celles qui sont très différentes (tout en étant parmi les plus utilisées), pour garder les contrastes par exemple ^^. .
ma routine ne fait que "mesurer" la distance entre deux teintes
donc plus la teinte est lointaine, le maximum etant ( RGB(0,0,0) // RGB(255,255,255) ) plus ça te retourne une valeur élevé

par contre, je n'ai pas trop compris ce que tu cherche a faire :)

Re: trouver le nombre le plus proche parmi plusieurs

Publié : jeu. 16/nov./2017 22:09
par Ollivier
Zorro a écrit :

Code : Tout sélectionner

 Declare distance_couleur(couleur1,couleur2)
debug "couleur peu distante : "+ str(distance_couleur(rgb(255,0,2),rgb(255,0,5))) ;
debug "couleur identique :"+str( distance_couleur(rgb(255,0,2),rgb(255,0,2)) );
debug " couleur tres eloignée :"+str(distance_couleur(rgb(255,255,255),rgb(0,0,0))) ;
Procedure distance_couleur(couleur1,couleur2)
; by Dobro
rf.c=red(couleur1) :vf.c=green(couleur1): bf.c=blue(couleur1)
r.c=red(couleur2) :v.c=green(couleur2): b.c=blue(couleur2)
distance=sqr(pow(rf-r.c,2)+ pow(vf-v.c,2)+pow(bf-b.c,2)) ; calcul de la distqnce qui separe la
couleur de l'image avec la couleur de la palette
ProcedureReturn distance
Endprocedure
;Epb 
Tu peux sophistiquer le berzingue aussi :

Code : Tout sélectionner

Procedure.I ColorDist(p.I, q.I)
   a = alpha(p) - alpha(q)
   r = red(p) - red(q)
   g = green(p) - green(q)
   b = blue(p) - blue(q)
   a * a
   r * r
   g * g
   b * b
   ProcedureReturn Sqr(a + r + g + b)
EndProcedure
Là, chaque couleur est dans un hyper-cube de 256 unités de côté. Ça intègre la transparence avec une simplicité déconcertante.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : ven. 17/nov./2017 0:27
par Fig
Et en assembleur ça donnerait ça... (en retirant la racine carrée qui est inutilement chronophage pour notre comparaison)

Code : Tout sélectionner

DisableDebugger
Procedure.L ColorDist(p.i, q.i)
   a = Alpha(p) - Alpha(q)
   r = Red(p) - Red(q)
   g = Green(p) - Green(q)
   b = Blue(p) - Blue(q)
   a * a
   r * r
   g * g
   b * b
   ProcedureReturn a + r + g + b
EndProcedure
Procedure.L ColorDistAsm(p.L, q.L)
   EnableASM
   MOV eax,dword [p.v_p]
   MOV ebx,dword [p.v_q]
   MOV edi,ebx
   AND eax,255
   AND ebx,255
   SUB eax,ebx
   IMUL eax
   MOV ebp,eax
   
   MOV eax,dword [p.v_p]
   MOV ebx,edi
   SHR eax,8
   SHR ebx,8
   AND eax,255
   AND ebx,255
   SUB eax,ebx
   IMUL eax
   MOV esi,eax
   
   MOV eax,dword [p.v_p]
   MOV ebx,edi
   SHR eax,16
   SHR ebx,16
   AND eax,255
   AND ebx,255
   SUB eax,ebx
   IMUL eax
   MOV ecx,eax
   
   MOV eax,dword [p.v_p]
   MOV ebx,edi
   SHR eax,24
   SHR ebx,24
   AND eax,255
   AND ebx,255
   SUB eax,ebx
   IMUL eax
   
   ADD eax,ecx
   ADD eax,esi
   ADD eax,ebp
   
   ProcedureReturn
   DisableASM
EndProcedure
a.q=ElapsedMilliseconds()
For i=1 To 10000000
   ColorDist(2000, 1001)
Next i
a=ElapsedMilliseconds()-a
b.q=ElapsedMilliseconds()
For i=1 To 10000000
   ColorDistAsm(2000, 1001)
Next i
b=ElapsedMilliseconds()-b
MessageRequester("test",Str(a)+"ms vs "+Str(b)+"ms ")
 
Sinon, une fois le tableau trié, on peut éviter de comparer tous les éléments, en partant du centre du tableau et en appliquant une recherche dichotomique.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : lun. 20/nov./2017 17:34
par Mesa
@Blendman
Je ne veux pas te couper dans ton élan, mais si tu veux une méthode tiptop, alors il te faudra utiliser les produits de convolution (niveau math universitaire bac + 2 ou 3, la quantifiquation par wavelet (math bac +5) ou par réseau neuronaux (math bac +5).

En fait la réduction des couleurs est un problème "vieux comme l'informatique" et qui n'a pas de solution à la fois simple et éfficace car c'est fonction de la complexité de la photo (nombre de couleur au départ et répartition plus ou moins aléatoire des couleurs).

L'algorithme de zorro est à la fois le plus ancien trouvé par les informaticien qui est toujours utilisé, à condition d'accepter la dégradation de la qualité.
https://en.wikipedia.org/wiki/Color_quantization
C'est un choix à faire: poids ou qualité, comme toujours.

Tu peux toujours essayer de trouver un code tout fait, en faisant une recherche google avec "wavelet" ou "neuronal" et "Color quantization"

M.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : mer. 06/déc./2017 10:43
par blendman
Mesa a écrit :Je ne veux pas te couper dans ton élan, mais si tu veux une méthode tiptop, alors il te faudra utiliser les produits de convolution (niveau math universitaire bac + 2 ou 3, la quantifiquation par wavelet (math bac +5) ou par réseau neuronaux (math bac +5).
Bon, bah, j'ai pas le niveau en math ^^.

Par contre, mon algorythme marche quand super bien, pourtant il est hyper simple, mais il n'utilise pas (pas encore) les couleurs indexées intelligentes.

Je verrais plus tard si j'ai le temps de le modifier ;)

En fait la réduction des couleurs est un problème "vieux comme l'informatique" et qui n'a pas de solution à la fois simple et éfficace car c'est fonction de la complexité de la photo (nombre de couleur au départ et répartition plus ou moins aléatoire des couleurs).
par contre, je n'ai pas trop compris ce que tu cherche a faire
Je veux simplement réduire le poids des images pour mes jeux.
J'ai testé plusieurs programmes, mais pour le moment, je n'ai trouvé aucun soft qui réduise le poids des png (ou jpg) comme mon programme :
- pnggauntlet : c'est pourri lol. J'ai testé plein d'images, et je gagne maximum 5 à 10 % et encore. Moi, avec une qualité presque identité, je gagne parfois plus de 50% !
- png optimiser : pourri, je gagne moins de 5%
- Xn-view : on perd la transparence des pngs, et la qualité est fortement réduite, mais la taille aussi (+70% de gain si je passe en 256 couleurs, mais je perds la transparence).
- caesar : le plus pourri : augmente la taille des png !

Le meilleur (mais online et payant si plug ing photoshop) :
- Tinypng : gain : 75% sur certains fichier avec très peu de perte de qualité, très impressionnant.
- La plupart des outils online font de la bonne compression, mais c'est online, donc l'image reste sur leur serveur.

Après, mon soft à moi se défend pas mal du tout ^^ (même si c'est moins bon que tinypng).

Re: trouver le nombre le plus proche parmi plusieurs

Publié : mer. 06/déc./2017 11:39
par Micoute
Pour être heureux, il faut savoir se contenter de ce qu'on a et pas de ce qu'on pourrait avoir.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : mer. 06/déc./2017 15:02
par djes
Regarde du côté des formats par ondelettes, tu as des codeurs/décodeurs gratuits, et ce sans d'autre perte que celle du temps de compression. Les meilleurs (MrSid ou ECW) sont sous copyright, mais le JPEG2000 devrait convenir. pour des photos. A noter que pour du dessin, le PNG sera meilleur, sauf si tu ajoutes des dégradés ou ce genre de choses.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : ven. 15/déc./2017 20:40
par Ollivier
@Fig

ton code ASM mériterait d'être copié en section ASM dans un sujet ludique pour tenter de faire plus rapide hors SSE. Etrangement, en voulant le détrôner, non seulement d'avoir, pour l'instant échoué, faute de temps, j'ai appris 2, 3 astuces en ASM. Ça me semblerait intéressant de le faire partager dans un tel sujet.

Re: trouver le nombre le plus proche parmi plusieurs

Publié : dim. 17/déc./2017 21:19
par Fig
Je t'en prie, crées le sujet si tu le souhaite. On peut surement faire plus rapide sans aucun doute. :wink:

Re: trouver le nombre le plus proche parmi plusieurs

Publié : sam. 23/déc./2017 11:49
par Ollivier
Bonjour Fig,

pas si évident que ça de créer plus rapide hors SSE. Et justement, je me suis confronté à des rappels de règles arithmétiques vieux de 30 ans au moins pour tenter de "supplanter".

Tenter de faire plus vite n'a pas grand intérêt. Mais raconter les casseroles que j'ai rencontrées en voulant faire mieux, ça peut aider certains à se familiariser avec l'ASM.

Je suis très occupé actuellement, mais si j'ai un peu de temps à consacrer, je lancerai un sujet en reprenant ton code.

Bon temps à vous, et, pour 50 boules, j'ai une voyante assermentée et certifiée qui m'a prédit une épidémie internationale de crises de foie ces prochains jours. A ce prix-là, je demande à être cru.