View Full Version : ShowChannels() v0.09 - 15 Jan 2019
StainlessS
16th January 2012, 18:29
ShowChannels(), (c) 2012/2019 StainlessS,
Requires VS2008 CPP runtimes.
Plugins for Avisynth v2.5 & v2.6, x86 & x64
Planar, YUY2 and RGB.
v0.0, 1st public release.
v0.1, 16 Jan 2012, better formatting, added MinPerc/MaxPerc args.
v0.2, 15 Sept 2012, Fixed RGB offset bug.
v0.3beta, 7 Oct 2012, Added Setvar stuff
v0.4, 15 Oct 2012, Added AccFile
v0.5, 31 Oct 2012, Added x,y,w,h coords, not colorspace restricted (real pain in the bum to implement).
Can use odd coords for eg YV12, and even sample a single pixel.
v0.6, 05 Dec 2012. Added Interlaced arg for Planar only. Now gets correct chroma for planar interlaced , even down to single pixel.
v0.7, 20 Apr 2013, Added Compile for v2.6 stuff.
v0.8, 30 Mar 2015, v2.6 dll compile with Avisynth Version 6 Header.
v0.9, 15 Jan 2019, Moved to VS2008, Added version resource + x64.
ShowChannels(), (c) 2012/2019 StainlessS, https://forum.doom9.org/showthread.php?t=163829
Requires VS2008 CPP runtimes.
Plugins for Avisynth v2.5 & v2.6, x86 & x64
Planar, YUY2 and RGB.
Simple plugin whose only function is to display the average Y,U and V
values for a YUV frame or R,G, and B for an RGB frame.
Also shows accumulated average for all frames visited so far.
Typical output for a YUV clip:-
---------------------------
347 ] Frames Visited = 348
This Frame Accumulated
Y U V Y U V
Ave 77.00 125.52 125.42 70.91 125.87 125.78
Min 4 80 95 0 69 83
Max 255 177 165 255 190 174
~Min 14 95 101 12 92 101
~Max 234 167 148 235 167 151
---------------------------
where
'AVE' shows average for current frame and accumulated average for all visited frames.
'MIN' shows minimum value for a channel, this frame and accumulated.
'MAX' shows maximum value for a channel, this frame and accumulated.
'~MIN' shows loose minimum value for a channel, this frame and accumulated.
'~MAX' shows loose maximum value for a channel, this frame and accumulated.
Loose minimum uses the filter arg float MinPerc, a percentage of total pixels to ignore
when finding the loose minimum, allows to ignore extreme stray pixels (noise).
Loose maximum uses the filter arg float MaxPerc, a percentage of total pixels to ignore
when finding the loose maximum, allows to ignore extreme stray pixels (noise).
The "loose" values are made to filter out very bright
or very dark noise creating an artificially low or high minimum / maximum.
The Accumulated Ave is a "Average of Averages", or "Average Mean" or "Mean Average", take your pick but accumulated seemed more appropriate
considering that it was not restricted to describing just the averages. Accumulated Min is the minimum of all minimums so far, etc.
Usage:-
ShowChannels(clip c,float "MinPerc"=0.1, float "MaxPerc"=0.1, bool "ver"=false,bool "Setvar"=false,String "Prefix"="SC_", \
bool "Show"=true,String ="AccFile"="",int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "Interlaced"=false)
Where:-
c is the clip
MinPerc is percentage of pixels to ignore for loose minimum. (default 0.1%, ie 1/1000 of total pixels)
ColorYUV (Analyze=true) Loose Minimum ignores 1/256 of the darkest pixels, and ShowChannels 0.1% or 1/1000 by default,
so a Minperc of 0.4% would be about the same as ColorYUV uses.
MaxPerc is percentage of pixels to ignore for loose maximum. (default 0.1%, ie 1/1000 of total pixels)
ColorYUV (Analyze=true) Loose Maximum ignores 1/256 of the lightest pixels, and ShowChannels 0.1% or 1/1000 by default,
so a Maxperc of 0.4% would be about the same as ColorYUV uses.
ver display version info, false OFF [default] , true ON
Setvar if true then sets Global Variables using Prefix string.
Prefix (default "SC_"), prefix to Global variable names when using SetVar.
Show, false switches off normal text display, you may want to set false if using SetVar.
AccFile, default "", name of text file to output final Accumulated values for entire file.
x,y,w,h, sets coordinates, all default to 0 as for crop, ie full image. NOT colorspace limited, eg can use odd values
even for YV12 and YUY2.
Interlaced (default false). Planar formats only, alters interpretation for the chroma, false=Progressive, true=interlaced.
Default Global variable names when SetVar=true and using Default Prefix = "SC_"
"SC_Visited" = Frames visited
Channel 0 (Y or R)
"SC_Ave_0","SC_Min_0","SC_Max_0","SC_LMn_0","SC_LMx_0","SC_AAve_0","SC_AMin_0","SC_AMax_0","SC_ALMn_0","SC_ALMx_0",
Channel 1 (U or G, NOT Y8)
"SC_Ave_1","SC_Min_1","SC_Max_1","SC_LMn_1","SC_LMx_1","SC_AAve_1","SC_AMin_1","SC_AMax_1","SC_ALMn_1","SC_ALMx_1",
Channel 2 (V or B, NOT Y8)
"SC_Ave_2","SC_Min_2","SC_Max_2","SC_LMn_2","SC_LMx_2","SC_AAve_2","SC_AMin_2","SC_AMax_2","SC_ALMn_2","SC_ALMx_2",
For Y8, channels 1 and 2 will all be set to -1
--------------------------------------------------------------------------------
Typical Global Variable settings for RGB something like:-
SC_Ave_0=124.55 SC_Ave_1=126.06 SC_Ave_2=199.77
SC_Min_0=0 SC_Min_1=0 SC_Min_2=0
SC_Max_0=255 SC_Max_1=255 SC_Max_2=255
SC_LMn_0=0 SC_LMn_1=0 SC_LMn_2=0
SC_LMx_0=255 SC_LMx_1=255 SC_LMx_2=255
SC_AAve_0=129.24 SC_AAve_1=132.12 SC_AAve_2=126.68
SC_AMin_0=0 SC_AMin_1=0 SC_AMin_2=0
SC_AMax_0=255 SC_AMax_1=255 SC_AMax_2=255
SC_ALMn_0=0 SC_ALMn_1=0 SC_ALMn_2=0
SC_ALMx_0=255 SC_ALMx_1=255 SC_ALMx_2=255
--------------------------------------------------------------------------------
Contents of AccFile for a small sample clip showing typical output using defaults:
SC_AAve_0=98.971779 SC_AMin_0=0 SC_AMax_0=255 SC_ALMn_0=14 SC_ALMx_0=241
SC_AAve_1=122.572746 SC_AMin_1=66 SC_AMax_1=200 SC_ALMn_1=99 SC_ALMx_1=160
SC_AAve_2=137.286911 SC_AMin_2=72 SC_AMax_2=209 SC_ALMn_2=108 SC_ALMx_2=175
SC_Visited=4000
--------------------------------------------------------------------------------
Lastly, you may find it better to crop off any borders when ascertaining frame/accumulated values, or set coordinates to suit.
ssS
Available from Mediafire via below sig:-
Zip includes 3 dll's, + source + full VS2008 project files for easy rebuild. (~128KB)
EDIT:
AviSource("D:\Parade.avi")
Showchannels(ver=True)
https://i.postimg.cc/ts5LkGhK/Show-Channels.jpg (https://postimg.cc/ts5LkGhK)
StainlessS
15th September 2012, 10:09
New Version ShowChannels v0.2, Fixed RGB Offset Bug.
jmac698
20th September 2012, 00:57
I'd like to use the values programmaticly.
StainlessS
20th September 2012, 14:15
From this thread (1st post):-
http://forum.doom9.org/showthread.php?t=165479
# Requires GScript and ShowChannels plugins.
AviSource("D:\avs\avi\1.avi").trim(0,0999)
Sum = 0.0
SumHi=0.0 # Hi part Extra precision (need for long scans)
SumLo=0.0 # Lo part Extra precision
GScript("""
for(n=0,FrameCount()-1) {
Tmp = RT_AverageLuma(n)
RT_Debug("RT_Debug:","["+String(n)+"]","AveLuma = "+String(Tmp)) # Real Time Debug Info using DebugView
# Sum = Sum + Tmp # Were gonna use extra precision instead
SumLo = SumLo + Tmp
SumHi = SumHi + floor(SumLo / 256.0) # Hi part, Extra Precision
SumLo = frac(SumLo / 256.0) * 256.0 # Lo part, Extra Precision
}
""")
# Sum=Sum/Float(FrameCount()) # Were gonna use extra precision instead
Sum = (SumHi / Float(FrameCount()) * 256.0) + (SumLo / Float(FrameCount()))
s=ShowChannels(ver=true) # Show eg Ave Luma for frame and Accumulated Ave luma for all frames visited
s.Subtitle(String(Sum),Align=1)
# The sum variable shown on bottom left via Subtitle, is the accumulated Average Luma for entire clip, will be valid on the LAST FRAME.
# ShowChannels used for result comparison.
The extra precision is recommended, although you might want to use the Avisynth built in runtime funcs (if Planar only).
EDIT: the only other sensible way would I think be use env->invoke() in plugin to set some Global vars
in the scripts, but some thought might be needed in the naming of the global vars, ie
YUV current and Accumulated, RGB same and Y same in Y8. Maybe use channel numbers rather than eg "Y" or "R"
and take care over Y8.
You have the source, should not be too hard to figure out the invoke thing. (I've never used invoke but there are several
threads in development on using it).
EDIT: Sorry, I'm a bit otherwise involved at the moment.
IanB
20th September 2012, 22:55
You don't need to env>Invoke() for vars, just env->SetGlobalVar()
StainlessS
21st September 2012, 09:00
Thankyou Mr B, musta been half asleep.
@Jmac,
OK, I've got a hour or so, I will I think use SetVar, using a user selected name prefix
defaulting to eg "SC_", resulting eg "SC_Ave_" & "SC_AAve_" [Accumulated] and appending "0=x" where x is return value for
channel 0 (Y=R=0,U=G=1,V=B=2). Unused values in Y8 will be given a value of -1.
Typical return for RGB something like:-
SC_Ave_0=124.55 SC_Ave_1=126.06 SC_Ave_2=199.77
SC_Min_0=0 SC_Min_1=0 SC_Min_2=0
SC_Max_0=255 SC_Max_1=255 SC_Max_2=255
SC_LMn_0=0 SC_LMn_1=0 SC_LMn_2=0
SC_LMx_0=255 SC_LMx_1=255 SC_LMx_2=255
SC_AAve_0=129.24 SC_AAve_1=132.12 SC_AAve_2=126.68
SC_AMin_0=0 SC_AMin_1=0 SC_AMin_2=0
SC_AMax_0=255 SC_AMax_1=255 SC_AMax_2=255
SC_ALMn_0=0 SC_ALMn_1=0 SC_ALMn_2=0
SC_ALMx_0=255 SC_ALMx_1=255 SC_ALMx_2=255
Also, see here for some nice work in wiki by Wilbert on CPP interface:-
http://avisynth.org/mediawiki/index.php?title=Cplusplus_API
http://avisynth.org/mediawiki/index.php?title=Cplusplus_API/VideoInfo
StainlessS
7th October 2012, 16:08
Jmac,
Here is beta (source incl), dont know if implemented correctly as no idea how SetGlobalVar should be called (env->SaveString)
but seems to be alright, give it a go, temporary link here:
EDIT: LINK REMOVED. See 1st post.
EDIT: Used env->SaveString for variable names in constructor only.
EDIT: You can ignore the beta status, env->SaveString is used correctly.
ShowChannels() v0.3beta
(c) 2012 StainlessS
Plugin for Avisynth 2.5
Planar, YUY2 and RGB.
Simple plugin whose only function is to display the average Y,U and V
values for a YUV frame or R,G, and B for an RGB frame.
Also shows accumulated average for all frames visited so far.
Typical output for a YUV clip:-
---------------------------
347 ] Frames Visited = 348
This Frame Accumulated
Y U V Y U V
Ave 77.00 125.52 125.42 70.91 125.87 125.78
Min 4 80 95 0 69 83
Max 255 177 165 255 190 174
~Min 14 95 101 12 92 101
~Max 234 167 148 235 167 151
---------------------------
where
'AVE' shows average for current frame and accumulated average for all visited frames.
'MIN' shows minimum value for a channel, this frame and accumulated.
'MAX' shows maximum value for a channel, this frame and accumulated.
'~MIN' shows loose minimum value for a channel, this frame and accumulated.
'~MAX' shows loose maximum value for a channel, this frame and accumulated.
Loose minimum uses the filter arg float MinPerc, a percentage of total pixels to ignore
when finding the loose minimum, allows to ignore extreme stray pixels.
Loose maximum uses the filter arg float MaxPerc, a percentage of total pixels to ignore
when finding the loose maximum, allows to ignore extreme stray pixels.
Usage:-
ShowChannels(clip Last,float MinPerc, float MaxPerc, bool ver,bool "Setvar"=false,String "Prefix"="SC_",bool "Show"=true)
Where:-
Last is the clip
MinPerc is percentage of pixels to ignore for loose minimum. (default 0.1%, ie 1/1000 of total pixels)
MaxPerc is percentage of pixels to ignore for loose maximum. (default 0.1%, ie 1/1000 of total pixels)
ver display version info, false OFF [default] , true ON
BETA
Setvar if true then sets Global Variables using Prefix.
Prefix (default "SC_"), prefix to Global variable names.
Show, false switches off normal display, set false if using SetVar.
Default Global variable names when SetVar=true and using Default Prefix = "SC_"
"SC_Visited" = Frames visited
Channel 0 (Y or R)
"SC_Ave_0","SC_Min_0","SC_Max_0","SC_LMn_0","SC_LMx_0","SC_AAve_0","SC_AMin_0","SC_AMax_0","SC_ALMn_0","SC_ALMx_0",
Channel 1 (U or G, NOT Y8)
"SC_Ave_1","SC_Min_1","SC_Max_1","SC_LMn_1","SC_LMx_1","SC_AAve_1","SC_AMin_1","SC_AMax_1","SC_ALMn_1","SC_ALMx_1",
Channel 2 (V or B, NOT Y8)
"SC_Ave_2","SC_Min_2","SC_Max_2","SC_LMn_2","SC_LMx_2","SC_AAve_2","SC_AMin_2","SC_AMax_2","SC_ALMn_2","SC_ALMx_2",
For Y8, channels 1 and 2 will all be set to -1
A test script (Included)
Avisource("D:\avs\avi\1.avi").ConvertToYV12() #.Trim(0,100)
A=showchannels()
showchannels(setvar=true,show=false)
ScriptClip("""
Line0 = "Visited = "+String(SC_Visited)
Line1 = (IsRGB()) ? " R G B R G B"
\ :" Y U V Y U V"
Line2 = "Ave = "+String(SC_Ave_0,"%0.2f")+" "+String(SC_Ave_1,"%0.2f")+" "+String(SC_Ave_2,"%0.2f") + " "+String(SC_AAve_0,"%0.2f")+
\ " "+String(SC_AAve_1,"%0.2f")+" "+String(SC_AAve_2,"%0.2f")
Line3 = "Min = "+String(SC_Min_0)+" "+String(SC_Min_1)+" "+String(SC_Min_2)+" "+String(SC_AMin_0)+" "
\ +String(SC_AMin_1)+" "+String(SC_AMin_2)
Line4 = "Max = "+String(SC_Max_0)+" "+String(SC_Max_1)+" "+String(SC_Max_2)+" "+String(SC_AMax_0)+" "
\ +String(SC_AMax_1)+" "+String(SC_AMax_2)
Line5 = "LMn = "+String(SC_LMn_0)+" "+String(SC_LMn_1)+" "+String(SC_LMn_2)+" "+String(SC_ALMn_0)+" "
\ +String(SC_ALMn_1)+" "+String(SC_ALMn_2)
Line6 = "LMx = "+String(SC_LMx_0)+" "+String(SC_LMx_1)+" "+String(SC_LMx_2)+" "+String(SC_ALMx_0)+" "
\ +String(SC_ALMx_1)+" "+String(SC_ALMx_2)
# Subtitle(line0,y=00)
# Subtitle(line1,y=20)
# Subtitle(line2,y=40)
# Subtitle(line3,y=60)
# Subtitle(line4,y=80)
# Subtitle(line5,y=100)
# Subtitle(line6,y=120)
lines = line0+"\n"+line1+"\n"+line2+"\n"+line3+"\n"+line4+"\n"+line5+"\n"+line6
Subtitle(lines,y=0,lsp=20)
""",after_frame=True) # Important, after_frame=True
StackHorizontal(A,Last)
return last
EDIT: Methinks we can expect a color correction script.
Mounir
8th October 2012, 04:48
I still don't have a clue what the loose values mean ? Anyone knows ?
StainlessS
8th October 2012, 05:13
Loose minimum uses the filter arg float MinPerc, a percentage of total pixels to ignore
when finding the loose minimum, allows to ignore extreme stray pixels.
Loose maximum uses the filter arg float MaxPerc, a percentage of total pixels to ignore
when finding the loose maximum, allows to ignore extreme stray pixels.
Same as loose minimum/maximum in ColorYUV Analyze=true
analyze can be true or false. This will print out color statistics on the screen.
There are maximum and minimum values for all channels.
There is an average for all channels.
There is a "loose maximum" and "loose minimum". The "loose" values are made to filter out very bright
or very dark noise creating an artificially low or high minimum / maximum.
Mounir
8th October 2012, 09:21
That's interesting. So if i believe this info i should pay more attention to these loose values because they return more accurate values (noise in dark/bright areas being eliminated of the equation)
I like the accumulated feature but it would be even better if we could analyse a whole video automatically and get the result in a text file because currently i do it manually and skip many frames doing so (in avspmod)...not very accurate
keep up the good work
StainlessS
8th October 2012, 18:33
YPlaneMin/YPlaneMax has the same sort of thing where what I've called 'MinPerc/MaxPerc' uses name of 'Threshold'.
YPlaneMin | v2.x | YPlaneMin(clip, float threshold)
YPlaneMax | v2.x | YPlaneMax(clip, float threshold)
threshold is a percentage, stating how many percent of the pixels are allowed above or below minimum.
The threshold is optional and defaults to 0.
The Accumulated Ave is a "Average of Averages", or "Average Mean" or "Mean Average", take your pick but accumulated seemed more appropriate
considering that it was not restricted to describing just the averages. Accumulated Min is the minimum of all minimums so far, etc.
Comment From ColorYUV source
// When 1/256th of all pixels have been reached, trigger "Loose min/max"
So ColorYUV ignores 1/256 of the darkest/lightest pixels, YPlaneMin ignores 0% default, and ShowChannels 0.1% or 1/1000 by default,
so a Minperc/Maxperc of 0.4% would be about the same as ColorYUV uses.
You could write a script which outputs the final accumulated Showchannels values to a file where eg
SC_AAve_1 (U) and SC_AAve_2 (V) might suggest a correction to a color cast imperfection, in a perfect world
you might expect the accumulated average to be ~128. (EDIT: correctable in ColorYUV using off_u and off_v)
For accumulated Ave luma, I would think that gamma might have to be taken into consideration, it tends to be lower
than 128 for YUV. EDIT: or 126 for mid point of 16-235
EDIT:
@Mounir
What format would you want the file to be written ?
Just final accumulated values for entire file?
StainlessS
9th October 2012, 04:20
@Jmac698
You seem not to read prior to the last post in a thread, tried to PM you to say, "See post #7",
BUT, your PM box is FULL (must be nice to be so popular).
StainlessS
15th October 2012, 03:28
ShowChannels() v0.4, New version, See 1st post.
jmac698
21st October 2012, 22:51
Ok, got it - nice!
For another purpose, including a box region to sample would be very convenient. Yes I can do something with crop, but it's a bit awkward, plus I do need to use full luma precision in some cases, well actually I do.
What I'm thinking of is a color correction script where you've got recorded colorbars. These take 1/7 the width of the video line, and can end up on odd pixels, at least when measuring the luma part.
What I'd do is find the accumulated average (for accuracy against noise) over several frames in 7 separate regions. I'll be using the values for all planes, but bear in mind they have diffrent resolutions too. It would be nice too to return the hue and saturation values instead of plain "plane" u v. It's just atan2(u,v) and sqrt(u*u+v*v) (but don't quote me on that, really you have to look it up).
Of course I can calculate that in script, it's just convenient.
StainlessS
21st October 2012, 23:37
and can end up on odd pixels, at least when measuring the luma part.
Single region to examine, accepted.
I think, I like the Unix type model of restriction to a simple function, but doing it flexibly and well. H & S feels like another filter.
I'll take a look at doing the 1st part, if I ever do the second, it will be some time, I've got a load of stuff I've been heaping on the
back burner and I really want to get that backlog cleared.
jmac698
22nd October 2012, 00:25
Hmm, it doesn't feel different to me at all - in fact it sounds more appropriate. If this is truly a video oriented filter, we should always be talking in terms of luma hue and saturation. This U/V planes business is very low level and you rarely ever refer to it directly.
So as such, it's a purely mathematical filter on an internal representation of video, very low level, and not very video-sih.
StainlessS
22nd October 2012, 01:04
And how would one calc the average HUE (of a clip), being circular in nature, also, min/max loose min/max and accumulated,
would not really make sense, and way too specific a function measuring eg one specific color in colorbars. If it can
be done as required in script then would be a shame to cripple speed even a little just for that one off functionality.
EDIT:
You have the source, you can do a specific version to do exactly as you require, eg ShowHSL or whatever..
Mounir
22nd October 2012, 01:11
What about implementing a slice display graph and gamut display
more info here: http://www.synthetic-ap.com/products/tg/index.html
StainlessS
22nd October 2012, 01:32
Looks like (I think Wilbert's) VScope.
I really want to get away from doing user suggested mods, I have things I really would like to get running and will
have limited time to do so from a few weeks hence. Perhaps Jmac will incorporate the slice & gamut display
in his new plugin ShowHSL(). Hehe :)
jmac698
22nd October 2012, 02:03
The plugin is still useful (at least to me), I'm just saying it makes sense to call it a low-level mathematical plugin, and that's fine if that's what you want it to be.
As for user mods, well that is really part of the fun of coding, getting the feedback and being helpful, and receiving praise. For example I loved following AvsP development, he did a great job of taking suggestions and people were really happy, and I think that's one of the reasons it's such a great program.
Of course, most of us do a plugin mainly for our own uses at first, and there is limited time. These suggestion were certainly not critical, just enhancements.
There's a min/max hue, even though it's circular. Take the average and find the CCW and CW values from that. Let's say in noisy colourbars, it's +-3% of some roughly reddish colour. That makes sense to me.
If all hues are present, you get +- 180degrees, of course.
jmac698
22nd October 2012, 02:06
I've tested all of the vectorscopes, they're calculated wrong. A pure atan2(u,v) doesn't cut it. There range of hues is a hexagon with different scaled axis. You have to account for the scaling to get a true hue.
jmac698
22nd October 2012, 02:07
So what else are you up to in the plugin dept.? I'm looking forward to it :)
I've been too busy to make new plugins, but yeah I was doing a few a week last July :)
StainlessS
22nd October 2012, 03:32
These suggestion were certainly not critical
I know.
1st line of doc:
Simple plugin whose only function is to display the average Y,U and V
Was never meant for anything other than to assist with simple mods using ColorYUV, eg off_u and off_v for color cast correction.
Written previously in thread:
For accumulated Ave luma, I would think that gamma might have to be taken into consideration, it tends to be lower
than 128 for YUV. EDIT: or 126 for mid point of 16-235
Any idea how to generate a BellJar random distribution curve ? (probably not the correct term).
No idea what CCW and CW are, best guess is Celebrity Championship Wrestling, or Carrying Concealed Weapon, although I did initially think Clockwise,
Counter Clockwise. :)
What I'm I wanting to do, well a number of things keep getting pushed back, including mods to both DGIndex and MeGUI Batchers,
investigation field order, interlace/ivtc detection, and other infos useful in autonomous conversion script. RoboCrop auto crop and auto
levels setting plug. Perhaps MediaInfo implemented as plug.
Investigate implement Avisynth Script Editor from VDMod into latest version VD (perhaps beyond me, or too time consuming).
+ lots more.
I'm always happier doing what I want, and is usually where my better ideas surface.
jmac698
22nd October 2012, 10:56
Hmm, the luma gamma of 2.2 already approxmiates the power curve of the eye response, so it's generally ok as is. I think what you're trying to get at is a perceptually uniform percentage measurement. This would be accomplished by measuring the L of L a* b*. It certainly can be converted internally, but it's gonna be a bit slow as it needs several floating point ops.
As for, do you really want to do this - yes, I think most filters want to operate on a perceptually uniform domain, but not all. Some exception include, gamma-aware resizing (and interpolation etc.), and perceptual masking.
As for the luma distribution of natural objects, I believe they follow the Phong illumination model. Highlights are a raised cosine, diffuse is a cosine, and ambient is a constant, so I don't think the histogram follows a Gaussian Normal Distribution (aka "Bell Curve") as you propose.
Interestingly, if you take the inverse Phong, you can deduce the angle a surface is based on how it's shaded, which leads to a way to create a 3d model from a single photo. There's far better ways to do this though, like projecting a pattern onto the object, using lidar, or using multiple views.
Oh, a Bell jar is a shape to contain high pressure, like a vacuum jar, I think. It's a different shape; the Bell curve could refer to a Mr. Bell, but I think it's the shape of a bell that you ring, and that shape is designed to resonate and amplify sound. As I recall, sound is best amplified by a log shape.. the classic horn design. It's the most efficient speaker shape. Blah blah balh :)
StainlessS
25th October 2012, 21:48
Thanks for that jmac, and yep, I meant "Bell" rather than "BellJar".
I've done some tests on 320MB chunks of test vobs cut from somewhere in middle of a DVD vob,
clip lengths vary from about 8 mins to 15 mins depending on eg bitrate and number of audio channels etc.
Results are Accumulated values for the entire clips, just to show typical results that might be expected.
EDIT: The clips were all auto cropped and auto leveled prior to ShowChannels(), hence 16 -> 235 Y range.
NTSC_Top_FORCEFILM-ReturnOfTheKing.d2v
AVE_Y=71.12 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=127.22 MIN_U= 62 MAX_U=168 LMIN_U= 78 LMAX_U=158
AVE_V=126.63 MIN_V= 74 MAX_V=188 LMIN_V= 78 LMAX_V=174
PAL_I_Top_169_P-FellowshipOfTheRings_Extended.d2v
AVE_Y=70.31 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=119.82 MIN_U= 54 MAX_U=178 LMIN_U= 77 LMAX_U=166
AVE_V=132.89 MIN_V= 82 MAX_V=190 LMIN_V=103 LMAX_V=183
PAL_I_Top_169_P-TwoTowers_Extended.d2v
AVE_Y=72.33 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=129.66 MIN_U= 63 MAX_U=159 LMIN_U= 70 LMAX_U=153
AVE_V=124.38 MIN_V= 87 MAX_V=226 LMIN_V= 93 LMAX_V=201
PAL-P_169_P-ReturnOfTheKing_Extended.d2v
AVE_Y=98.68 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=122.03 MIN_U= 73 MAX_U=144 LMIN_U= 88 LMAX_U=137
AVE_V=131.77 MIN_V=102 MAX_V=183 LMIN_V=117 LMAX_V=164
PAL_I_Top_169_P-LordOfTheRings_Symphony.d2v
AVE_Y=56.30 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=130.30 MIN_U= 33 MAX_U=249 LMIN_U= 73 LMAX_U=220
AVE_V=129.64 MIN_V= 6 MAX_V=248 LMIN_V= 29 LMAX_V=204
PAL_I_Top_169_P-DieHard.d2v
AVE_Y=51.19 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=122.70 MIN_U= 55 MAX_U=220 LMIN_U= 77 LMAX_U=172
AVE_V=134.51 MIN_V= 32 MAX_V=248 LMIN_V= 60 LMAX_V=191
PAL_I_Top_169_P-DieHard_2.d2v
AVE_Y=55.67 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.27 MIN_U= 56 MAX_U=196 LMIN_U= 69 LMAX_U=172
AVE_V=129.37 MIN_V= 53 MAX_V=216 LMIN_V= 65 LMAX_V=183
PAL-I-Top_169_P-DieHard_3.d2v
AVE_Y=95.52 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=123.56 MIN_U= 62 MAX_U=173 LMIN_U= 81 LMAX_U=154
AVE_V=136.44 MIN_V= 75 MAX_V=237 LMIN_V= 93 LMAX_V=209
PAL_I_Top_43_Hybrid-StarTrekNG_1_TooShortASeason.d2v
AVE_Y=60.59 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=127.39 MIN_U= 1 MAX_U=209 LMIN_U=107 LMAX_U=180
AVE_V=136.72 MIN_V= 1 MAX_V=203 LMIN_V= 96 LMAX_V=191
PAL_I_Top_43_Hybrid-StarTrekNG_2_WhenTheBoughBreaks.d2v
AVE_Y=52.47 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.70 MIN_U= 52 MAX_U=210 LMIN_U= 59 LMAX_U=173
AVE_V=135.38 MIN_V= 45 MAX_V=195 LMIN_V=105 LMAX_V=189
PAL_I_Top_43_Hybrid-StarTrekNG_3_HomeSoil.d2v
AVE_Y=51.29 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.48 MIN_U= 61 MAX_U=207 LMIN_U= 88 LMAX_U=188
AVE_V=131.68 MIN_V= 0 MAX_V=255 LMIN_V=106 LMAX_V=178
PAL_I_Top_169_P-Godfather.d2v
AVE_Y=50.64 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=121.47 MIN_U= 46 MAX_U=188 LMIN_U= 68 LMAX_U=144
AVE_V=134.98 MIN_V= 71 MAX_V=214 LMIN_V=101 LMAX_V=190
PAL_I_Top_169_P-Godfather_2.d2v
AVE_Y=62.44 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=119.61 MIN_U= 72 MAX_U=180 LMIN_U= 80 LMAX_U=151
AVE_V=136.48 MIN_V= 78 MAX_V=179 LMIN_V=115 LMAX_V=169
PAL_I_Top_169_P-Godfather_3.d2v
AVE_Y=57.43 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=118.46 MIN_U= 47 MAX_U=188 LMIN_U= 82 LMAX_U=186
AVE_V=137.32 MIN_V= 76 MAX_V=206 LMIN_V= 91 LMAX_V=200
PAL_I_Bot_43-BustyCops.d2v
AVE_Y=122.60 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=118.15 MIN_U= 32 MAX_U=255 LMIN_U= 62 LMAX_U=167
AVE_V=139.79 MIN_V= 48 MAX_V=246 LMIN_V= 92 LMAX_V=221
PAL_I_Bot_169_P-FalseBadFieldOrder-FlightPlan.d2v
AVE_Y=58.96 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.46 MIN_U= 0 MAX_U=255 LMIN_U= 90 LMAX_U=167
AVE_V=125.02 MIN_V= 0 MAX_V=255 LMIN_V= 61 LMAX_V=182
PAL_I_Top_43_I-GirlIn3D.d2v
AVE_Y=60.73 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=124.27 MIN_U= 50 MAX_U=222 LMIN_U= 63 LMAX_U=213
AVE_V=129.07 MIN_V= 47 MAX_V=232 LMIN_V= 60 LMAX_V=205
PAL_I_Top_43_I-SocialClimber.d2v
AVE_Y=85.46 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=120.87 MIN_U= 30 MAX_U=212 LMIN_U= 56 LMAX_U=192
AVE_V=136.94 MIN_V= 89 MAX_V=212 LMIN_V= 97 LMAX_V=194
PAL_I_Top_43_I-UltimateLimit.d2v
AVE_Y=52.55 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.92 MIN_U= 31 MAX_U=189 LMIN_U= 51 LMAX_U=183
AVE_V=129.58 MIN_V= 82 MAX_V=212 LMIN_V= 92 LMAX_V=193
PAL_I_Top_43_P-ArtificialTelepathy.d2v
AVE_Y=89.88 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.38 MIN_U= 0 MAX_U=218 LMIN_U= 68 LMAX_U=207
AVE_V=126.38 MIN_V= 0 MAX_V=217 LMIN_V= 44 LMAX_V=200
PAL_I_Top_43_P-AssaultOnPrecinct13.d2v
AVE_Y=60.04 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=129.02 MIN_U= 0 MAX_U=173 LMIN_U= 85 LMAX_U=157
AVE_V=123.97 MIN_V= 0 MAX_V=215 LMIN_V= 74 LMAX_V=188
PAL_I_Top_43_P-Cabaret.d2v
AVE_Y=44.20 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.85 MIN_U= 1 MAX_U=254 LMIN_U= 73 LMAX_U=232
AVE_V=130.97 MIN_V= 30 MAX_V=253 LMIN_V= 81 LMAX_V=210
PAL_I_Top_43_P-FourPlay.d2v
AVE_Y=72.80 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=124.06 MIN_U= 69 MAX_U=190 LMIN_U= 90 LMAX_U=170
AVE_V=130.90 MIN_V= 65 MAX_V=205 LMIN_V= 75 LMAX_V=191
PAL_I_Top_43_P-GoingOverboard.d2v
AVE_Y=104.08 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=127.27 MIN_U= 53 MAX_U=188 LMIN_U= 76 LMAX_U=161
AVE_V=129.42 MIN_V= 42 MAX_V=221 LMIN_V= 82 LMAX_V=203
PAL_I_Top_43_P-GroundControl.d2v
AVE_Y=57.19 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.20 MIN_U= 0 MAX_U=255 LMIN_U= 84 LMAX_U=187
AVE_V=132.69 MIN_V= 19 MAX_V=211 LMIN_V= 36 LMAX_V=201
PAL_I_Top_43_P-Panic.d2v
AVE_Y=64.10 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=124.26 MIN_U= 37 MAX_U=179 LMIN_U= 87 LMAX_U=159
AVE_V=130.67 MIN_V= 67 MAX_V=203 LMIN_V=107 LMAX_V=189
PAL_I_Top_169_P-AllTheQueensMen.d2v
AVE_Y=75.95 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.43 MIN_U= 25 MAX_U=190 LMIN_U= 42 LMAX_U=183
AVE_V=126.32 MIN_V= 81 MAX_V=238 LMIN_V= 95 LMAX_V=227
PAL_I_Top_169_P-DuskTillDawn.d2v
AVE_Y=54.26 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=121.26 MIN_U= 56 MAX_U=191 LMIN_U= 61 LMAX_U=183
AVE_V=137.11 MIN_V= 82 MAX_V=219 LMIN_V= 95 LMAX_V=203
PAL_I_Top_169_P-EducatingRita.d2v
AVE_Y=74.65 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=125.96 MIN_U= 71 MAX_U=167 LMIN_U= 99 LMAX_U=156
AVE_V=127.71 MIN_V= 99 MAX_V=177 LMIN_V=108 LMAX_V=161
PAL_I_Top_169_P-HarryPotter-DeathlyHallows2.d2v
AVE_Y=56.44 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=123.50 MIN_U= 0 MAX_U=255 LMIN_U=102 LMAX_U=140
AVE_V=128.86 MIN_V= 82 MAX_V=165 LMIN_V=105 LMAX_V=151
PAL_I_Top_169_P-JurassicPark.d2v
AVE_Y= 91.04 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=125.36 MIN_U= 3 MAX_U=206 LMIN_U= 89 LMAX_U=169
AVE_V=134.81 MIN_V= 3 MAX_V=238 LMIN_V=101 LMAX_V=196
PAL_I_Top_169_P-LastSign.d2v
AVE_Y=60.97 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=125.24 MIN_U= 44 MAX_U=244 LMIN_U= 55 LMAX_U=219
AVE_V=128.43 MIN_V= 76 MAX_V=249 LMIN_V= 97 LMAX_V=174
PAL_I_Top_169_P-LegallyBlond.d2v
AVE_Y=69.96 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=123.08 MIN_U= 42 MAX_U=214 LMIN_U= 63 LMAX_U=197
AVE_V=136.82 MIN_V= 43 MAX_V=241 LMIN_V= 59 LMAX_V=222
PAL_I_Top_169_P-MillionDollarBaby.d2v
AVE_Y=74.50 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=124.28 MIN_U= 0 MAX_U=255 LMIN_U= 85 LMAX_U=152
AVE_V=124.73 MIN_V= 0 MAX_V=255 LMIN_V= 95 LMAX_V=157
PAL_I_Top_169_P-ResidentEvil_Apocalypse.d2v
AVE_Y=58.35 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=136.48 MIN_U= 20 MAX_U=191 LMIN_U= 63 LMAX_U=181
AVE_V=118.23 MIN_V= 23 MAX_V=215 LMIN_V= 40 LMAX_V=195
PAL_I_Top_169_P-ShawshankRedemption.d2v
AVE_Y=65.69 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.15 MIN_U= 35 MAX_U=251 LMIN_U=100 LMAX_U=159
AVE_V=129.75 MIN_V= 45 MAX_V=251 LMIN_V=100 LMAX_V=164
PAL_I_Top_169_P-Spiderman.d2v
AVE_Y=74.89 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=123.81 MIN_U= 1 MAX_U=216 LMIN_U= 83 LMAX_U=189
AVE_V=135.67 MIN_V= 1 MAX_V=231 LMIN_V= 48 LMAX_V=202
PAL_I_Top_169_P-SweetestThing.d2v
AVE_Y=64.76 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=120.72 MIN_U= 1 MAX_U=254 LMIN_U= 48 LMAX_U=201
AVE_V=136.83 MIN_V= 1 MAX_V=254 LMIN_V= 71 LMAX_V=221
PAL_I_Top_169_P-XXX-TheNextLevel.d2v
AVE_Y=77.01 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.31 MIN_U= 37 MAX_U=192 LMIN_U= 55 LMAX_U=181
AVE_V=125.04 MIN_V= 36 MAX_V=219 LMIN_V= 63 LMAX_V=205
PAL_I_Top_169_I-LoveOnTheSide(Weird mix I and P).d2v
AVE_Y=73.29 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=122.95 MIN_U= 68 MAX_U=203 LMIN_U= 78 LMAX_U=193
AVE_V=136.01 MIN_V= 60 MAX_V=225 LMIN_V= 76 LMAX_V=220
PAL-I-Top_169_P-MissionImpossible_2.d2v
AVE_Y=76.59 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=125.45 MIN_U= 3 MAX_U=199 LMIN_U= 56 LMAX_U=187
AVE_V=132.29 MIN_V= 34 MAX_V=232 LMIN_V= 47 LMAX_V=198
PAL-I-Top_169_P-ResevoirDogs.d2v
AVE_Y=70.37 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=124.45 MIN_U= 42 MAX_U=191 LMIN_U= 69 LMAX_U=181
AVE_V=131.47 MIN_V= 32 MAX_V=234 LMIN_V= 88 LMAX_V=206
PAL-I-Top_169_P-Unbreakable.d2v
AVE_Y=47.84 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.94 MIN_U= 59 MAX_U=207 LMIN_U= 88 LMAX_U=182
AVE_V=126.05 MIN_V= 41 MAX_V=207 LMIN_V= 82 LMAX_V=165
PAL-P_169_P-AeonFlux.d2v
AVE_Y=64.54 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=123.49 MIN_U= 36 MAX_U=164 LMIN_U= 59 LMAX_U=158
AVE_V=131.04 MIN_V= 67 MAX_V=199 LMIN_V= 80 LMAX_V=187
PAL-P_169_P-Alexander.d2v
AVE_Y=93.62 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=121.21 MIN_U= 35 MAX_U=186 LMIN_U= 60 LMAX_U=168
AVE_V=134.59 MIN_V= 63 MAX_V=218 LMIN_V= 95 LMAX_V=186
PAL-P_169_P-BodyGuard.d2v
AVE_Y=59.37 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=130.49 MIN_U= 58 MAX_U=226 LMIN_U= 68 LMAX_U=207
AVE_V=129.52 MIN_V= 60 MAX_V=212 LMIN_V= 84 LMAX_V=207
PAL-P_169_P-DownWithLove.d2v
AVE_Y=72.96 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=122.13 MIN_U= 6 MAX_U=200 LMIN_U= 14 LMAX_U=188
AVE_V=132.64 MIN_V= 70 MAX_V=209 LMIN_V= 80 LMAX_V=183
PAL-P_169_P-Gladiator.d2v
AVE_Y=69.03 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=123.12 MIN_U= 50 MAX_U=168 LMIN_U= 64 LMAX_U=162
AVE_V=134.22 MIN_V= 90 MAX_V=225 LMIN_V= 99 LMAX_V=211
PAL-P_169_P-Hannibal.d2v
AVE_Y=61.85 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=132.80 MIN_U= 90 MAX_U=202 LMIN_U=106 LMAX_U=179
AVE_V=124.39 MIN_V= 84 MAX_V=220 LMIN_V= 92 LMAX_V=189
PAL-P_169_P-HitchhikersGuideToTheGalaxy_Movie.d2v
AVE_Y=113.73 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=121.45 MIN_U= 40 MAX_U=198 LMIN_U= 55 LMAX_U=181
AVE_V=134.68 MIN_V= 27 MAX_V=228 LMIN_V= 47 LMAX_V=213
PAL-P_169_P-HuntForRedOctober.d2v
AVE_Y=49.98 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=127.82 MIN_U= 71 MAX_U=224 LMIN_U= 86 LMAX_U=210
AVE_V=131.32 MIN_V= 70 MAX_V=234 LMIN_V= 81 LMAX_V=223
PAL-P_169_P-ItalianJob_2.d2v
AVE_Y=71.63 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=128.50 MIN_U= 5 MAX_U=251 LMIN_U= 71 LMAX_U=169
AVE_V=127.32 MIN_V= 5 MAX_V=251 LMIN_V= 65 LMAX_V=225
PAL-P_169_P-SinCity.d2v
AVE_Y=55.55 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=127.57 MIN_U=102 MAX_U=176 LMIN_U=113 LMAX_U=161
AVE_V=128.48 MIN_V= 48 MAX_V=176 LMIN_V= 58 LMAX_V=145
PAL-P_169_P-TombRaider.d2v
AVE_Y=55.56 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=126.50 MIN_U= 70 MAX_U=219 LMIN_U= 91 LMAX_U=194
AVE_V=130.88 MIN_V= 73 MAX_V=234 LMIN_V= 84 LMAX_V=207
PAL-P_169_P-TombRaider_CradleOfLife.d2v
AVE_Y=49.62 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=124.05 MIN_U= 32 MAX_U=191 LMIN_U= 82 LMAX_U=186
AVE_V=134.29 MIN_V= 68 MAX_V=239 LMIN_V=104 LMAX_V=224
PAL-P_169_P-UnderworldEvolution.d2v
AVE_Y=39.20 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=129.71 MIN_U= 37 MAX_U=164 LMIN_U= 69 LMAX_U=158
AVE_V=125.12 MIN_V= 58 MAX_V=190 LMIN_V= 70 LMAX_V=172
PAL-P_169_P-VanHelsing.d2v
AVE_Y=75.26 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=137.14 MIN_U= 58 MAX_U=170 LMIN_U=103 LMAX_U=161
AVE_V=123.96 MIN_V= 97 MAX_V=201 LMIN_V=107 LMAX_V=173
PAL-P_169_P-WarOfTheWorlds.d2v
AVE_Y=80.80 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=122.47 MIN_U= 58 MAX_U=191 LMIN_U= 75 LMAX_U=186
AVE_V=130.60 MIN_V= 64 MAX_V=205 LMIN_V= 71 LMAX_V=185
PAL-P_169_P-XMen_2.d2v
AVE_Y=50.75 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=129.09 MIN_U= 0 MAX_U=255 LMIN_U= 73 LMAX_U=189
AVE_V=121.72 MIN_V= 0 MAX_V=255 LMIN_V= 44 LMAX_V=192
PAL-P_169_P-TimeMachine.d2v
AVE_Y=59.64 MIN_Y= 16 MAX_Y=235 LMIN_Y= 16 LMAX_Y=235
AVE_U=117.64 MIN_U= 56 MAX_U=193 LMIN_U= 83 LMAX_U=145
AVE_V=141.43 MIN_V= 97 MAX_V=214 LMIN_V=125 LMAX_V=182
StainlessS
29th October 2012, 05:22
DGIndex Template Script to produce ShowChannels data as in previous post (Is slow, as plays entire clip to end).
Writes "Accumulated.txt" file on last frame (appended to any already existing file).
# Requires GScript, Grunt, RT_Stats, ShowChannels, DGIndex
#Import ("D:\avs\BANK\QueryBorderCrop.avsi") # Required by RoboLevels unless in plugs dir
#Import ("D:\avs\BANK\QueryLumaMinMAx.Avsi")
VIDOEOFILE="__vid__" # DGIndex inserts clip name here
MPEG2Source(VIDOEOFILE)
NAME=VIDOEOFILE
# RoboLevels() # Uncomment if Global (clipwise) Auto Levels required first
ShowChannels(SetVar=true,show=false) # set Show=true, if required but may be a tiny bit slower
AssumeFPS(250.0) # Do it a bit quicker
EOL=Chr(10)
S="""NAME + EOL + \
" AVE_Y="+String(SC_AAve_0,"%3.2f")+" MIN_Y="+String(SC_AMIN_0,"%3.0f")+" MAX_Y="+String(SC_AMAX_0,"%3.0f")+ \
" LMIN_Y="+String(SC_ALMN_0,"%3.0f")+" LMAX_Y="+String(SC_ALMX_0,"%3.0f") + EOL + \
" AVE_U="+String(SC_AAve_1,"%3.2f")+" MIN_U="+String(SC_AMIN_1,"%3.0f")+" MAX_U="+String(SC_AMAX_1,"%3.0f")+ \
" LMIN_U="+String(SC_ALMN_1,"%3.0f")+" LMAX_U="+String(SC_ALMX_1,"%3.0f") + EOL + \
" AVE_V="+String(SC_AAve_2,"%3.2f")+" MIN_V="+String(SC_AMIN_2,"%3.0f")+" MAX_V="+String(SC_AMAX_2,"%3.0f")+ \
" LMIN_V="+String(SC_ALMN_2,"%3.0f")+" LMAX_V="+String(SC_ALMX_2,"%3.0f") + EOL"""
WriteFileIf("Accumulated.txt","current_frame==FrameCount()-1",S,append=true)Return Last
return last
# Below optional
Function RoboLevels(clip c,float "Strength",int "Samples",float "Ignore",Bool "QBC",Float "QBC_Thresh",int "X",int "Y",int "W",int "H", \
int "Matrix",bool "PC",bool "DEBUG") {
c
Frames=FrameCount
Strength=Float(Default(Strength,1.0))
Samples=(!Defined(Samples)) ? 24 : (Samples > Frames) ? Frames : (Samples < 1) ? 1 : Samples
Ignore=Float(Default(Ignore,0.2))
QBC=Default(QBC,True)
QBC_Thresh=Float(Default(QBC_Thresh,-32.0))
QBCropXP = Default(X,0)
QBCropYP = Default(Y,0)
QBCropWP = Default(W,0)
QBCropHP = Default(H,0)
Matrix = Default(Matrix,(width <= 720) ? 2 : 3)
PC=Default(PC,False)
DEBUG=Default(DEBUG,True)
Assert(Strength>0.0 && Strength <=1.0, "RoboLevels: 0.0 < Strength <= 1.0")
GScript("""
if(QBC) {
QBCS=QueryBorderCrop(samples=Samples,thresh=QBC_Thresh,debug=DEBUG,ignore=Ignore,matrix=Matrix)
(DEBUG)? RT_Debug(QBCS): NOP
Eval(QBCS)
}
tclip=c.Crop(QBCropXP,QBCropYP,QBCropWP,QBCropHP)
QLMMS=QueryLumaMinMax(tclip,samples=Samples,ignore=Ignore,debug=DEBUG,matrix=Matrix)
(DEBUG)?RT_Debug(QLMMS):NOP
Eval(QLMMS)
if(IsRGB() || PC) {
CSMin = 0
CSMax = 255
} else {
CSMin = 16
CSMax = 235
}
ALMin = Int(CSMin - ((CSMin - QLMMMin) * Strength) + 0.5) # Round Up
ALMax = Int(CSMax - ((CSMax - QLMMMax) * Strength)) # Round down
(QBC) ? Crop(QBCropXM,QBCropYM,QBCropWM,QBCropHM): NOP
(DEBUG)? RT_Debug("Levels("+String(ALMin)+",1.0,"+String(AlMax)+","+String(CSMin)+","+String(CSMax)+",Coring=False)"):NOP
Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DO NOT use Coring
""")
return Last
}
EDITED As per Gavino post following.
EDIT: Was unsuccessful in trying to get it to WriteFile on close without using ScriptClip, anybody clever out there ?
EDIT: Clarify, WriteFileEnd wants to write the "S" string as it was on WriteFileEnd contructor call ie at the beginning,
we want to write final results, not what it was before starting.
EDIT:, OK, think I've twigged a way, new plugin to inquire value of string variable in destructor and then write it, other suggestions ?
EDIT: Perhaps WriteFileEnd should have the option to evaluate on writing ie at destructor rather than when constructed, would seem the
obvious way anyhow.
Gavino
29th October 2012, 10:05
EDIT: Was unsuccessful in trying to get it to WriteFile on close without using ScriptClip, anybody clever out there ?
EDIT: Clarify, WriteFileEnd wants to write the "S" string as it was on WriteFileEnd contructor call ie at the beginning,
we want to write final results, not what it was before starting.
EDIT:, OK, think I've twigged a way, new plugin to inquire value of string variable in destructor and then write it, other suggestions ?
EDIT: Perhaps WriteFileEnd should have the option to evaluate on writing ie at destructor rather than when constructed, would seem the obvious way anyhow.
WriteFileEnd cannot evaluate the expression in the destructor as it needs the script environment ("env") to do this, and this is not available to the destructor. Even if the filter was changed to save a copy of env, it cannot be reliably used at the time the destructor is called.
See this post.
(EDIT) PS To show a final value in a run-time script, an alternative to your WriteFileIf(...,"current_frame==FrameCount()-1",...) is to use (still within ScriptClip)
WriteFile("Accumulated.txt","S",append=false)
See here for an explanation.
The advantage of this is it shows the value for the last frame rendered, which no longer needs to be the final frame of the clip.
EDIT2: (Following your custom of repeated edits. :))
Your original way can be done without ScriptClip by setting S to be the expression to be evaluated rather than the value itself:
EOL=Chr(10)
S="""NAME + EOL + \
" AVE_Y="+String(SC_AAve_0,"%3.2f")+" MIN_Y="+String(SC_AMIN_0,"%3.0f")+" MAX_Y="+String(SC_AMAX_0,"%3.0f")+ \
" LMIN_Y="+String(SC_ALMN_0,"%3.0f")+" LMAX_Y="+String(SC_ALMX_0,"%3.0f") + EOL + \
" AVE_U="+String(SC_AAve_1,"%3.2f")+" MIN_U="+String(SC_AMIN_1,"%3.0f")+" MAX_U="+String(SC_AMAX_1,"%3.0f")+ \
" LMIN_U="+String(SC_ALMN_1,"%3.0f")+" LMAX_U="+String(SC_ALMX_1,"%3.0f") + EOL + \
" AVE_V="+String(SC_AAve_2,"%3.2f")+" MIN_V="+String(SC_AMIN_2,"%3.0f")+" MAX_V="+String(SC_AMAX_2,"%3.0f")+ \
" LMIN_V="+String(SC_ALMN_2,"%3.0f")+" LMAX_V="+String(SC_ALMX_2,"%3.0f") + EOL"""
WriteFileIf("Accumulated.txt","current_frame==FrameCount()-1",S,append=true)
StainlessS
29th October 2012, 15:04
Thank you for the edit, I think I tried similar but could not get it to work, perhaps problem with my double quotes or something,
Ill try again.
Have never seen either of your links, were both posted a couple of months before I joined D9.
Again, thanks.
PS,
anybody clever out there ?
Modesty would have prevented me answering such a request, I see you suffer from no such impediment. :)
Gavino
29th October 2012, 16:52
Modesty would have prevented me answering such a request, I see you suffer from no such impediment. :)
You didn't say that only someone clever should reply, so I felt free to do so ... :)
StainlessS
31st October 2012, 13:27
ShowChannels v0.5, new version, see 1st post.
StainlessS
6th November 2012, 15:20
@Jmac698,
I see you there on-line, thought that you may have missed the ShowChannels update to 0.5,
implemented x,y,w,h coords (any coords even for eg YV12) as requested.
Dont think that you saw it as only 1 download and think that was a moderator.
StainlessS
5th December 2012, 09:26
ShowChannels() v0.6 - 05 Dec 2012, Plugin for Avisynth 2.5+
Planar, YUY2 and RGB.
v0.5, 31 Oct 2012, Added x,y,w,h coords, not colorspace restricted (real pain in the bum to implement).
Can use odd coords for eg YV12, and even sample a single pixel.
v0.6, 05 Dec 2012. Added Interlaced arg for Planar only. Now gets correct chroma for planar interlaced , even down to single pixel.
(an even bigger pain in the bum to implement, modest speed improvement)
See 1st post.
EDIT: Other colorspaces dont require the interlaced arg. (You owe me big-time Jmac:)).
StainlessS
21st April 2013, 00:33
ShowChannels() v0.7 - 20 Apr 2013
Updated for Avisynth v2.60.
v2.58 & v2.60 dll's.
See 1st post.
StainlessS
21st May 2013, 11:30
Script to create log file containing info on each frame
Avisource("D:\avs\test.avi").Trim(0,9)
ShowChannels(SetVar=True,Accfile="SC_WholeClip.Log")
S="""String(current_frame)+"]" + \
"YAve="+String(SC_Ave_0,"%6.2f")+"," + \
"YMin="+String(SC_Min_0,"%3.f")+"," + \
"YMax="+String(SC_Max_0,"%3.f")+"," + \
"YLmn="+String(SC_LMn_0,"%3.f")+"," + \
"YLmx="+String(SC_LMx_0,"%3.f")+"," + \
"UAve="+String(SC_Ave_1,"%6.2f")+"," + \
"UMin="+String(SC_Min_1,"%3.f")+"," + \
"UMax="+String(SC_Max_1,"%3.f")+"," + \
"ULmn="+String(SC_LMn_1,"%3.f")+"," + \
"ULmx="+String(SC_LMx_1,"%3.f")+"," + \
"VAve="+String(SC_Ave_2,"%6.2f")+"," + \
"VMin="+String(SC_Min_2,"%3.f")+"," + \
"VMax="+String(SC_Max_2,"%3.f")+"," + \
"VLmn="+String(SC_LMn_2,"%3.f")+"," + \
"VLmx="+String(SC_LMx_2,"%3.f")
"""
WriteFile("Frame.log", S, flush=true)
EDITED to remove ScriptClip().
Frame log, 1st 10 frames only
0]YAve= 75.13,YMin= 26,YMax=212,YLmn= 28,YLmx=197,UAve=119.51,UMin=100,UMax=132,ULmn=102,ULmx=132,VAve=140.11,VMin=127,VMax=198,VLmn=127,VLmx=188
1]YAve= 75.91,YMin= 26,YMax=212,YLmn= 28,YLmx=198,UAve=119.39,UMin=100,UMax=132,ULmn=102,ULmx=132,VAve=140.31,VMin=127,VMax=197,VLmn=127,VLmx=188
2]YAve= 77.11,YMin= 25,YMax=213,YLmn= 28,YLmx=201,UAve=119.24,UMin=100,UMax=132,ULmn=102,ULmx=132,VAve=140.51,VMin=127,VMax=197,VLmn=127,VLmx=188
3]YAve= 77.56,YMin= 24,YMax=212,YLmn= 28,YLmx=202,UAve=119.18,UMin=100,UMax=132,ULmn=102,ULmx=132,VAve=140.61,VMin=127,VMax=199,VLmn=127,VLmx=188
4]YAve= 77.85,YMin= 24,YMax=206,YLmn= 28,YLmx=200,UAve=119.11,UMin=101,UMax=132,ULmn=102,ULmx=132,VAve=140.66,VMin=127,VMax=199,VLmn=127,VLmx=188
5]YAve= 78.01,YMin= 24,YMax=208,YLmn= 28,YLmx=199,UAve=119.10,UMin=101,UMax=132,ULmn=102,ULmx=132,VAve=140.67,VMin=126,VMax=199,VLmn=127,VLmx=189
6]YAve= 77.79,YMin= 22,YMax=203,YLmn= 28,YLmx=198,UAve=119.13,UMin=101,UMax=132,ULmn=101,ULmx=132,VAve=140.55,VMin=127,VMax=197,VLmn=127,VLmx=189
7]YAve= 76.34,YMin= 21,YMax=200,YLmn= 28,YLmx=197,UAve=119.42,UMin=101,UMax=132,ULmn=101,ULmx=132,VAve=140.20,VMin=127,VMax=197,VLmn=127,VLmx=188
8]YAve= 74.68,YMin= 22,YMax=199,YLmn= 28,YLmx=195,UAve=119.75,UMin=101,UMax=132,ULmn=101,ULmx=132,VAve=139.80,VMin=127,VMax=198,VLmn=127,VLmx=188
9]YAve= 73.02,YMin= 22,YMax=200,YLmn= 28,YLmx=194,UAve=120.06,UMin=101,UMax=132,ULmn=101,ULmx=132,VAve=139.44,VMin=127,VMax=199,VLmn=127,VLmx=188
And log for accumulated info on whole clip.
SC_AAve_0=76.339836 SC_AMin_0=21 SC_AMax_0=213 SC_ALMn_0=28 SC_ALMx_0=202
SC_AAve_1=119.388771 SC_AMin_1=100 SC_AMax_1=132 SC_ALMn_1=101 SC_ALMx_1=132
SC_AAve_2=140.285110 SC_AMin_2=126 SC_AMax_2=199 SC_ALMn_2=127 SC_ALMx_2=189
SC_Visited=10
StainlessS
30th March 2015, 18:10
ShowChannels v0.8, See 1st post.
v0.8, 30 Mar 2015, v2.6 dll compiled with Avisynth Version 6 Header.
fvisagie
1st July 2015, 07:52
Very useful, thanks :).
Cheers,
François
jmac698
4th July 2016, 01:55
Hello,
Thanks for writing this plugin. I find it very useful.
Currently making use of this, this time for analyzing camera sensor noise in RAW frames. Basically want to answer the question, how many frames must I average for a given ISO to produce a noiseless picture, also to compute myself bias frames etc. (which are slight offsets as not every pixel is perfectly the same).
The addition of area parameters is really useful, because on the sensor a certain area is covered up by metal so that it's always completely dark, that is used for a calibration.
With the accumulated average, I can simply step through images, averaging them, until the MinMax reads 1 (or std dev reads some low value etc.). Read off the frame number, and that's the number of shots I need.
StainlessS
16th January 2019, 19:15
Showchannels() v0.09, new version see 1st post.
v0.9, 15 Jan 2019, Moved to VS2008, Added version resource + x64.
Kisa_AG
22nd January 2019, 15:48
...Added version resource + x64.
Hello!
Great, thank you!
Danette
6th February 2019, 03:21
Showchannels() v0.09, new version see 1st post.
v0.9, 15 Jan 2019, Moved to VS2008, Added version resource + x64.
StainlessS: I want to make sure that I understand the use of the screen coordinates aspect of ShowChannels. Perhaps the best way is through an example.
If I have a 720 x 480 AR, and want to select the area that would exclude 5% (36 pixels) along each edge, essentially analyzing the center 648 x 408 area, would I phrase the x,y,w,h coordinates as follows:
ShowChannels(36, 36, 648, 408)
StainlessS
6th February 2019, 03:24
Easiest, as in crop(36,36,-36,-36)
or
x=36
y=36
w=-36
h=-36
Danette
6th February 2019, 03:42
Easiest, as in crop(36,36,-36,-36)
or
x=36
y=36
w=-36
h=-36
Ahhhh, yes ...thanks.
Dogway
18th November 2021, 16:56
I noticed that the global variables are one frame late to current frame:
ShowChannels(SetVar=True,show=true)
scriptclip("""subtitle(string(SC_Min_0))""")
It also would be great to support HBD, 1/256 value jump is noticeable when doing levels or some sort of manipulation. Maybe an additional feature would be to flush values (maybe a third column) after a scene change. And support frameprops(?)
Gavino
18th November 2021, 18:10
I noticed that the global variables are one frame late to current frame:
ShowChannels(SetVar=True,show=true)
scriptclip("""subtitle(string(SC_Min_0))""")
You need to use ScriptClip(..., after_frame=true) so that the value is evaluated after the frame has been fetched from the filter above.
StainlessS
18th November 2021, 19:32
Thanks G.
It also would be great
Baring it in mind.
Dogway
18th November 2021, 20:10
Thanks Gavino! I'm making a soft limiter so I was thinking on feeding the (accumulated) loose minmax values, not sure how I can do it without HBD support, somehow I need to force the ShowChannels() call despite not using its output clip.
ColorYUV() has HBD support but didn't see how to extract values. I also want to add a per scene accumulated, a fast method is to reinitiate ShowChannels() after a scene change.
EDIT: Strange, new ScriptClip can't grab ShowChannels globals.
ShowChannels(SetVar=True,show=false)
ScriptClip( function [] () {
propSetArray("_YMin", function[]() { return [SC_Min_0,SC_Max_0] } )
}, after_frame=True )
propshow()
StainlessS
19th November 2021, 01:43
EDIT: ShowChannels SC_LMn_0 and SC_LMx_0 are LOOSE min and max.
You can also use YPlaneMin(Threshold=0.0) and YPlaneMax(Threshold=0.0) for Ymin and Ymax.
YPlaneMin(Threshold=whatever%) and YPlaneMax(Threshold=whatever%) for loose min/max,
if not interested in other values. (and builtin HBD)
EDIT: ShowChannels defo sets Globals [some of my plugs set locals because of some problem/request or other reported by user].
EDIT: I have no idea what your script snippet does, I have not yet figured out that scriptclip function stuff.
But, does this work
ScriptClip( function [] () {
propSetArray("_YMin", function[]() { return [YPlaneMin(0.0),YPlaneMax(0.0)] } )
}, after_frame=True ) # Maybe After_Frame not needed : Presumably YPlaneMin/Max will be using implicit Last (or something ???)
propshow()
Dogway
19th November 2021, 02:02
Yes, maybe I will do that for not accumulated, although that uses 0.4 percentile (?)
I wanted some kind of temporal average for the values.
I managed somewhat (https://github.com/Dogway/Avisynth-Scripts/blob/dec5a9bec0fd8c5d0e35d85facbba3e79c8d297c/TransformsPack.avsi#L2198)to pass the global vars to SoftLimiter, but with the old ScriptClip.
StainlessS
19th November 2021, 03:16
ColorYUV(analyse=true)
uses 0.4, actually total Y sample count / 256 for Y, and total Y sample count / 1024 for U and V (when YV12, so still 0.4).
[old v2.58 ColorYUV which I have source for].
ShowChannels uses default 0.1%.
Loose minimum uses the filter arg float MinPerc, a percentage of total pixels to ignore
when finding the loose minimum, allows to ignore extreme stray pixels.
Loose maximum uses the filter arg float MaxPerc, a percentage of total pixels to ignore
when finding the loose maximum, allows to ignore extreme stray pixels.
Same as loose minimum/maximum in ColorYUV Analyze=true
analyze can be true or false. This will print out color statistics on the screen.
There are maximum and minimum values for all channels.
There is an average for all channels.
There is a "loose maximum" and "loose minimum". The "loose" values are made to filter out very bright
or very dark noise creating an artificially low or high minimum / maximum.
YPlaneMin/YPlaneMax has the same sort of thing where what I've called 'MinPerc/MaxPerc' uses name of 'Threshold'.
YPlaneMin | v2.x | YPlaneMin(clip, float threshold)
YPlaneMax | v2.x | YPlaneMax(clip, float threshold)
threshold is a percentage, stating how many percent of the pixels are allowed above or below minimum.
The threshold is optional and defaults to 0.
# ...
Comment From ColorYUV source
// When 1/256th of all pixels have been reached, trigger "Loose min/max"
So ColorYUV ignores 1/256 of the darkest/lightest pixels, YPlaneMin ignores 0% default, and ShowChannels 0.1% or 1/1000 by default,
so a Minperc/Maxperc of 0.4% would be about the same as ColorYUV uses.
EDIT: Should it matter that TV levels range is 220 [not 256] ie 235-16+1, where is 1/220*100 = 0.45454 %.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.