AccueilAccueil  FAQFAQ  RechercherRechercher  Dernières imagesDernières images  S'enregistrerS'enregistrer  Connexion  
Le Deal du moment : -50%
-50% Baskets Nike Air Huarache Runner
Voir le deal
69.99 €

 

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

Aller en bas 
4 participants
AuteurMessage
Mass
*Excellent utilisateur*
Mass


Messages : 3351
Localisation : Dans une canonnière wookie.
Projet Actuel : Monter des trucs et des machins

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyMar 4 Nov 2014 - 16: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
onilink_


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

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyMar 4 Nov 2014 - 17: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...

_________________
[C++] Approximation entière d'un produit avec un float Runningpotato1[C++] Approximation entière d'un produit avec un float TvF6GED [C++] Approximation entière d'un produit avec un float MdetltS
Revenir en haut Aller en bas
Mass
*Excellent utilisateur*
Mass


Messages : 3351
Localisation : Dans une canonnière wookie.
Projet Actuel : Monter des trucs et des machins

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

Comment tu détermines X ?

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


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

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyMar 4 Nov 2014 - 22: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

_________________
[C++] Approximation entière d'un produit avec un float Runningpotato1[C++] Approximation entière d'un produit avec un float TvF6GED [C++] Approximation entière d'un produit avec un float MdetltS
Revenir en haut Aller en bas
ombre
Utilisateur confirmé: Rang ***
ombre


Messages : 689
Localisation : Dans sa batcave.

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyMar 4 Nov 2014 - 23: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
onilink_


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

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyMer 5 Nov 2014 - 10: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

_________________
[C++] Approximation entière d'un produit avec un float Runningpotato1[C++] Approximation entière d'un produit avec un float TvF6GED [C++] Approximation entière d'un produit avec un float MdetltS
Revenir en haut Aller en bas
Mass
*Excellent utilisateur*
Mass


Messages : 3351
Localisation : Dans une canonnière wookie.
Projet Actuel : Monter des trucs et des machins

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyJeu 6 Nov 2014 - 21: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
onilink_


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

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyJeu 6 Nov 2014 - 21: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

_________________
[C++] Approximation entière d'un produit avec un float Runningpotato1[C++] Approximation entière d'un produit avec un float TvF6GED [C++] Approximation entière d'un produit avec un float MdetltS
Revenir en haut Aller en bas
Mass
*Excellent utilisateur*
Mass


Messages : 3351
Localisation : Dans une canonnière wookie.
Projet Actuel : Monter des trucs et des machins

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyJeu 6 Nov 2014 - 21: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
onilink_


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

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyJeu 6 Nov 2014 - 22: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.

_________________
[C++] Approximation entière d'un produit avec un float Runningpotato1[C++] Approximation entière d'un produit avec un float TvF6GED [C++] Approximation entière d'un produit avec un float MdetltS
Revenir en haut Aller en bas
[TheDarkTiger]
Modérateur
[TheDarkTiger]


Messages : 7420
Localisation : Essonne

[C++] Approximation entière d'un produit avec un float Empty
MessageSujet: Re: [C++] Approximation entière d'un produit avec un float   [C++] Approximation entière d'un produit avec un float EmptyLun 24 Nov 2014 - 1: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 ^^
[C++] Approximation entière d'un produit avec un float U3dfr2[C++] Approximation entière d'un produit avec un float Sign l'antique
Bienvenue au 2629eme utilisateur : Mike Jones !
Revenir en haut Aller en bas
http://www.tdms.fr
Contenu sponsorisé





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

Revenir en haut Aller en bas
 
[C++] Approximation entière d'un produit avec un float
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» produit en croix
» variable entiere
» Problème avec un objet dirigé vers un autre avec image_angle
» [Resolu] Orienter un vecteur 2D avec un angle avec cosinus et sinus.
» probleme avec game maker studio et avec CBNA Bump 2

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