Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 Doom9's Forum Manual White Balance in YUV without converting to RGB
 Register FAQ Calendar Search Today's Posts Mark Forums Read

 3rd March 2014, 02:25 #1  |  Link Leo D9 Registered User   Join Date: Feb 2013 Posts: 10 Manual White Balance in YUV without converting to RGB 1) Firstly, when adjusting white balance in RGB, my understanding is that the correct way to do this is by simply scaling the values of one or two of the R, G and/or B channel(s) as required. Is that correct? 2) There seem to be many ways of changing Y, U and V, but what is the "correct" method (by which I guess I mean mathematically/colorimetrically correct, not subjective) of manually adjusting white balance in the YUV colorspace? (Or is it necessary/better to convert to RGB, scale the channels and convert back?) 3) Is there a simple way to translate a colour temperature conversion into a change of YUV, and/or change of RGB? (I sometimes work with RGB so an answer for each would be useful.) e.g. If I want to convert the colour temperature from 3200K to 5600K how would I do that in YUV, and how should it be done in RGB? Many thanks! PS: 4) Mildly off-topic, but when using ColorYUV(autogain=true) will any values get clipped? The documentation says, "it will scale up the luma (y) values to match the minimum and maximum values." So, if there is one value at 255 and everything else is 200 or less what happens? And if the lowest value in the image is, say, 30 what happens? (ie, does it adjust the offset for setting black as well as pure gain?) Or does it do something like clip 1% of whites and 1% of blacks. Is it purely on a per-frame basis, completely ignoring preceding and subsequent frames? Also, since (unlike in Levels() ) I can't specify a black level (eg 0 or 16) nor a white level (eg 235 or 255), how does it know what the max and min values should be? (Assuming I'm not changing the levels "TV->PC" or "PC->TV".) Thanks.
 3rd March 2014, 07:46 #2  |  Link smok3 brontosaurusrex     Join Date: Oct 2001 Posts: 2,392 1. Can't be that simple, since what you got is curved nonLinear camera data, so you'd need to uncurve that before changing each curve to fix white balance. (or fix the actual existing curve considering low,mid,high positions) (resolve lite is free and you'd get the idea how it may actually work) __________________ certain other member
 3rd March 2014, 12:26 #3  |  Link Gavino Avisynth language lover   Join Date: Dec 2007 Location: Spain Posts: 3,423 Regarding ColorYUV(autogain=true), it simply adjusts the gain_y and off_y parameters, on a per-frame basis, to put the darkest pixel in each frame at y=16 and the brightest at y=236 (not 235, for some reason!). The levels parameter ("TV->PC" or "PC->TV") is ignored in this process. EDIT: It's a little more complicated if you have existing pixels outside the range [16,236]. What actually happens is it sets gain_y and off_y so that the range [max(yMin, 16), min(yMax, 236)] is mapped to [16,236]. __________________ GScript and GRunT - complex Avisynth scripting made easier Last edited by Gavino; 3rd March 2014 at 12:45.
 4th March 2014, 06:33 #4  |  Link Leo D9 Registered User   Join Date: Feb 2013 Posts: 10 Ach, I'd forgotten about the gamma curves. So how do people manage/control white balance in AviSynth? What is the standard method? eg if I load a clip and see the white balance is off, how should it be corrected? @Gavino : So that means if I use autogain on a clip with the range 0-255, then the frames with any pixel above 235 and any pixel below 16 won't be changed at all? So I would have to do Levels(0, 1, 255, 16, 235) before autogain to ensure 0-255 clips are treated the same way as 16-235 clips? I guess that risks banding? Basically... my problem is that I'm processing and encoding dozens of video clips one by one by using a batch file to generate a temporary AVS file (to add intro, outro, title, watermark, temporal smoothing, etc) that gets encoded by FFMPEG. Some of the clips could be 16-235 and some 0-255 (such as Canon DSLR MOVs). 5.A) Is there any way to automatically identify the luma/chroma range of a clip or normalise the whole clip to a range? (Ideally without needing a plug-in.) 5.B) And when I encode the clip with FFMPEG.exe, does it just assume the range is 16-235 with Rec.709 colour? (Sorry if that's off-topic, perhaps I should have started a new thread.) Thanks. Last edited by Leo D9; 4th March 2014 at 19:06. Reason: Levels() syntax, as noted by Gavino
4th March 2014, 13:21   #5  |  Link
Gavino
Avisynth language lover

Join Date: Dec 2007
Location: Spain
Posts: 3,423
Quote:
 Originally Posted by Leo D9 @Gavino : So that means if I use autogain on a clip with the range 0-255, then the frames with any pixel above 235 and any pixel below 16 won't be changed at all?
If a frame has some pixels above 235 AND some below 16, it will not be changed at all. However, if it has some above 235, but the darkest pixel is (for example) 20, then the range [20, 236] will be mapped to [16,236] and the pixels above 236 will be increased in brightness. A similar effect occurs at the other end if there are pixels below 16 but none above 236 (the darkest pixels will get darker).

Quote:
 So I would have to do Levels(0, 255, 1, 16, 235) before autogain to ensure 0-255 clips are treated the same way as 16-235 clips? I guess that risks banding?
Yes [you mean Levels(0, 1, 255, 16, 235)], and if you wanted the output to remain 0-255 you would also have to do Levels(16, 1, 235, 0, 255) after.
__________________
GScript and GRunT - complex Avisynth scripting made easier

 5th March 2014, 06:32 #6  |  Link raffriff42 Retried Guesser     Join Date: Jun 2012 Posts: 1,373 I don't know all the math involved, but I found some interesting things on the Wikipedia page on Color Temperature. Take a look at this animation: it's the light spectrum of a radiating black body at various temperatures: I took this image and carefully measured the graph values at red, green and blue (estimated from the rainbow bar at the bottom) and normalized to 0-255: Adjusted for gamma=1.8: I also measured the color swatch: (not shown: red below about 6500k; it's always 255; similarly, blue above about 6500K is always 255) Note Wikipedia does not attempt to show the high red & blue levels at the extremes; it looks like they convey the impression of reddish or bluish white (given the limits of computer imagery) by decreasing the other channels instead. I got some transfer functions by curve regression, but I haven't attempted to use them, because (a) I'm not absolutely certain they will be accurate, and (b), there is a simple cheat that is "good enough" for most purposes: If you view the above Wikipedia animation with a vector scope such as Histogram(mode="color2"), you will notice the color swatch is moving along a pretty straight line on the scope within the range 2000K-20000K. This means a simple call to ColorYUV with the appropriate values of offset_u and offset_v can fake color temp changes pretty well. In fact, the result looks identical to Photoshop's "warm" and "cool" photographic filters... But that wasn't good enough for me! Simply adding U and V offsets cannot correct white, black and gray balance at the same time. To me, it looks kinda nasty (too much saturation in blacks and whites). So to do it correctly, one should use RGB mode and adjust gain, offset and gamma on all channels. But we want correction in YUV space! So I propose another cheap trick: I create masks for low, middle and high luminance areas and apply different offsets to each range. Here is my take at a cheating color correction function; I am calling it CheapColorTemp. Please try this with your own sources and see if it isn't pretty neat. To me luma range selectivity is more important than mathematical correctness. A "calibrated" way to alter apparent color temperature would be nice though, I admit. Over-adjusted to show the range of the effect. Code: ```##Last=YUV ## CheapColorTemp demonstration ## flip between original and several corrections ## (view in step mode; not for real time playback) Interleave( \ last.Subtitle("original"), \ CheapColorTemp(0, -10, 0).Subtitle("mid -10"), \ CheapColorTemp(0, 0, -10).Subtitle("hi -10"), \ last.Subtitle("original"), \ CheapColorTemp(0, 0, 10).Subtitle("hi +10"), \ CheapColorTemp(0, 10, 0).Subtitle("mid +10")) ## scope(s) optional ## RGBParade http://forum.doom9.org/showthread.php?p=1570968#post1570968 #ConvertToRGB32.HistogramRGBParade ## #Histogram(mode="levels") Histogram(mode="color2") return Last ####################################### ### emulate color temperature changes in three luma ranges ## ## @ offset_x - arbitrary units; <0 means lower temp (warmer colors) ## (input range is unlimited, but is normally around -20 to +20; default 0) ## function CheapColorTemp(clip C, \ int offset_lo, int offset_mid, int offset_hi) { Assert(C.IsYUV, "CheapColorTemp: source must be YUV") return C.ColorYUVx3( \ off_u_lo =offset_lo, off_v_lo =Round(-0.7*offset_lo), \ off_u_mid=offset_mid, off_v_mid=Round(-0.7*offset_mid), \ off_u_hi =offset_hi, off_v_hi =Round(-0.7*offset_hi)) } ####################################### ### apply ColorYUV U & V offsets to three luma ranges ## ## @ off_x - see ColorYUV ## @ xover_x - aproximate 50% luma blend between ranges ## ( no reason to mess with this) ## @ showmasks - if true, show original + 3 masks in quad split ## function ColorYUVx3(clip C, \ float "off_u_lo", float "off_u_mid", float "off_u_hi", \ float "off_v_lo", float "off_v_mid", float "off_v_hi", \ float "xover_lomid", float "xover_midhi", \ bool "showmasks") { off_u_lo = Float(Default(off_u_lo, 0.0)) off_u_mid = Float(Default(off_u_mid, 0.0)) off_u_hi = Float(Default(off_u_hi, 0.0)) off_v_lo = Float(Default(off_v_lo, 0.0)) off_v_mid = Float(Default(off_v_mid, 0.0)) off_v_hi = Float(Default(off_v_hi, 0.0)) xlo = Min(Max( 0, Default(xover_lomid, 102)), 127) * 3.0 / 256 xhi = Min(Max(128, Default(xover_midhi, 191)), 255) * 3.0 / 256 showmasks = Default(showmasks, false) C_lo = C.ColorYUV(off_u=off_u_lo, off_v=off_v_lo) C_mid = C.ColorYUV(off_u=off_u_mid, off_v=off_v_mid) C_hi = C.ColorYUV(off_u=off_u_hi, off_v=off_v_hi) ## mt_lutxyz too slow!! mask_lo = C.mt_lut( \ yexpr="x -0.01 * "+String(xlo)+" + 256 * ", \ u=-128, v=-128) mask_hi = C.mt_lut( \ yexpr="1 x -0.01 * "+String(xhi)+" + - 256 * ", \ u=-128, v=-128) mask_mid = mt_lutxy(mask_lo, mask_hi, "x y + -1 * 256 + ", u=-128, v=-128) return (showmasks) \ ? StackVertical( \ StackHorizontal(C, mask_lo), \ StackHorizontal(mask_mid, mask_hi)) \ .BilinearResize(C.Width, C.height) \ .Subtitle("Low", align=9) \ .Subtitle("\nMid", align=4, lsp=0) \ .Subtitle("\nHigh", align=6, lsp=0) \ : C.Overlay(C_lo, mask=mask_lo) \ .Overlay(C_mid, mask=mask_mid) \ .Overlay(C_hi, mask=mask_hi) }``` Last edited by raffriff42; 18th March 2017 at 01:01. Reason: (fixed image links)
27th November 2014, 21:51   #7  |  Link
TheFluff
Excessively jovial fellow

Join Date: Jun 2004
Location: rude
Posts: 1,100
Quote:
 Originally Posted by raffriff42 I took this image and carefully measured the graph values at red, green and blue (estimated from the rainbow bar at the bottom)
why would you- I don't even...

dude
you realize that image was created by graphing an equation, right? you can have the exact answer for any wavelength and temperature by just asking wolframalpha, jeez

Last edited by TheFluff; 27th November 2014 at 21:57.

 7th March 2014, 07:53 #8  |  Link raffriff42 Retried Guesser     Join Date: Jun 2012 Posts: 1,373 Here's my gamma-adjusted raw data, converted to video, to show the color follows a straight line on a U-V vectorscope. As you can see when viewing this script, there isn't much point to doing more than simply tweaking U and V. Code: ```C = BlankClip(length=1, color=_rgb(226, 77, 12))._sub("2000K") \ + BlankClip(length=1, color=_rgb(224, 93, 30))._sub("2200K") \ + BlankClip(length=1, color=_rgb(219, 110, 47))._sub("2500K") \ + BlankClip(length=1, color=_rgb(216, 120, 60))._sub("2700K") \ + BlankClip(length=1, color=_rgb(212, 130, 72))._sub("2900K") \ + BlankClip(length=1, color=_rgb(206, 141, 85))._sub("3200K") \ + BlankClip(length=1, color=_rgb(198, 148, 100))._sub("3500K") \ + BlankClip(length=1, color=_rgb(192, 158, 112))._sub("3800K") \ + BlankClip(length=1, color=_rgb(182, 162, 127))._sub("4200K") \ + BlankClip(length=1, color=_rgb(176, 167, 141))._sub("4600K") \ + BlankClip(length=1, color=_rgb(167, 171, 152))._sub("5000K") \ + BlankClip(length=1, color=_rgb(160, 174, 164))._sub("5500K") \ + BlankClip(length=1, color=_rgb(152, 176, 175))._sub("6000K") \ + BlankClip(length=1, color=_rgb(148, 178, 179))._sub("6600K") \ + BlankClip(length=1, color=_rgb(141, 178, 192))._sub("7200K") \ + BlankClip(length=1, color=_rgb(136, 178, 201))._sub("7900K") \ + BlankClip(length=1, color=_rgb(132, 178, 207))._sub("8600K") \ + BlankClip(length=1, color=_rgb(127, 178, 213))._sub("9400K") \ + BlankClip(length=1, color=_rgb(124, 178, 217))._sub("10000K") \ + BlankClip(length=1, color=_rgb(120, 178, 221))._sub("11000K") \ + BlankClip(length=1, color=_rgb(116, 178, 226))._sub("12000K") \ + BlankClip(length=1, color=_rgb(112, 178, 228))._sub("13000K") \ + BlankClip(length=1, color=_rgb(109, 174, 237))._sub("15000K") \ + BlankClip(length=1, color=_rgb(105, 174, 239))._sub("16000K") \ + BlankClip(length=1, color=_rgb(101, 174, 242))._sub("18000K") \ + BlankClip(length=1, color=_rgb(101, 174, 245))._sub("19000K") \ + BlankClip(length=1, color=_rgb(101, 172, 249))._sub("21000K") \ + BlankClip(length=1, color=_rgb(100, 172, 252))._sub("23000K") \ + BlankClip(length=1, color=_rgb(100, 172, 254))._sub("25000K") \ + BlankClip(length=1, color=_rgb(100, 172, 255))._sub("28000K") C.ConvertToYV12() Histogram(mode="color2") Loop AssumeFPS(10) return Last function _rgb(int R, int G, int B) { return R*65536 + G*256 + B } function _sub(clip C, string s) { return C.Subtitle(s, text_color=\$808080, align=5, size=C.Height/16) } __END__ Black Body (Wikipedia) digitized from graphic image corrected for gamma=1.8 TEMP R G B 2000 226 77 12 2200 224 93 30 2500 219 110 47 2700 216 120 60 2900 212 130 72 3200 206 141 85 3500 198 148 100 3800 192 158 112 4200 182 162 127 4600 176 167 141 5000 167 171 152 5500 160 174 164 6000 152 176 175 6600 148 178 179 7200 141 178 192 7900 136 178 201 8600 132 178 207 9400 127 178 213 10000 124 178 217 11000 120 178 221 12000 116 178 226 13000 112 178 228 15000 109 174 237 16000 105 174 239 18000 101 174 242 19000 101 174 245 21000 101 172 249 23000 100 172 252 25000 100 172 254 28000 100 172 255``` Last edited by raffriff42; 7th March 2014 at 08:08. Reason: _sub
7th March 2014, 21:09   #10  |  Link
raffriff42
Retried Guesser

Join Date: Jun 2012
Posts: 1,373
Hi Leo D9, thanks for your feedback.

Yes, I am leaving the Y channel completely alone, and adding offsets to the U and V channels.

Re: green-magenta shift, you could call ColorYUVx3() directly instead of through CheapColorTemp(), and adjust the offsets as required; I'd suggest adding a vectorscope, eg Histogram(mode="color2"), so you can see what you are doing. Find something in the video that should be white, or black, or gray, and adjust the appropriate offsets to center the color in the vectorscope.

Sorry about the plugin requirement, but I consider Masktools2 ("alpha 48") to be fundamental, as it's used by so many scripts. It's one of a very few plugins I allow to auto load.

re gamma 1.8, it was a judgement call; I happen to agree with the author of
The Monitor calibration and Gamma assessment page
Quote:
 My personal preference is to set a system gamma of 1.8, even though I use a PC. I'll explain why I made this decision, and you can choose to agree or ignore me, as you wish. Reason 1, and most fundamental, is that a gamma of 2.2 is just too damned dark! ...
I don't know if this method makes sense - it's a hack. Any "real" color corrector would convert to RGB. Avisynth is not really the right tool for color correction - except that it's scriptable and fits into an existing Avisynth workflow. As suggested by smok3, Da Vinci Resolve Lite is an excellent color correction tool.

This method is very subjective and not mathematically correct. That said, I think it looks good and it simple to use, with only 3 parameters to worry about (only two of which are really used - offset_lo should be left alone unless black balancing is needed).

By the way, to do white/black/gray balancing in RGB without plugins, you can do this:
Code:
```MergeRGB(
\    ShowRed("Y8")   .Levels(0, 1.0, 255, 0, 255, coring=false),
\    ShowGreen("Y8") .Levels(0, 1.0, 255, 0, 255, coring=false),
\    ShowBlue("Y8")  .Levels(0, 1.0, 255, 0, 255, coring=false))```
...it's probably best to find the parameters using a visual tool like Photoshop, then copy the numbers over. Too much work if you are correcting scene-by-scene.

Last edited by raffriff42; 7th March 2014 at 21:50. Reason: vectorscope, code

 8th March 2014, 19:54 #11  |  Link Reel.Deel Registered User   Join Date: Mar 2012 Location: Texas Posts: 1,611 Hey there Leo D9, thanks for creating this thread, it reminded me of something I had started but had forgotten. You might want to try WhiteBalance (recently added to the wiki ). The documentation contains some good information regarding white balance. Another suggestion is AWB (Automatic White Balance); the script is heavily commented with useful information. Hope this helps.
 10th March 2014, 09:53 #12  |  Link pandy Registered User   Join Date: Mar 2006 Posts: 1,053 My two cents is - you can do white balance in RGB space, read offsets in YUV and then repeat but only in YUV space - so do measurements in RGB but correction in YUV - should be comparable without conversions RGB<>YUV.
 10th March 2014, 18:56 #13  |  Link Bernardd Registered User   Join Date: Jan 2012 Location: Toulon France Posts: 243 Hello RaffRiff42 Your white balance observations are impressive. I agree with you. Your method is very subjective and perhaps not mathematically correct. But you show well that luma range selectivity is more important than mathematical correctness for warm colors. I have changed your script to use auto white balance function of ColorYUV and to display the different luma range outputs for warm color choice. I have not your perfect masktools knowledge. So i have keep your script part relative to mask creation and use. What you think about this fork of your process. Do you know limit of this approach ? Code: ```##Last=YUV ## From CheapColorTemp demonstration, mod auto white balance version ## stack between original and several corrections ## (view in step mode; not for real time playback) StackVertical( \StackHorizontal(last.Subtitle("original"),CheapColorTempAuto(1,0,0).Subtitle("AWB lo")), \StackHorizontal(last.Subtitle("original"),CheapColorTempAuto(0,1,0).Subtitle("AWB mid")), \ StackHorizontal(last.Subtitle("original"),CheapColorTempAuto(0,0,1).Subtitle("AWB hi")), \StackHorizontal(last.Subtitle("original"),last.ColorYuv(autowhite=true).Subtitle("AWB ColorYuv"))) return last ####################################### ### emulate color temperature changes in three luma ranges ## ## function CheapColorTempAuto(clip C, int lo_auto, int mid_auto, int hi_auto) { Assert(C.IsYUV, "CheapColorTemp: source must be YUV") lo_auto = Default(lo_auto, 0) mid_auto = Default(mid_auto, 0) hi_auto = Default(hi_auto, 0) return C.ColorYUVxAuto(lo_auto = lo_auto, mid_auto = mid_auto, hi_auto = hi_auto) } ####################################### ### apply ColorYUV autowhite to three luma ranges ## ## @ xover_x - aproximate 50% luma blend between ranges ## ( no reason to mess with this) ## @ showmasks - if true, show original + 3 masks in quad split ## function ColorYUVxAuto(clip C, \ int "lo_auto",int "mid_auto", int "hi_auto", \ float "xover_lomid", float "xover_midhi", \ bool "showmasks") { lo_auto = Default(lo_auto, 0) mid_auto = Default(mid_auto, 0) hi_auto = Default(hi_auto, 0) xlo = Min(Max( 0, Default(xover_lomid, 102)), 127) * 3.0 / 256 xhi = Min(Max(128, Default(xover_midhi, 191)), 255) * 3.0 / 256 showmasks = Default(showmasks, false) (lo_auto == 1) ? C.ColorYUV(autowhite=true) : C C_lo_auto = last (mid_auto == 1) ? C.ColorYUV(autowhite=true) : C C_mid_auto = last (hi_auto == 1) ? C.ColorYUV(autowhite=true) : C C_hi_auto = last ## mt_lutxyz too slow!! mask_lo = C.mt_lut( \ yexpr="x -0.01 * "+String(xlo)+" + 256 * ", \ u=-128, v=-128) mask_hi = C.mt_lut( \ yexpr="1 x -0.01 * "+String(xhi)+" + - 256 * ", \ u=-128, v=-128) mask_mid = mt_lutxy(mask_lo, mask_hi, "x y + -1 * 256 + ", u=-128, v=-128) return (showmasks) \ ? StackVertical( \ StackHorizontal(C, mask_lo), \ StackHorizontal(mask_mid, mask_hi)) \ .BilinearResize(C.Width, C.height) \ .Subtitle("Low", align=9) \ .Subtitle("\nMid", align=4, lsp=0) \ .Subtitle("\nHigh", align=6, lsp=0) \ : C.Overlay(C_lo_auto, mask=mask_lo) \ .Overlay(C_mid_auto, mask=mask_mid) \ .Overlay(C_hi_auto, mask=mask_hi) }```
 23rd March 2014, 18:07 #15  |  Link Bernardd Registered User   Join Date: Jan 2012 Location: Toulon France Posts: 243 Hello, After many tests, i have written this little script to enable automatic Coloryuv strength tune. For best look result and for smart tune action, i have use raffriff 42's luma ranges proposal. This script is based on AvsPmod user sliders use. Code: ```ori_chroma=last.Info_Chroma().Subtitle("original") ori_luma=last.Info_Luma().Subtitle("original") [< separator="Output choice">] [< separator=" 0 = production ">] [< separator=" 1 = Automatic White Balance tune">] [< separator=" 2 = Automatic gain tune">] choice = [<"choice", 0, 2, 2>] # ------------------------------------------------- Tones mask ------------------------------------------ LoadPlugin("C:\mt_masktools-25.dll") xlo = 62 * 3.0 / 256 xhi = 191 * 3.0 / 256 mask_lo = mt_lut( \ yexpr="x -0.01 * "+String(xlo)+" + 256 * ", \ u=-128, v=-128) mask_hi = mt_lut( \ yexpr="1 x -0.01 * "+String(xhi)+" + - 256 * ", \ u=-128, v=-128) mask_mid = mt_lutxy(mask_lo, mask_hi, "x y + -1 * 256 + ", u=-128, v=-128) #--------------------------------------------- AWB -------------------------------------- [< separator="Automatic White Balance tune">] force_AWB_lo = [<"Automatic White Balance strength on shadows tones", 0.0, 1.0, 1.0>] force_AWB_mid = [<"Automatic White Balance strength on midtones", 0.0, 1.0, 1.0>] force_AWB_hi = [<"Automatic White Balance strength on hightlights tones", 0.0, 1.0, 1.0>] awb=ColorYUV(AutoWhite=true) awb_info=awb.Info_Chroma().Subtitle("simple AWB") awb_mod=Overlay(awb, mask = mask_lo, opacity=force_AWB_lo, mode="chroma").Overlay(awb, mask = mask_mid, opacity=force_AWB_mid, mode="chroma") \.Overlay(awb, mask = mask_hi, opacity=force_AWB_hi, mode="chroma") awb_mod_info=awb_mod.Info_Chroma().Subtitle("tuned AWB") #--------------------------------------------- Autogain ------------------------------------------ [< separator="Réglage du niveau automatique de gain">] force_AWB_lo = [<"force du gain automatique tons sombres", 0.0, 1.0, 1.0>] force_AWB_mid = [<"force du gain automatique tons moyens", 0.0, 1.0, 1.0>] force_AWB_hi = [<"force du gain automatique tons clairs", 0.0, 1.0, 1.0>] autogain = awb_mod.ColorYUV(Autogain=true) autogain_info = autogain.Info_luma().Subtitle("simple autogain") autogain_mod =awb_mod.Overlay(autogain, mask = mask_lo, opacity=force_AWB_lo, mode="luma").Overlay(autogain, mask = mask_mid, opacity=force_AWB_mid, mode="luma") \.Overlay(autogain, mask = mask_hi, opacity=force_AWB_hi, mode="luma") autogain_mod_info = autogain_mod.Info_luma().Subtitle("tuned autogain") #------------------------------------------- Results (choice==1) ? StackHorizontal (ori_chroma,awb_info,awb_mod_info).Histogram("levels") : \((choice==2) ? StackHorizontal (ori_luma,autogain_info,autogain_mod_info) : autogain_mod) # ----------------------------------------Function info function Info_chroma(clip c) { c.ScriptClip(""" acu = AverageChromaU() acv = AverageChromaV() Subtitle("Average_Chroma_U = " + String(acu),y=40) Subtitle("Average_Chroma_V = " + String(acv),y=60) Subtitle("difference_U_V = " + String(acu-acv),y=80) Subtitle("moyenne_U_V = " + String((acu+acv)/2),y=100) """) return last } function Info_luma(clip c) { c.ScriptClip(""" aly = AverageLuma() Subtitle("AverageLuma = " + String(aly),y=40) """) return last }``` The purpose of this little script is to only amend automatic coloryuv use, not to amend AWB and Autogain functions.
 26th March 2014, 17:50 #16  |  Link Bernardd Registered User   Join Date: Jan 2012 Location: Toulon France Posts: 243 Hello, I use Avisynth script for old super 8 or 8 mm restoration. So i have sometimes problems with dominant color. Because for me old movies are in accordance with some faults, I do not search perfect white balance, but i search a pleasant look. So i use coloryuv auto functions, but sometimes the look is no good. Raffriff42's observation and demonstration on luma range proceeded white balance, give me idea to get more detail actions. So I have written this function to tune the Coloryuv auto functions, it request Masktools2 plugin load : Code: ```function Auto_ColorYUV_Strenght(clip clip, float "strenght_AWB_lo", float "strenght_AWB_mid", float "strenght_AWB_hi", \ float "strenght_Autogain_lo",float "strenght_Autogain_mid",float "strenght_Autogain_hi", \ bool "Show_Help_Display",bool "Show_AWB_or_Autogain_Strenght") { Assert(clip.IsYUV, "CheapColorTemp: source must be YUV") Show_Help_Display = Default(Show_Help_Display, false) Show_AWB_or_Autogain_Strenght = Default(Show_AWB_or_Autogain_Strenght, true) #--------------------------------------------- Information clip -------------------------------------------- ori=clip.Subtitle("original") ori_chroma=clip.Info_Chroma().Subtitle("original") ori_luma=clip.Info_Luma().Subtitle("original") # ------------------------------------------------- Tones mask ------------------------------------------ xlo = 62 * 3.0 / 256 xhi = 191 * 3.0 / 256 mask_lo = clip.mt_lut( \ yexpr="x -0.01 * "+String(xlo)+" + 256 * ", \ u=-128, v=-128) mask_hi = clip.mt_lut( \ yexpr="1 x -0.01 * "+String(xhi)+" + - 256 * ", \ u=-128, v=-128) mask_mid = mt_lutxy(mask_lo, mask_hi, "x y + -1 * 256 + ", u=-128, v=-128) #--------------------------------------------- AWB -------------------------------------- strenght_AWB_lo = Default(strenght_AWB_lo, 1.0) # Automatic White Balance strength on shadows tones, between 0.0 and 1.0, default 1.0 strenght_AWB_mid = Default(strenght_AWB_mid, 1.0) # Automatic White Balance strength on midtones, between 0.0 and 1.0, default 1.0 strenght_AWB_hi = Default(strenght_AWB_hi, 1.0) # Automatic White Balance strength on hightlights tones, between 0.0 and 1.0, default 1.0 awb=clip.ColorYUV(autoWhite=true) awb_info=awb.Info_Chroma().Subtitle("default AWB") awb_mod=clip.Overlay(awb, mask = mask_lo, opacity=strenght_AWB_lo, mode="chroma").Overlay(awb, mask = mask_mid, opacity=strenght_AWB_mid, mode="chroma") \.Overlay(awb, mask = mask_hi, opacity=strenght_AWB_hi, mode="chroma") awb_mod_info=awb_mod.Info_Chroma().Subtitle("Tuned AWB") #--------------------------------------------- Autogain ------------------------------------------ strenght_Autogain_lo = Default(strenght_Autogain_lo, 1.0) # Autogain strength on shadows tones, between 0.0 and 1.0, default 1.0 strenght_Autogain_mid = Default(strenght_Autogain_mid, 1.0) # Autogain strength on midtones, between 0.0 and 1.0, default 1.0 strenght_Autogain_hi = Default(strenght_Autogain_hi, 1.0) # Autogain strength on hightlights tones, between 0.0 and 1.0, default 1.0 autogain = awb_mod.ColorYUV(autogain=true) autogain_info = autogain.Info_luma().Subtitle("Default Autogain") autogain_mod =awb_mod.Overlay(autogain, mask = mask_lo, opacity=strenght_Autogain_lo, mode="luma").Overlay(autogain, mask = mask_mid, opacity=strenght_Autogain_mid, mode="luma") \.Overlay(autogain, mask = mask_hi, opacity=strenght_Autogain_hi, mode="luma") autogain_mod_info = autogain_mod.Info_luma().Subtitle("Tuned Autogain") #------------------------------------------- Results (Show_Help_Display == true) ? ((Show_AWB_or_Autogain_Strenght == true) ? StackHorizontal (ori_chroma,awb_info,awb_mod_info).Histogram("levels") : \ StackHorizontal (ori_luma,autogain_info,autogain_mod_info).Histogram("levels")) : \autogain_mod return last } # ---------------------------------------- Info functions function Info_chroma(clip c) { c.ScriptClip(""" acu = AverageChromaU() acv = AverageChromaV() Subtitle("correction U = " + String(127-acu),y=20) Subtitle("correction V = " + String(127-acv),y=40) Subtitle("moyenne_U_V = " + String((acu+acv)/2),y=60) """) return last } function Info_luma(clip c) { c.ScriptClip(""" aly = AverageLuma() Subtitle("AverageLuma = " + String(aly),y=40) """) return last }``` For best results, it is good to proceed scene by scene, but sometimes, i have found acceptable strenght values for a 3 mn long video. Last edited by Bernardd; 27th March 2014 at 09:17.
 3rd April 2014, 21:45 #17  |  Link Bernardd Registered User   Join Date: Jan 2012 Location: Toulon France Posts: 243 Hello raffriff 42 I have written this function based on your luma range script and avisynth overlay internal function opacity tune. It is like a manual RGB problem soluce way in YUV world. It is possible with it to process manual white balance. For easy test of this function, in script end, is written a function call script with AvsPmod usersliders use. Code: ```function Other_colors(clip clip, int "limit_lo", int "limit_hi", \ float "color_red_invert", float "color_green_invert", float "color_blue_invert", \ float "color_lo_red", float "color_mid_red", float "color_hi_red", \ float "color_lo_green",float "color_mid_green",float "color_hi_green", \ float "color_lo_blue",float "color_mid_blue",float "color_hi_blue", \ float "color_lo_black", float "color_mid_black", float "color_hi_black", \ float "color_lo_white", float "color_mid_white", float "color_hi_white", \ float "contrast_lo",float "contrast_mid",float "contrast_hi", \ bool "show_mask_color") { Assert(clip.IsYUV, "CheapColorTemp: source must be YUV") show_mask_color = Default(show_mask_color, false) #--------------------------------------------- Masks making ---------------------------------------- limit_lo = Default(limit_lo, 62) # seuil bas between in 0 et 190, valeur par default 62 limit_hi = Default(limit_hi, 191) # seuil bas between in 191 et 255, valeur par default 191 xlo_color = limit_lo * 3.0 / 256 xhi_color = limit_hi * 3.0 / 256 mask_lo_color mt_lut(clip, \ yexpr="x -0.01 * "+String(xlo_color)+" + 256 * ", \ u=-128, v=-128) mask_hi_color mt_lut(clip, \ yexpr="1 x -0.01 * "+String(xhi_color)+" + - 256 * ", \ u=-128, v=-128) mask_mid_color = (mask_version == 0) ? mt_lutxy(mask_lo_color, mask_hi_color, "x y + -1 * 256 + ", u=-128, v=-128) control_mask = StackHorizontal(mask_lo_color.Subtitle("mask lo"),mask_mid_color.Subtitle("mask mid"),mask_hi_color.Subtitle("mask hi")) #-------------------------------------------- Add colors tuning color_red_invert = Default(color_red_invert, 0.0) # percentage between red color and her invert color color_lo_red = Default(color_lo_red, 0.0) # red add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_red = Default(color_mid_red, 0.0) # red add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_red = Default(color_hi_red, 0.0) # red add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_green_invert = Default(color_green_invert, 0.0) # percentage between green color and her invert color color_lo_green = Default(color_lo_green, 0.0) # green add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_green = Default(color_mid_green, 0.0) # green add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_green = Default(color_hi_green, 0.0) # green add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_blue_invert = Default(color_blue_invert, 0.0) # percentage between blue color and her invert color color_lo_blue = Default(color_lo_blue, 0.0) # blue add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_blue = Default(color_mid_blue, 0.0) # blue add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_blue = Default(color_hi_blue, 0.0) # blue add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_red = Overlay(BlankClip(clip , color=\$FF0000), BlankClip(clip , color=\$FF0000).invert, opacity = color_red_invert, mode = "Chroma") color_green = Overlay(BlankClip(clip , color=\$00FF00), BlankClip(clip , color=\$00FF00).invert, opacity = color_green_invert, mode = "Chroma") color_blue = Overlay(BlankClip(clip , color=\$0000FF), BlankClip(clip , color=\$0000FF).invert, opacity = color_blue_invert, mode = "Chroma") #-------------------------------------------- Luma tunning color_lo_black = Default(color_lo_black, 0.0) #black add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_black = Default(color_mid_black, 0.0) # black add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_black = Default(color_hi_black, 0.0) # black add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_lo_white = Default(color_lo_white, 0.0) # white add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_white = Default(color_mid_white, 0.0) # white add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_white = Default(color_hi_white, 0.0) # white add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_black = BlankClip(clip , color=\$000000) color_white = BlankClip(clip , color=\$FFFFFF) color_sup = clip.Overlay(color_green, mask = mask_lo_color, opacity=color_lo_green, mode="chroma",greymask=true).Overlay(color_green, mask = mask_mid_color, opacity=color_mid_green, mode="chroma",greymask=true) \.Overlay(color_green, mask = mask_hi_color, opacity=color_hi_green, mode="chroma",greymask=true). \Overlay(color_red, mask = mask_lo_color, opacity=color_lo_red, mode="chroma",greymask=true).Overlay(color_red, mask = mask_mid_color, opacity=color_mid_red, mode="chroma",greymask=true) \.Overlay(color_red, mask = mask_hi_color, opacity=color_hi_red, mode="chroma",greymask=true). \Overlay(color_blue, mask = mask_lo_color, opacity=color_lo_blue, mode="chroma",greymask=true).Overlay(color_blue, mask = mask_mid_color, opacity=color_mid_blue, mode="chroma",greymask=true) \.Overlay(color_blue, mask = mask_hi_color, opacity=color_hi_blue, mode="chroma",greymask=true). \Overlay(color_black, mask = mask_lo_color, opacity=color_lo_black, mode="luma",greymask=true).Overlay(color_black, mask = mask_mid_color, opacity=color_mid_black, mode="luma",greymask=true) \.Overlay(color_black, mask = mask_hi_color, opacity=color_hi_black, mode="luma",greymask=true). \Overlay(color_white, mask = mask_lo_color, opacity=color_lo_white, mode="luma",greymask=true).Overlay(color_white, mask = mask_mid_color, opacity=color_mid_white, mode="luma",greymask=true) \.Overlay(color_white, mask = mask_hi_color, opacity=color_hi_white, mode="luma",greymask=true) # ------------------------------------------ contrast contrast_lo = Default(contrast_lo, 0.0) # contrast percentage in shadows toness, between in 0.0, 1.0, default 0.0 contrast_mid = Default(contrast_mid, 0.0) # contrast percentage in midtones, between in 0.0, 1.0, default 0.0 contrast_hi = Default(contrast_hi, 0.0) # contrast percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_contr = color_sup.Overlay(color_sup, mask = mask_lo_color, opacity=contrast_lo, mode="add").Overlay(color_sup, mask = mask_mid_color, opacity=contrast_mid, mode="add") \.Overlay(color_sup, mask = mask_hi_color, opacity=contrast_hi, mode="add") #------------------------------------------- Results (show_mask_color == true) ? control_mask : color_contr return last } __END__ # paths to be customised Source # Your source LoadPlugin("C:\...........\mt_masktools-25.dll") Import("C:\..........\Add colors function.avs ") # If you have saved this function script with this file name [color addition=1] [< separator="Add color tuning">] show = [<"Show tones masks (no = 0 et yes = 1)", 0, 1, 0>] show_mask_color = (show == 1) ? true : false [< separator="Mask tuning">] limit_lo=[<"limit_lo", 0, 190, 62>] limit_hi=[<"limit_hi", 191, 255, 191>] [< separator="Add colors percentage tuning ">] [< separator=" red addition">] color_red_invert = [<"percentage between red color and her invert color", 0.0, 1.0, 0.0>] color_lo_red = [<"red add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_red = [<"red add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_red = [<"red add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator=" green addition">] color_green_invert = [<"percentage between green color and her invert color", 0.0, 1.0, 0.0>] color_lo_green = [<"green add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_green = [<"green add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_green = [<"green add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator=" blue addition">] color_blue_invert = [<"percentage between blue color and her invert color", 0.0, 1.0, 0.0>] color_lo_blue = [<"blue add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_blue = [<"blue add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_blue = [<"blue add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator="Luma tuning">] [< separator="More dark">] color_lo_black = [<"black add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_black = [<"black add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_black = [<"black add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator="More light">] color_lo_white = [<"white add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_white = [<"white add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_white = [<"white add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator="Contrast tuning">] contrast_lo = [<"contrast add percentage in shadows tones", 0.0, 1.0, 0.0>] contrast_mid = [<"contrast add percentage in midtones", 0.0, 1.0, 0.0>] contrast_hi = [<"contrast add percentage in highlights tones", 0.0, 1.0, 0.0>] Assert(isclip, "No defined source") # Line to be deleted if you have gived a variable name for the clip Other_colors(limit_lo = limit_lo, limit_hi = limit_hi, \color_red_invert = color_red_invert, color_green_invert = color_green_invert, color_blue_invert = color_blue_invert, \color_lo_red = color_lo_red, color_mid_red = color_mid_red, color_hi_red = color_hi_red, \color_lo_green = color_lo_green, color_mid_green = color_mid_green, color_hi_green = color_hi_green, \color_lo_blue = color_lo_blue, color_mid_blue = color_mid_blue, color_hi_blue = color_hi_blue, \color_lo_black = color_lo_black, color_mid_black = color_mid_black, color_hi_black = color_hi_black, \color_lo_white = color_lo_white, color_mid_white = color_mid_white, color_hi_white = color_hi_white, \contrast_lo = contrast_lo, contrast_mid =contrast_mid, contrast_hi = contrast_hi, \show_mask_color = show_mask_color) [/color addition]``` I think that i should get more accuracy with more luma range zones. But i do not know write masktools formulas for this. Thus i have put in beginng two variable values for enable little mask making modifications. What do you think of this trial, is it in accordance with yours observations ? Thanks
 4th April 2014, 14:19 #18  |  Link raffriff42 Retried Guesser     Join Date: Jun 2012 Posts: 1,373 Hello Bernardd, I'm not sure what this script should be doing, as I am not familiar with AvsPmod scripts. I got an error (expected ':') when attempting to preview the script and had to make a change: Code: ```mask_mid_color = /*(mask_version == 0) ? */ \ mt_lutxy(mask_lo_color, mask_hi_color, "x y + -1 * 256 + ", u=-128, v=-128)``` Also, should there be "=" here? Code: ```mask_lo_color /* = */ mt_lut(clip, \ yexpr="x -0.01 * "+String(xlo_color)+" + 256 * ", \ u=-128, v=-128) mask_hi_color /* = */ mt_lut(clip, \ yexpr="1 x -0.01 * "+String(xhi_color)+" + - 256 * ", \ u=-128, v=-128)``` I didn't see any sliders, but again, I'm not too familiar with the program. As far as customizing the lut equations, maybe this speadsheet will help. It should probably have a term for width at peak gain, but I must leave it for later: Last edited by raffriff42; 18th March 2017 at 00:53. Reason: (fixed image link)
 4th April 2014, 21:39 #19  |  Link Bernardd Registered User   Join Date: Jan 2012 Location: Toulon France Posts: 243 Hello RaffRiff42, I apologize, i have too fast cut trial masks input, thus the script has not been good. You have well find the mistakes. The good version is below : Code: ```function Other_colors(clip clip, int "limit_lo", int "limit_hi", \ float "color_red_invert", float "color_green_invert", float "color_blue_invert", \ float "color_lo_red", float "color_mid_red", float "color_hi_red", \ float "color_lo_green",float "color_mid_green",float "color_hi_green", \ float "color_lo_blue",float "color_mid_blue",float "color_hi_blue", \ float "color_lo_black", float "color_mid_black", float "color_hi_black", \ float "color_lo_white", float "color_mid_white", float "color_hi_white", \ float "contrast_lo",float "contrast_mid",float "contrast_hi", \ bool "show_mask_color") { Assert(clip.IsYUV, "CheapColorTemp: source must be YUV") show_mask_color = Default(show_mask_color, false) #--------------------------------------------- Masks making ---------------------------------------- limit_lo = Default(limit_lo, 62) # seuil bas between in 0 et 190, valeur par default 62 limit_hi = Default(limit_hi, 191) # seuil bas between in 191 et 255, valeur par default 191 xlo_color = limit_lo * 3.0 / 256 xhi_color = limit_hi * 3.0 / 256 mask_lo_color = mt_lut(clip, \ yexpr="x -0.01 * "+String(xlo_color)+" + 256 * ", \ u=-128, v=-128) mask_hi_color = mt_lut(clip, \ yexpr="1 x -0.01 * "+String(xhi_color)+" + - 256 * ", \ u=-128, v=-128) mask_mid_color = mt_lutxy(mask_lo_color, mask_hi_color, "x y + -1 * 256 + ", u=-128, v=-128) control_mask = StackHorizontal(mask_lo_color.Subtitle("mask lo"),mask_mid_color.Subtitle("mask mid"),mask_hi_color.Subtitle("mask hi")) #-------------------------------------------- Add colors tuning color_red_invert = Default(color_red_invert, 0.0) # percentage between red color and her invert color color_lo_red = Default(color_lo_red, 0.0) # red add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_red = Default(color_mid_red, 0.0) # red add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_red = Default(color_hi_red, 0.0) # red add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_green_invert = Default(color_green_invert, 0.0) # percentage between green color and her invert color color_lo_green = Default(color_lo_green, 0.0) # green add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_green = Default(color_mid_green, 0.0) # green add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_green = Default(color_hi_green, 0.0) # green add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_blue_invert = Default(color_blue_invert, 0.0) # percentage between blue color and her invert color color_lo_blue = Default(color_lo_blue, 0.0) # blue add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_blue = Default(color_mid_blue, 0.0) # blue add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_blue = Default(color_hi_blue, 0.0) # blue add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_red = Overlay(BlankClip(clip , color=\$FF0000), BlankClip(clip , color=\$FF0000).invert, opacity = color_red_invert, mode = "Chroma") color_green = Overlay(BlankClip(clip , color=\$00FF00), BlankClip(clip , color=\$00FF00).invert, opacity = color_green_invert, mode = "Chroma") color_blue = Overlay(BlankClip(clip , color=\$0000FF), BlankClip(clip , color=\$0000FF).invert, opacity = color_blue_invert, mode = "Chroma") #-------------------------------------------- Luma tunning color_lo_black = Default(color_lo_black, 0.0) #black add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_black = Default(color_mid_black, 0.0) # black add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_black = Default(color_hi_black, 0.0) # black add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_lo_white = Default(color_lo_white, 0.0) # white add percentage in shadows toness, between in 0.0, 1.0, default 0.0 color_mid_white = Default(color_mid_white, 0.0) # white add percentage in midtones, between in 0.0, 1.0, default 0.0 color_hi_white = Default(color_hi_white, 0.0) # white add percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_black = BlankClip(clip , color=\$000000) color_white = BlankClip(clip , color=\$FFFFFF) color_sup = clip.Overlay(color_green, mask = mask_lo_color, opacity=color_lo_green, mode="chroma",greymask=true).Overlay(color_green, mask = mask_mid_color, opacity=color_mid_green, mode="chroma",greymask=true) \.Overlay(color_green, mask = mask_hi_color, opacity=color_hi_green, mode="chroma",greymask=true). \Overlay(color_red, mask = mask_lo_color, opacity=color_lo_red, mode="chroma",greymask=true).Overlay(color_red, mask = mask_mid_color, opacity=color_mid_red, mode="chroma",greymask=true) \.Overlay(color_red, mask = mask_hi_color, opacity=color_hi_red, mode="chroma",greymask=true). \Overlay(color_blue, mask = mask_lo_color, opacity=color_lo_blue, mode="chroma",greymask=true).Overlay(color_blue, mask = mask_mid_color, opacity=color_mid_blue, mode="chroma",greymask=true) \.Overlay(color_blue, mask = mask_hi_color, opacity=color_hi_blue, mode="chroma",greymask=true). \Overlay(color_black, mask = mask_lo_color, opacity=color_lo_black, mode="luma",greymask=true).Overlay(color_black, mask = mask_mid_color, opacity=color_mid_black, mode="luma",greymask=true) \.Overlay(color_black, mask = mask_hi_color, opacity=color_hi_black, mode="luma",greymask=true). \Overlay(color_white, mask = mask_lo_color, opacity=color_lo_white, mode="luma",greymask=true).Overlay(color_white, mask = mask_mid_color, opacity=color_mid_white, mode="luma",greymask=true) \.Overlay(color_white, mask = mask_hi_color, opacity=color_hi_white, mode="luma",greymask=true) # ------------------------------------------ contrast contrast_lo = Default(contrast_lo, 0.0) # contrast percentage in shadows toness, between in 0.0, 1.0, default 0.0 contrast_mid = Default(contrast_mid, 0.0) # contrast percentage in midtones, between in 0.0, 1.0, default 0.0 contrast_hi = Default(contrast_hi, 0.0) # contrast percentage in highlights tones, between in 0.0, 1.0, default 0.0 color_contr = color_sup.Overlay(color_sup, mask = mask_lo_color, opacity=contrast_lo, mode="add").Overlay(color_sup, mask = mask_mid_color, opacity=contrast_mid, mode="add") \.Overlay(color_sup, mask = mask_hi_color, opacity=contrast_hi, mode="add") #------------------------------------------- Results (show_mask_color == true) ? control_mask : color_contr return last } __END__ # paths to be customised Source # Your source LoadPlugin("C:\...........\mt_masktools-25.dll") Import("C:\..........\Add colors function.avs ") # If you have saved this function script with this file name [color addition=1] [< separator="Add color tuning">] show = [<"Show tones masks (no = 0 et yes = 1)", 0, 1, 0>] show_mask_color = (show == 1) ? true : false [< separator="Mask tuning">] limit_lo=[<"limit_lo", 0, 190, 62>] limit_hi=[<"limit_hi", 191, 255, 191>] [< separator="Add colors percentage tuning ">] [< separator=" red addition">] color_red_invert = [<"percentage between red color and her invert color", 0.0, 1.0, 0.0>] color_lo_red = [<"red add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_red = [<"red add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_red = [<"red add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator=" green addition">] color_green_invert = [<"percentage between green color and her invert color", 0.0, 1.0, 0.0>] color_lo_green = [<"green add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_green = [<"green add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_green = [<"green add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator=" blue addition">] color_blue_invert = [<"percentage between blue color and her invert color", 0.0, 1.0, 0.0>] color_lo_blue = [<"blue add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_blue = [<"blue add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_blue = [<"blue add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator="Luma tuning">] [< separator="More dark">] color_lo_black = [<"black add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_black = [<"black add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_black = [<"black add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator="More light">] color_lo_white = [<"white add percentage in shadows tones", 0.0, 1.0, 0.0>] color_mid_white = [<"white add percentage in midtones", 0.0, 1.0, 0.0>] color_hi_white = [<"white add percentage in highlights tones", 0.0, 1.0, 0.0>] [< separator="Contrast tuning">] contrast_lo = [<"contrast add percentage in shadows tones", 0.0, 1.0, 0.0>] contrast_mid = [<"contrast add percentage in midtones", 0.0, 1.0, 0.0>] contrast_hi = [<"contrast add percentage in highlights tones", 0.0, 1.0, 0.0>] Assert(isclip, "No defined source") # Line to be deleted if you have gived a variable name for the clip Other_colors(limit_lo = limit_lo, limit_hi = limit_hi, \color_red_invert = color_red_invert, color_green_invert = color_green_invert, color_blue_invert = color_blue_invert, \color_lo_red = color_lo_red, color_mid_red = color_mid_red, color_hi_red = color_hi_red, \color_lo_green = color_lo_green, color_mid_green = color_mid_green, color_hi_green = color_hi_green, \color_lo_blue = color_lo_blue, color_mid_blue = color_mid_blue, color_hi_blue = color_hi_blue, \color_lo_black = color_lo_black, color_mid_black = color_mid_black, color_hi_black = color_hi_black, \color_lo_white = color_lo_white, color_mid_white = color_mid_white, color_hi_white = color_hi_white, \contrast_lo = contrast_lo, contrast_mid =contrast_mid, contrast_hi = contrast_hi, \show_mask_color = show_mask_color) [/color addition]``` The script aim is to overlay red, green, blue or their invert color screens to video and to search good result by tuning the overlay opacity. Whitout AvsPmod UserSliders this script is not fun to use. Thanks for the curves, i study them.
 5th April 2014, 01:55 #20  |  Link raffriff42 Retried Guesser     Join Date: Jun 2012 Posts: 1,373 OK here is a better set of curves, I think. Here is the new spreadsheet. The spreadsheet formula is: Code: `MIN(MAX(0; (1+((WIDTH_2/512)*(256/RAMP_2)))-((ABS(A8-CENTER_2)/256)*(256/RAMP_2))); 1)` It translates to Avisynth with the following code: Code: ```ImageSource("Grayscale_816x72.png", fps=30) TurnRight Lanczos4Resize(56, 450) ConvertToYV12(matrix="PC.709") a_ctr = 128 a_rmp = 80 a_wid = 60 s1 = ("x * min(max((1+((\$w/512)*(256/\$r)))-((abs(x-\$c)/256)*(256/\$r)), 0), 1)") \ .StrReplace("\$c", String(a_ctr)) \ .StrReplace("\$r", String(a_rmp)) \ .StrReplace("\$w", String(a_wid)) \ .mt_polish mt_lut(yexpr=s1) return Last.Histogram function StrReplace(string base, string findstr, string repstr) { pos = FindStr(base, findstr) return (StrLen(findstr)==0) || (pos==0) \ ? base \ : StrReplace( \ LeftStr(base, pos-1) + repstr + \ MidStr(base, pos+StrLen(findstr)), \ findstr, repstr) }``` which gives you (before & after) (image source) (EDIT looks like there is a gamma effect happening here; fixing it is left as an exercise for the reader) A final point: I am pretty sure you want the gain of all the curves to add up to unity at all input levels. This was done in my previous script by defining mid range as a difference: mid = input - (low+high). Last edited by raffriff42; 18th March 2017 at 00:52. Reason: (fixed image links)

 Tags colour temperature, manual white balance, rgb, white balance, yuv