AccueilAccueil  FAQFAQ  RechercherRechercher  S'enregistrerS'enregistrer  MembresMembres  Connexion  

Partagez | 
 

 [C++] Approximation entière d'un produit avec un float

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
Mass
*Excellent utilisateur*
avatar

Messages : 3325
Localisation : Dans une canonnière wookie.
Projet Actuel :
Things


MessageSujet: [C++] Approximation entière d'un produit avec un float   Mar 4 Nov 2014 - 15:43

Salut tout le monde happy1

Je m'intéressait il y a peu au traitement/compression du signal vidéo et j'ai eu à convertir un signal RGB en un signal YUV.
La formule "classique" donnée notamment par Wikipédia est la suivante :

Code:
Y = 0,299 * R + 0,587 * G + 0,114 * B
U = −0,14713 * R − 0,28886 * G + 0,436 * B
V = 0,615 * R − 0,51498 * G - 0,10001 * B

Cela marche très bien mais il s'agit de multiplier chaque composante RGB (un entier non signé de 8 bits) par un float, donc c'est un calcul beaucoup plus lent pour le CPU.

J'ai donc trouvé un code similaire qui me fait le même calcul mais avec une approximation utilisant des entiers :
Code:
#define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)

#define RGB2Y(R, G, B) CLIP(( (  66 * (R) + 129 * (G) +  25 * (B) + 128) >> 8) +  16)
#define RGB2U(R, G, B) CLIP(( ( -38 * (R) -  74 * (G) + 112 * (B) + 128) >> 8) + 128)
#define RGB2V(R, G, B) CLIP(( ( 112 * (R) -  94 * (G) -  18 * (B) + 128) >> 8) + 128)

Ici CLIP est une simple fonction empêchant l'overflow, mais comme vous pouvez le constater, l'intégralité du calcul se fait au moyen d'entiers, ce qui est beaucoup beaucoup beaucoup plus rapide (testé et approuvé).

Le soucis, c'est que je ne comprend pas le fonctionnement de ce code. J'aimerai comprendre comment il fonctionne, et j'aimerai surtout établir une façon de faire de même pour n'importe quel produit utilisant des flottants !

Quelqu'un pourrait me donner des pistes pour y parvenir ?
Merci de votre aide gnii

_________________
Revenir en haut Aller en bas
http://madmass.mype.fr/CBNA/
onilink_
Modérateur
avatar

Messages : 8915
Localisation : Montpellier
Projet Actuel : Planet Centauri
OniDev

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Mar 4 Nov 2014 - 16:34

Bah en fait tu changes juste de repère, donc de base c'est [0.0, 1.0] vers un repère entier.
Du coup tous les trucs a virgule, tu multiplies par X, ce qui donne:

[0.0, 1.0]
Y = 0.299 * R + 0.587 * G + 0.114 * B

[0, 220]
Y = 0.299 * 220 * R + 0.587 * 220 * G + 0.114 * 220 * B
Y = 66 * R + 129 * G +  25 * B

Par contre, le (X + 128) >> 8, je sais pas trop a quoi ça correspond la...

_________________
                 
Revenir en haut Aller en bas
Mass
*Excellent utilisateur*
avatar

Messages : 3325
Localisation : Dans une canonnière wookie.
Projet Actuel :
Things


MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Mar 4 Nov 2014 - 20:51

Comment tu détermines X ?

_________________
Revenir en haut Aller en bas
http://madmass.mype.fr/CBNA/
onilink_
Modérateur
avatar

Messages : 8915
Localisation : Montpellier
Projet Actuel : Planet Centauri
OniDev

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Mar 4 Nov 2014 - 21:44

Bah perso j'aurais choisis 255, du coup je sais pas trop comment ils ont déterminé 220.
C'est peut être lié aux autres trucs que je capte pas trop Razz

_________________
                 
Revenir en haut Aller en bas
ombre
Utilisateur confirmé: Rang ***
avatar

Messages : 689
Localisation : Dans sa batcave.

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Mar 4 Nov 2014 - 22:52

C'est que des histoires de % est malheureusement ça marche qu'avec les multiples de 2 ! Petite astuce de développeur pour faire une division (sans virgule of course) avec un multiple de 2 c'est l'opérateur >>
Par exemple, diviser par 2, c'est >> 1
diviser par 4 c'est >> 2
...
DONC diviser par 256 ça équivaut à >> 8
<< x ; c'est multiplier par 2^x.

Je prends un le 1er code :
Y = 0,299 * R + 0,587 * G + 0,114 * B
En faites c'est :
29.9% de rouge + 58,7% de vert + 11,4% de bleu
en gros :
Y = (29,9 * R + 58,7  * G + 11,4 * B) / 100
Sauf qu'on sait là, que le max c'est 256 (2^8 ), donc plutôt que faire un ratio 100, il fait un ratio 255 :
~= (environ égale)
0.299 * 255 ~= 66
0.587 * 255 ~= 129
0.114 * 255 ~= 25
Après son calcul c'est :
(66 * R + 129 * G + 25 * B) / 255

Le +128, c'est parce que je penses que c'est des nombres "négatifs" (donc de -128 à 128) et il passe ça à 0 à 256.
Le + 16 c'est l'anguille de l'histoire, mais j'ai tendance à penser que c'est ce qui manque pour faire 256 (66 + 129 + 25 + 16).

En gros, si tu veux faire la même méthode, c'est pour faire des calculs de %, et au lieu d'utiliser une base 100, faut utiliser une base 256.
Revenir en haut Aller en bas
http://www.3arks.com
onilink_
Modérateur
avatar

Messages : 8915
Localisation : Montpellier
Projet Actuel : Planet Centauri
OniDev

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Mer 5 Nov 2014 - 9:17

Ouai bah justement, dans le calcul ci dessus pour Y il utilise 220 et pas 256.
Et après être passé d'un domaine flottant a un domaine entier, je vois toujours pas l’intérêt de faire un >> 8 perso Razz

_________________
                 
Revenir en haut Aller en bas
Mass
*Excellent utilisateur*
avatar

Messages : 3325
Localisation : Dans une canonnière wookie.
Projet Actuel :
Things


MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Jeu 6 Nov 2014 - 20:15

ben parce que il faut repasser sur 8 bits après, donc diviser par 256 vu qu'il a multiplié par 220 (au lieu de 256) avant, du coup happy1

_________________
Revenir en haut Aller en bas
http://madmass.mype.fr/CBNA/
onilink_
Modérateur
avatar

Messages : 8915
Localisation : Montpellier
Projet Actuel : Planet Centauri
OniDev

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Jeu 6 Nov 2014 - 20:27

Ah ouai c'est vrai que la valeur en entrée est entière... Reste juste a comprendre le 220 du coup Very Happy

_________________
                 
Revenir en haut Aller en bas
Mass
*Excellent utilisateur*
avatar

Messages : 3325
Localisation : Dans une canonnière wookie.
Projet Actuel :
Things


MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Jeu 6 Nov 2014 - 20:54

Peut-être une erreur ? Ou une approximation spécifique à la conversion YUV ?
C'est embêtant j'espérais que cette méthode me permettrait de transformer un bon nombre de calculs flottants en approximation avec des entiers, mais elle est moins miracle que ce que je pensais beh

_________________
Revenir en haut Aller en bas
http://madmass.mype.fr/CBNA/
onilink_
Modérateur
avatar

Messages : 8915
Localisation : Montpellier
Projet Actuel : Planet Centauri
OniDev

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Jeu 6 Nov 2014 - 21:09

Bah elle est pas utile dans n'importe quel cas imaginable ouai, mais sinon ça permet de faire des optis assez cool en général surtout quand tu bidouilles des images.

_________________
                 
Revenir en haut Aller en bas
[TheDarkTiger]
Modérateur
avatar

Messages : 7377
Localisation : Essonne

MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   Lun 24 Nov 2014 - 0:44

C'est dû aux niveaux électriques du signal.

Le 'Noir' 'studio' n'est pas le même que le 'noir' 'PC'.
Ainsi, pour le Y (la luminosité), sur PC, elle est dans l'intervalle [0-255], parce qu'on peut stoquer tout ça, mais en 'studio', (donc avant l'avènement numérique), les signaux ne pouvaient pas aller au vrai 0 électrique ni au niveau maximum (1V de mémoire). Donc, en numérisant ces signaux, on tombait à peu près sur [16-235]. Les valeurs ont don été normalisées pour les données studio : le Y aura un niveau minimal de 16 et une amplitude de 220, soit l'intervalle [16-235].

Bref, un reliquat d'un temps ancien où l'on est passé au MPEG.

Edit :
L'article wikipedia en anglais sur le YUV est plutôt bien fait.
https://en.wikipedia.org/wiki/YUV

Le paragraphe "Numerical approximations" corrobore à peu près ce que je disait.
aparement, c'est plutôt qu'avec les erreurs d'arrondi, on arrivait à 16 de différence, et qu'ils ont juste recentré le tout pour être sûrs de pas déborder.

_________________
Bonne chance pour vos projets actuels ! Prêt à aider ceux qui en ont besoin ^^
l'antique http://www.membres.lycos.fr/thedarkminousite/
Bienvenue au 2521eme utilisateur : Jeijmeh_ !
Revenir en haut Aller en bas
http://www.membres.lycos.fr/thedarkminousite/
Contenu sponsorisé




MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   

Revenir en haut Aller en bas
 
[C++] Approximation entière d'un produit avec un float
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» MAJ du 05/05/11 mes débuts avec mac/ajout de mes autres produits!!!!
» Coastal Scents et EZ Prez pour presser avec amour?
» Produit vaisselle
» Et vous lavez ou pensez laver bébé avec quoi?
» Trucs et astuces pour en finir avec la poussière !

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Forum Le CBNA :: Développement :: Programmation-
Sauter vers: