Log in

View Full Version : Yuv <-> hsv


jmac698
27th July 2011, 04:35
Hope this didn't exist before :)
This is better I'm sure someone *cough Gavino* will comment :)

#Demo
colorbars(pixel_type="YV12")
yuv2yhs
yhs_viewamp#view saturation, non-solid color indicates slight saturation error (this is not true saturation)
#yhs2yuv

#YHS Tools by jmac v0.3
#Requires Masktools v2 and YV12 video
#Functions to convert to and from YHS which is Y, Hue, Saturation - almost
#Simply finds the phase and amplitude of the YCbCr values
# and scales them back into a YUV clip
#Can be useful to quickly view color hue/saturation. Can also make adjustments to hue/saturation (todo).
#All functions work, reconversion fairly accurate
function yuv2yhs(clip y){
y
dist="x 128 - 2 ^ y 128 - 2 ^ + .5 ^"#sqrt(x^2+y^2)
deg="180 pi / * 360 + 360 %"#(*180/pi+360) % 360
sc1="224 120 / * 16 +"#scale 120 to 16-235 for saturation
sc2="224 360 / * 16 +"#scale 360 degrees to 16-240 to stuff in U
amp=mt_lutxy(utoy,vtoy,dist+" "+sc1)#close to saturation, max=120 (I think)
#check if v is 128, to avoid div0. Return 0 for convenience. Otherwise return atan2(u,v) which is the angle from coord.
#then convert to degress and scale to fit chroma range.
#sample hue's:
#Color Deg Ph Dist Amp
#Blu 351 234 113 175
#Red 109 83 118 181
#Yel 171 122 113 175
#Cyn 289 195 118 181
#ph is close to hue but starting at blue-magenta
ph=mt_lutxy(utoy,vtoy,"y 128 = 0 "+dist+" x 128 - - y 128 - / atan 2 * "+deg+" ? "+sc2)
ytouv(ph,amp,y)
}

function yhs2yuv(clip y){
y
sc1="16 - 120 224 / *"#scale 16-235 to 120 for saturation
sc2="16 - 360 224 / *"#scale 16-240 to 360 degrees
rad="pi 180 / *"#scale degrees to radians
u=mt_lutxy(utoy,vtoy,"x "+sc2+" "+rad+" cos y "+sc1+" * 128 +")
v=mt_lutxy(utoy,vtoy,"x "+sc2+" "+rad+" sin y "+sc1+" * 128 +")
ytouv(u,v,y)
}

function yhs_viewamp(clip y){
vtoy(y)
}

function yhs_viewph(clip y){
utoy(y)
}

function yhs_tweak(clip y, int sat, int hue){
y
#Just mutiply U to increase saturation
#Just add to V to change hue
#todo...
}

Gavino
27th July 2011, 10:25
I'm sure someone *cough Gavino* will comment :)
Well, since you asked... :)
Just one thing had me puzzled for a minute:

sc1="224 120 / * 16 +"#scale 120 to 16-235 for saturation
...
sc1="16 - 120 224 / *"#scale 16-235 to 120 for saturation
At first I thought the 224 in the code was wrong, but it's just the comment: 235 should be 240.

function yhs_tweak(clip y, int sat, int hue){
#Just add to V to change hue
... remembering to wrap around (to 16) when going past 240.

Of course, the standard Tweak can already do hue and saturation adjustment.
And (for RGB) we now have Wilbert's HSVAdjust filter.

jmac698
27th July 2011, 14:21
Actually I was wondering if tweak does s/v adjustment just like I'm doing, or a real adjustment. The real adjustment would mean scaling one of the UV axes and doing a rotation of 33 degrees +180 (I think), to correspond with the definition that hue0=red, and to get the saturation evenly in a circle.
The CbCr is scaled for maximum precision and is not even due to the slight rotation of the color wheel.

jmac698
27th July 2011, 14:33
We missed something. I didn't scaled from 224->219 in yhs_viewamp. You're right, the comment is wrong. And your warning about wrapping is something I forgot, I guess mod224 +16 will handle that.
I want to find true hsv, because all the vectorscope plugins out there do it wrong, and I don't think anyone truly adjusts h/s. I could make a numerically scaled colorspace for this just to display proper vectorscope (not to look at). It would also be neat to try encodes with true hsv. I wonder how it would act on denoising?

Gavino
27th July 2011, 17:03
Actually I was wondering if tweak does s/v adjustment just like I'm doing, or a real adjustment.
It does it the same way as you, simply converting (u,v) to polar co-ordinates, and taking the amplitude to represent saturation and the phase angle to represent hue. Thus hue=0 corresponds to v=0, a non-standard interpretation.

We missed something. I didn't scaled from 224->219 in yhs_viewamp.
Yes, I didn't think of that.
But actually, is there a good reason to use 16-240 in the first place? Why not just use 0-255 for both saturation and hue, giving slightly greater precision?

jmac698
27th July 2011, 19:57
I can include a fullrange flag in my function. In tests I found that reconversion was within +-1, I don't think it will make a huge difference. It's only those cases around .5 that make a difference.
But thanks for the answer, I think I really must do true HSV now.

Mr VacBob
4th August 2011, 05:47
HSV is not a particularly accurate colorspace. If you're trying to realistically change colors of something, CIELAB or so is a better one to do it in. It's harder to write the conversion for, of course.

jmac698
6th August 2011, 18:13
That's true, but my colorspace has some uses. For example, it's the usual hardware implementation, so I find it useful to model and undo hardware adjusted videos. It also helped me assess the level of noise in chroma, and here, to detect if there's any useful chroma. I'd like to update to find the yiq signal which is used in s-video, then I can model and fix common color errors like ... I forget what it's called, but when luma affects chroma saturation, this happens in analog electronics.
The saturation plane could be used for sharpening color transitions.
I'd like to write more colorspace conversions.