View Full Version : YUV and RGB color conversion problems
vcmohan
31st March 2005, 12:24
While testing a plugin of mine where I have balloons of different colors, opacity and light directions I had lot of problems with RGB color spaace. Switching over to YUY2 or YV12 I found I could get result easy. Then I checked processing in YV12 and in script using converttoRGB32() call. Strangely I had all sorts of artifacts. Since I do not have a website where the images can be posted nor could figure out how more than one file could be attached, I using vdub to output images and Irfanviewer to panorama and resize the file is attached.
The left image is the result of proceessing in YV12 and using converttoRGB32(). The right image is identical process except that convert was omitted. The differences were amazing.
I do not know whether this or similar type of problems were already discussed somewhere else.
What is happening?
E-Male
31st March 2005, 13:49
there are many sites that host images for free, including hotlinking
just google
Guest
31st March 2005, 14:28
There are no attachments pending for approval.
Richard Berg
31st March 2005, 18:05
Without seeing the pics yet, the most likely problem is a bug in the VFW codec being used to decompress the raw YV12. Bugs have been reported in various versions of msyuv.dll, ffvfw, Xvid, and Divx (all of which can do this conversion); I'm not sure which if any have known-good fixes available.
If you want to preview output e.g. in VDub, the safest way to get correct colors is to add ConvertToRGB32 at the end of the script. Huffyuv.dll can also be used as bug-free (afaict) decompressor, but it only supports YUY2, not YV12.
vcmohan
1st April 2005, 03:29
Originally posted by neuron2
There are no attachments pending for approval.
In the new thread box at the bottom attach file I have included path to my file. I am surprised to note that there was no file attached. What is the way to attach file then?
[i]Originally posted by Richard Berg{/i]
If you want to preview output e.g. in VDub, the safest way to get correct colors is to add ConvertToRGB32 at the end of the script.
ConverttoRGB32() at the end is giving all problems. Without this processing in YV12 and straight viewing in vdub is showing up properly (I think).
If required I can email my plugin dll and description of usage or its source.
Richard Berg
1st April 2005, 04:28
Without this processing in YV12 and straight viewing in vdub is showing up properly (I think).
What YV12 codec does VDub report you're using?
What makes you sure? For reference, I would encode to a lossless codec & compare that to the preview.
vcmohan
1st April 2005, 13:02
I think there is some problem in communicating. I am not processing any video. In fact I am using a blank clip as my background. I create circular (spherical) balloons of specified color, opacity, and reflecting a light placed at either front, left, right, top or bottom.
It is possible that the way I tried to do this is flawed. However I tried similar procedures in RGB and YUV formats. RGB results were unacceptable (to me). Then I tried converting the pixels from RGB to YUV and process identically and finally convert back to RGB for output. Surprisingly this also gave different results to that of YUV processing only. I am including the relevant code below. bht stands for base frame height. rest may be understandable.
unsigned char y=0.299*red+0.587*green+0.114*blue;
unsigned char u=-0.169*red-0.332*green+0.5*blue+128;
unsigned char v=0.5*red-green*0.419-blue*0.0813+128;
..............
if(vi.IsRGB32() || vi.IsRGB24() )
{
for(int h=sy;h<ey;h++)
for(int w=sx; w<ex;w++) if((h-yy)*(h-yy)+(w-xx)*(w-xx)<=radius*radius)
// within the circle
{
int bias=y<128?128:y<235?235-y:0;
int ratio;
// shading gradient. dark at periphery, light at center
if(*light=='f' ||*light=='F') ratio=bias-(bias*((h-yy)*(h-yy)+(w-xx)*(w-xx)))/(radius*radius); else if(*light=='l' ||*light=='L' ) // light on left
ratio=(bias*((h-yy)*(h-yy)+(w-radius/2-xx)*(w-radius/2-xx)))/(radius*radius);
else if(*light=='r' ||*light=='R' ) // light on right
ratio=(bias*((h-yy)*(h-yy)+(w+radius/2-xx)*(w+radius/2-xx)))/(radius*radius);
else if(*light=='t' ||*light=='T' )
// light at top
ratio=(bias*((h-radius/2-yy)*(h-radius/2-yy)+(w-xx)*(w-xx)))/(radius*radius);
else if(*light=='b' ||*light=='B' )
// light at bottom ratio=(bias*((h+radius/2-yy)*(h+radius/2-yy)+(w-xx)*(w-xx)))/(radius*radius);
else
ratio=0;
ratio=ratio>bias?bias:ratio;
// As formulating in RGB space is not resulting properly convert to YUV
// strangely even this has problems.
int yvalue=0.299*(*(lp+(bht-1-h)*lpitch+kb*w))
+0.587*(*(lp+(bht-1-h)*lpitch+kb*w+1))
+0.114*(*(lp+(bht-1-h)*lpitch+kb*w+2));
// calculate y with background being seen thru
double newy=(yvalue*(100-opacity))/100<y?y:(yvalue*(100-opacity))/100;
unsigned char finaly=newy+ratio>235?235:newy+ratio;
// use this y and balloon U and V
*(lp+(bht-1-h)*lpitch+kb*w)=finaly+1.779*(u-128);
*(lp+(bht-1-h)*lpitch+kb*w+1)=finaly-0.3455*(u-128)-0.7169*(v-128);
*(lp+(bht-1-h)*lpitch+kb*w+2)=finaly+1.4075*(v-128);
}
}
//The differing relevant part in YV12 processing is
unsigned char yvalue=*(lp+(h)*lpitch+w);
// calculate y with background being seen thru
unsigned char newy=(yvalue*(100-opacity))/100<y?y:(yvalue*(100-opacity))/100;
// ensure within limit
*(lp+(h)*lpitch+w)=newy+ratio>235?235:newy+ratio;
// using balloon U and V values
*(lpU+(h/2)*lpitchUV+w/2)=u;
*(lpV+(h/2)*lpitchUV+w/2)=v;
I tried using and tags. But the code went all over place. So removed them
I expected identical results but RGB is bad.
Richard Berg
6th April 2005, 03:12
Here is what I think you are saying:
"I have a filter that works correctly in YUV. When I convert to RGB, I see artifacts in VDub."
Here is my proposed test (to hopefully avoid codec bugs):
(1) Leave the filter running in YUY2. Encode a few frames of the output to HuffYUV.
(2) Add ConvertToRGB32() after your filter. Encode a few frames to raw.
Now compare these two AVIs. If there is a significant difference, please find a way to upload them...neuron2 has an open FTP server for instance.
vcmohan
6th April 2005, 04:01
I think I found out the problem. unsigned char for the sample values while converting to and fro to rgb-yuv use double maths. Reconversion to unsigned char by the c++ I thought would properly preserve values excepting for losing accuracies. I found overflow and underflows which completely changed the colors. Now I am using checks for these while still in Integer or double state and finally using unsigned char. It works ok now.
Backwoods
8th April 2005, 05:45
www.imageshack.us
www.uploadhouse.com
Free picture hosting if you still want to post some samples.
vcmohan
9th April 2005, 14:20
. Thanks for the info. I am just not happy that I have to take recourse to a third party hosting to display sample images here. I posted my views in the site related forum and given reason for this. There may be valid reasons for now but I am not happy and hope in not too distant future this will be solved.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.