# YUV to RGB (einfache Berechnung)



## Soahc (9. Apr 2010)

Hallo Zusammen,

ich mochte einen kleinen Konverter programmieren, der mit die BitWerte aus dem RGB-Farbmodel in das YUV-Farbmodel und umgekehrt berechnet. Die Werte sollen jeweils immer nur in einem Wertebereich von 8 Bit, also 0..255 liegen. Eigentlich sollte das keine große Sache sein, aber ich bekomms einfach nicht gebacken. 

Erstmal gibt es auf jeder Seite im Internet unterschiedliche Formeln. z.B.:

RGB <--> YUV Conversion Formulas
YUV/RGB conversion formulas Definition from PC Magazine Encyclopedia
Welcome to FOURCC.org - YUV to RGB Conversion
YUV-Farbmodell ? Wikipedia

...

Ich habe zwar schon alle Varianten durch, aber hier mal mein Code von der ersten Seite:
[JAVA=42]
private void rgbToYuv(){
	    this.y = (int) Math.round(this.r *  0.299 + this.g *  0.587 + this.b * 0.114);
	    this.u = (int) Math.round(this.r * -0.169 + this.g * -0.332 + this.b *  0.500 + 128);
	    this.v = (int) Math.round(this.r *  0.500 + this.g * -0.419 + this.b * -0.0813 + 128);	
	}

	private void yuvToRgb(){
             this.r = (int) Math.round(this.y + (1.4075 * (this.v - 128)));
	     this.g = (int) Math.round(this.y - (0.3455 * (this.u - 128)) - (0.7169 * (this.v - 128)));
	     this.b = (int) Math.round(this.y + (1.7790 * (this.u - 128)));
	}
[/code]

von RGB nach YUV lässt es sich sehr gut umrechnen, nur wenn ich mit den errechnetten YUV Werten wieder die RGB-Werte errechnen will, kommt totaler Quatsch raus. Hat da jemand einen Tip, was ich falsch gemacht haben könnte?

lg, Soahc


----------



## Ark (9. Apr 2010)

Witzigerweise habe ich gerade genau dasselbe Problem: Irgendwie kommt bei Anwendung der Formeln Murks raus. Meine Untersuchungen haben ergeben, dass es sich dabei wahrscheinlich um Rundungsfehler handelt (bin mir aber nicht sicher). Die exakteste Formel, die ich bisher fand, ist die hier. Die Formel für den Grünanteil kann man alternativ natürlich direkt durch Umstellen herleiten.  Danach sind alle Ergebnisse auch praktisch exakt (Ungenauigkeiten der Gleitkommazahlen ausgenommen).

Ark


----------



## Siassei (9. Apr 2010)

Ark hat gesagt.:


> Irgendwie kommt bei Anwendung der Formeln Murks raus. Meine Untersuchungen haben ergeben, dass es sich dabei wahrscheinlich um Rundungsfehler handelt (bin mir aber nicht sicher).


Naja, das liegt wohl daran, dass RGB != RGB ist. 

Es gibt sRGB, Adobe-RGB, eciRGB, ....
siehe RGB-Farbraum ? Wikipedia

Ein erster Überblick:
Farbraum ? Wikipedia
Welcome to Bruce Lindbloom's Web Site

Ich weiß nicht wie genau du das ganze benötigst, sollte die Umrechnung möglichst gut sein, solltest du einen Umweg über einen normierten Farbraum DIN99 gehen. Von diesen bekommst sehr gute Veröffentlichungen, mit denen du in allen anderen Farbräumen umrechnen kannst.



> Die Werte sollen jeweils immer nur in einem Wertebereich von 8 Bit, also 0..255 liegen[/qoute]
> Hierfür sollten die 4-stellige Umrechnungszahlen reichen. Ark hat dir den Link bereits gegeben. Ich meine, dass die von sRGB ausgehen.


----------



## Soahc (9. Apr 2010)

@Ark: Öhmn.. hast Du die Formeln schon in Java-Code übersetzt? 

@Siassei: Das ist mir schon klar, aber ich gehe von normalem 8Bit-RGB und 8-Bit YUV aus... beide haben also 3*8 Bit um eine Farbe darzustellen, also müsste man sie doch linear umrechnen können.


----------



## Ark (9. Apr 2010)

Soahc hat gesagt.:


> @Ark: Öhmn.. hast Du die Formeln schon in Java-Code übersetzt?


Ja, irgendwo daheim sollten sie liegen, wenn ich mich recht erinnere.  Allerdings sollte es keine Hürde sein, die Gleichungen einfach selbst umzustellen. 

@Siassei: Stimmt, ich gehe von sRGB aus. Danke für den Hinweis.

Ark


----------



## Ark (9. Apr 2010)

So, bitte nicht über die Unleserlichkeit des Codes beschweren.  Die Anordnung im Array ist jeweils R,G,B bzw. Y,U,V. Bei RGB wird hier immer auf 0-255 hochgerechnet; runden darfst du selbst. 

```
public void fromRGB(double[] rgbvalues,double[] result){
		double r=rgbvalues[0]/255.0;
		double b=rgbvalues[2]/255.0;
		double y=0.299*r+0.587*(rgbvalues[1]/255.0)+0.114*b;
		result[0]=y;
		result[1]=(b-y)*0.493;
		result[2]=(r-y)*0.877;
	}

	public void toRGB(double[] values,double[] rgbresult){
		double y=values[0];
		double b=y+values[1]/0.493;
		rgbresult[2]=b*255.0;
		double r=y+values[2]/0.877;
		rgbresult[0]=r*255.0;
		rgbresult[1]=((y-0.299*r-0.114*b)/0.587)*255.0;
	}
```

Hat jemand etwas Entsprechendes für YCbCr zu bieten, wie es bei JPEG zum Einsatz kommt? Das würde mich mal interessieren. ^^

*EDIT:* Okay, diese Seite erscheint gerade _extrem_ interessant. :exclaim:

Ark


----------

