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. |
3rd March 2014, 02:25 | #1 | Link |
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 |
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 |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,433
|
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]. Last edited by Gavino; 3rd March 2014 at 12:45. |
4th March 2014, 06:33 | #4 | Link |
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 | ||
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,433
|
Quote:
Quote:
|
||
5th March 2014, 06:32 | #6 | Link |
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) |
7th March 2014, 07:53 | #7 | Link |
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, 18:54 | #8 | Link |
Registered User
Join Date: Feb 2013
Posts: 10
|
Thanks raffriff42. I was hoping someone would just "know" the "right" answer/solution, but I see you've gone to a lot of effort to produce something usable from scratch! I'll have to give it a go when I get a moment. I've never used MaskTools but I think I roughly understand what's going on in the code - are you basically leaving the Y channel alone and applying a curve to the U channel and a separate curve to the V channel? Each curve is defined by three numbers. Because of the 50% cross-over this means each curve is essentially made up of 5 straight lines. Correct?
If luma stays pretty much the same as you say this sounds like a good solution for "black body" light sources, but what about green-magenta shift (such as for the green cast produced by fluorescent lights)? (As the Wikipedia article mentions: ...ineffective with sources such as fluorescent or discharge lamps, whose light varies in colour and may be harder to correct for. Because it is often greenish, a magenta filter may correct it. More sophisticated colorimetry tools can be used...) How did you come to use gamma 1.8? I followed the link for the animated GIF you used, which is apparently based on sRGB, using the table of RGB values for colour temperature listed here: http://www.vendian.org/mncharity/dir3/blackbody/ So sRGB would be RGB levels 0-255 using Rec.709 colour primaries. Wikipedia says: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value. The overall gamma is approximately 2.2, consisting of a linear (gamma 1.0) section near black, and a non-linear section elsewhere involving a 2.4 exponent and a gamma (slope of log output versus log input) changing from 1.0 through about 2.3. Also, I wonder what effect matrix Rec.709 vs Rec.601 has on your system. I was kinda hoping there would be a simple solution that doesn't require plugins. I had thought of doing something similar to your MaskTools code using Levels() multiple times to select lows, mids and highs, scale or adjust them, then re-combine with Layer() (using op="lighten" or op="darken") or possibly Merge(). Very useful to know if/that the luma doesn't need changing. I wonder if it "makes sense" to use your system rather than converting to RGB and back. Using MaskTools, masks and three Overlay() calls would presumably be slower than YUV-RGB-YUV conversions and channel scaling, and I think green-magenta shift may be easer to correct in RGB. But correct colour temperature adjustment in RGB may be complex too. It's quite nice if the luma channel doesn't need to be tampered with in YUV. Thanks again. Last edited by Leo D9; 7th March 2014 at 18:57. |
7th March 2014, 21:09 | #9 | Link | |
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:
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)) Last edited by raffriff42; 7th March 2014 at 21:50. Reason: vectorscope, code |
|
8th March 2014, 19:54 | #10 | Link |
Registered User
Join Date: Mar 2012
Location: Texas
Posts: 1,671
|
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 | #11 | Link |
Registered User
Join Date: Mar 2006
Posts: 1,049
|
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 | #12 | Link |
Registered User
Join Date: Jan 2012
Location: Toulon France
Posts: 251
|
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) } |
10th March 2014, 20:21 | #13 | Link |
Retried Guesser
Join Date: Jun 2012
Posts: 1,373
|
Bernardd, thank you very much for taking the time to thoroughly read my post. I'm so glad you can find some agreement with my thoughts on this.
Re: your fork, it is very welcome as far as I'm concerned. I have to say though: I have never used any "auto" color balance script, as I fear they will try to correct things that don't need correction -- forcing a blue sky to white is one example mentioned in the wiki. I prefer to balance the colors manually for each shot (as I said above, over-simplifying, "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.") Of course, everyone's needs are different, and auto mode may be just the thing for certain situations - for example, I suppose it must be very helpful for repairing home movies where the camera operator had no concept of color temperature. For an extreme illustration of the problems with auto white balance , take this shot from a video game, which is supposed to portray the golden light of early morning on the Côte d'Azur (in your part of the world?) If corrections like these are to be made (I'm not saying they are necessarily bad), I would prefer to have some kind of manual override: Last edited by raffriff42; 18th March 2017 at 00:59. Reason: (fixed image links) |
23rd March 2014, 18:07 | #14 | Link |
Registered User
Join Date: Jan 2012
Location: Toulon France
Posts: 251
|
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 } |
26th March 2014, 17:50 | #15 | Link |
Registered User
Join Date: Jan 2012
Location: Toulon France
Posts: 251
|
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 } Last edited by Bernardd; 27th March 2014 at 09:17. |
3rd April 2014, 21:45 | #16 | Link |
Registered User
Join Date: Jan 2012
Location: Toulon France
Posts: 251
|
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] 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 | #17 | Link |
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) 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) 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 | #18 | Link |
Registered User
Join Date: Jan 2012
Location: Toulon France
Posts: 251
|
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] Thanks for the curves, i study them. |
5th April 2014, 01:55 | #19 | Link |
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) 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) } (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 |
Thread Tools | Search this Thread |
Display Modes | |
|
|