View Full Version : YUV to RGB conversion
Chatwalker
27th October 2004, 11:10
Hi
Can someone explain how to convert YUV color values to RGB?
I've already seen a page from mpucoder with a online calculation, but i did'nt find this site anymore.
Thanks a lot.
hank315
27th October 2004, 11:57
This is the correct conversion:
B = (Y - 16) * 255 / 219 + (U - 128) * 2.018
G = (Y - 16) * 255 / 219 - (U - 128) * 0.391 - (V - 128) * 0.813
R = (Y - 16) * 255 / 219 + (V - 128) * 1.596
Chatwalker
27th October 2004, 12:40
Thanks a lot!!
diehardii
29th October 2004, 21:16
Hi, this is funny as I was just coming over here to post the same question. My problem however is that this is for image analysis software, so every inch of performance matters. I don't need to do this often, but when I do I would like it to be fast :D .Does anyone have any code that will do this conversion quickly? Intel used to have a whole site on this with mmx code, but they stupidly took it down:mad: . Anyways, please let me know if you have any examples. Thanks for the help.
~Steve
hank315
29th October 2004, 23:41
Just download the VirtualDub sources and look for the file a_yuv2rgbhq.asm, this shows an MMX version.
Maybe a SSE2 version will even be faster....
diehardii
30th October 2004, 00:58
Hi hank315,
Thanks for the help! Unfortunately I don't yet speak mmx or sse2, do you know what the uv_up, uv_down parameters are supposed to be? The others all make sense. Otherwise, I'll probably just use the non hq (high quality?) version. Thanks again for the hand.
~Steve
morsa
30th October 2004, 03:50
why don't you just make some LUTs and then just sum or rest the corresponding values.That would be much faster.
diehardii
30th October 2004, 13:06
Hi,
What are LUTs? Thanks.
~Steve
Manao
31st October 2004, 10:29
A LUT is a look up table. The principle is simple : if you have a limited set of inputs ( here when computing (U - 128) * 2.018 for example, U ranges from 0 to 255 ), you can precompute once and for all the results and store them into an array ( the LUT ).
However, in such a case, you must not use a LUT ( to have the required precision, you'd still need to use float / double ). The fastest ( non ASM ) way to do it is to make computation in 'int' instead of float. You have to use the same divisor, which has to be a power of 2 ( for speed, there again )
For example, 255/219 ~ 76309/65536 , 2.018 ~ 132252/65536, and so on.
Then, (Y-16) * 255/219 + (U-128) * 2.018 becomes ((Y - 16) * 76309 + (U - 128) * 132252 + 32768) >> 16, which is a lot faster. The 32768 is for rounding correctly.
diehardii
5th November 2004, 19:31
Hi, after banging my head on the wall quite a bit, I have some serious questions about the given conversion. Given a black and white image, y will be variable, however U and V will be either 0 or 16 (doesn't really matter for this example). Using the above equations on a black and white image, the image is very heavily skewed towards the green. A separate set of Equations from "The Image Processing Handbook" (John C. Russ), 1998 suggests that the equations for a transform should be.
R = 1*Y+.956U+0.621V
G = 1*Y - 0.272U - .657V
B = 1*Y - 1.106*U+1.703V
This will lead to a black and white image in RGB from a black and white image in YUV. Please let me know if I'm doing something wrong, I just can't figure out another way to get a black and white image working. Thanks for the help.
~Steve
mpucoder
5th November 2004, 20:21
The equations given by Hank are correct for ITU 470. But you must realize that U and V are biased by 128, and use the full range of values. For monochrome U and V should be 128. Y is limited to values between 16 and 235 inclusive.
diehardii
5th November 2004, 20:36
Aghh, I see thank you, the bias to 128 was the piece I was missing.
~Steve
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.