View Full Version : MYStats v1.06, Masked YStats + RgbChanStats Combo
StainlessS
16th August 2013, 21:00
Runtime filter for both Y and RGB statistics
v1.06, Combined MRgbChanStats into MYStats plugin.
Probably last version unless bugs found. Will be integrated into RT_Stats.
Part 1 of Masked YStats + RgbChanStats Combo plugin
MYStats(), Avisynth v2.5+ Plugin by StainlessS
Combined with MRgbChanStats()
Planar, YUY2, RGB32 RGB24. (YV24 etc under Avisynth 2.6a4, as only scans luma)
Mask, Optional Mask clip Planar ONLY [v2.6 colorpspaces OK]
-------------------------------------------------------------
------------------- MYStats ---------------------
-------------------------------------------------------------
The compiletime/runtime clip functions share some common characteristics:-
The optional mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is
in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed. The Mask must also be Planar but not
necessarily the same colorspace as clip c, also must be same dimensions and have at least the same number of frames as clip c.
NOTE, as Mask clip now optional, to supply a Mask, you MUST explicitly supply BOTH source clip and Mask clip args, a single clip
will be interpreted as source clip without mask (as will no clips at all, where implicit Last clip would be used as source clip).
A Maskless function call will process all pixels in the selected area.
Calling with MaskMin=0,MaskMax=255 will effectively ignore the mask and scan full x,y,w,h area.
The 'n' arg is an optional frame number and defaults to 'current_frame' if not specified.
The x,y,w,h, coords specify the source rectangle under scrutiny and are specified as for Crop(), the default 0,0,0,0 is full frame.
If 'interlaced' is true, then every other line is ommited from the scan, so if eg y=1, then scanlines 1,3,5,7 etc are scanned,
if eg y=4 then scanlines 4,6,8,10 etc are scanned. The 'h' coord specifies the full height scan ie same whether interlaced is true
or false, although it will not matter if the 'h' coord is specified as eg odd or even, internally the height 'h' is reduced by 1
when interlaced=true and 'h' is even.
Compile time/runtime functions, Planar, YUY2, RGB24 & RGB32. (RGB internally converted to YUV-Y).
Matrix: Conversion matrix for conversion of RGB to YUV-Y Luma. 0=REC601 : 1=REC709 : 2 = PC601 : 3 = PC709, Default=width<=720 then 2 else 3.
Default is 2(PC601) if width <= 720 else 3(PC709) : YUV not used
***
***
***
MYPlaneMin(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "threshold"=0.0,int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns int value minimum luma (0 -> 255) in frame(n+delta) for area x,y,w,h.
Threshold is a percentage, stating how many percent of the pixels are allowed below minimum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0.
***
***
***
MYPlaneMax(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "threshold"=0.0,int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns int value maximum luma (0 -> 255) in frame(n+delta) for area x,y,w,h.
Threshold is a percentage, stating how many percent of the pixels are allowed above maximum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0.
***
***
***
MYPlaneMinMaxDifference(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns int value luma range (maximum - minimum difference) (0 -> 255) in frame(n+delta) for area x,y,w,h.
Threshold is a percentage, stating how many percent of the pixels are allowed below minimum or above maximum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0.
***
***
***
MYPlaneMedian(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns int value luma median [equiv MYPlaneMin(threshold=50.0)] (0 -> 255) in frame(n+delta) for area x,y,w,h.
***
***
***
MAverageLuma(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT value average luma (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h.
***
***
***
MYPlaneStdev(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT value luma Standard Deviation (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h.
Standard Deviation (Changed, from Sample Standard Deviation with Bessels Correction).
http://en.wikipedia.org/wiki/Standard_deviation
***
***
***
MYInRange(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "lo"=128,int "hi"=lo,int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT value (0.0 -> 1.0) being the amount of pixels in the range "lo" to "hi" (inclusive), 1.0 is equivalent to 100%.
Implemented as requested by Martin53 (thankyou), NOTE, differs from other funcs that return range 0.0 to 255.0.
NOTE, lo defaults to 128, "hi" defaults to "lo".
***
***
***
MYPNorm(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1, int "MaskMin"=128,"MaskMax"=255, int "Matrix"=(width<=720?2:3))
Return int -1 if no valid pixels in Mask clip.
Returns FLOAT value greater or equal to 0.0, being the "Minkowski P-norm" (range depends upon values of 'd' and 'u') for frame(n+delta)
area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
mu, Float, default 0.0 (0.0 -> 255.0)
d, int, default 1 (1 -> 255) # downscale
p, int, default 1 (1 -> 16) # power
u, int, default 1 (1 -> 255) # final upscale before returning result (experimental)
Formula is: sum_over_pixels[ ((pixel-mu)/d)^p ]^(1/p) * u
or in words: d and u are scaling aids. The differences between the pixel values and mu are scaled, taken to the power of p and added up
over the frame. The sum is taken to the p-th root and finally rescaled.
mu=0, d=1, p=1, u=1 yields the average.
mu=average, d=1, p=2, u=1 yields the standard deviation (uncorrected sample standard deviation).
Implemented as requested by Martin53 (thankyou). EXPERIMENTAL
http://en.wikipedia.org/wiki/P-norm#The_p-norm_in_finite_dimensions
http://en.wikipedia.org/wiki/Minkowski_distance
***
***
***
MYstats(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "threshold"=0.0,int "lo"=128,int "hi"=lo,int "flgs"=255,string "prefix"="MYS_",int "MaskMin"=128,"MaskMax"=255,
float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1, int "Matrix"=(width<=720?2:3))
Returns multiple results as for above single frame Luma sampling functions as Global Variables (prefixed with the prefix string arg).
The args up to "interlaced", are as for all other clip functions, "threshold" used only for "MYPlaneMin", "MYPlaneMax" and
"MYPlaneMinMaxDifference" equivalent routines with same functionality.
"lo" and "hi" are used only with the "MYInRange" equivalent routine with same functionality.
"mu" and "d" and "p" and "u" are used only with the "MYPNorm" equivalent routine with same functionality.
The new arg "Flgs" selects which results you want returned and the string "Prefix" that is prepended
to the returned global variable names.
The actual return result is a copy of the flgs args with any non valid bits reset, ie the global variables that were set.
Global variables are NOT altered for any function not selected in flgs.
Returns 0 if no pixels found in search area of mask within MaskMin and MaskMax.
Flgs_Bit_Number Add_To_Flgs Equivalent_Function Global_Var_Set_Excluding_Prefix
0 1($01) MYPlaneMin() "yMin" (0->255)
1 2($02) MYPlaneMax() "yMax" (0->255)
2 4($04) MYPlaneMinMaxDifference() "yMinMaxDiff" (0->255)
3 8($08) MYPlaneMedian() "yMed" (0->255)
4 16($10) MAverageLuma() "yAve" (0.0->255.0)
5 32($20) MYPlaneStdev() "yStdev" (0.0->255.0)
6 64($40) MYInRange() "yInRng" (0.0->1.0)
7 128($80) MYPNorm() "yPNorm" (0.0->??? depends upon d and u)
MYstats() allows you to inquire multiple results simultaneously, with not much more overhead than calling a single individual
routine, however, you should not select sub functions that you dont need as there may be an additional unnecessary overhead.
The Default flgs=255($FF) are all bits set and so sets ALL global vars at once.
MYstats(flgs=1+2+16) would set global vars "MYS_yMin", "MYS_yMax" and "MYS_yAve" for full frame current_frame.
In addition to above Global Variables, MYStats() sets an int Global variable (where default prefix) of "MYS_PixelCount" being
the number of pixels in mask area X,Y,W,H between MaskMin and MaskMax inclusive, or pixels scanned in X,Y,W,H area where mask
not used.
See 2nd post for added MRgbChanStats docs.
See below MediaFire in sig.
StainlessS
16th August 2013, 21:01
Part 2 of Masked YStats + RgbChanStats Combo plugin
-------------------------------------------------------------
------------------- MRgbChanStats ---------------------
-------------------------------------------------------------
RGB32, RGB24 source clip. (Optional Mask clip Planar ONLY [v2.6 colorpspaces OK])
The compiletime/runtime clip functions share some common characteristics:-
The source clip c must be RGB32 or RGB24.
The optional Planar mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is
in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed.
Mask MUST, be same dimensions and have at least the same number of frames as clip c.
NOTE, as Mask clip now optional, to supply a Mask, you MUST explicitly supply BOTH source clip and Mask clip args, a single clip
will be interpreted as source clip without mask (as will no clips at all, where implicit Last clip would be used as source clip).
A Maskless function call will process all pixels in the selected area.
Calling with MaskMin=0,MaskMax=255 will effectively ignore the mask and scan full x,y,w,h area.
The 'n' arg is an optional frame number and defaults to 'current_frame' if not specified.
The x,y,w,h, coords specify the source rectangle under scrutiny and are specified as for Crop(), the default 0,0,0,0 is full frame.
If 'interlaced' is true, then every other line is ommited from the scan, so if eg y=1, then scanlines 1,3,5,7 etc are scanned,
if eg y=4 then scanlines 4,6,8,10 etc are scanned. The 'h' coord specifies the full height scan ie same whether interlaced is true
or false, although it will not matter if the 'h' coord is specified as eg odd or even, internally the height 'h' is reduced by 1
when interlaced=true and 'h' is even.
The Chan arg specifies which R or G or B channel to process [the multi-functional MRgbChanStats() function also allows a Chan arg of -1,
which processes R and G and B simulaneously for all functions selected by flgs arg, also allowed is chan arg of -2 which additionally
processes the ALPHA channel if RGB32 but throws an error if RGB24].
Default Chan is 0 (Red), 1 = Green, 2=Blue channel and 3=ALPHA channel when RGB32 ONLY else error.
***
***
***
MRgbChanMin(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,
int "chan"=0, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int minimum value (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
Threshold is a percentage, stating how many percent of the pixels are allowed below minimum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0.
***
***
***
MRgbChanMax(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,
int "chan"=0, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int maximum value (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
Threshold is a percentage, stating how many percent of the pixels are allowed above maximum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0
***
***
***
MRGBChanMinMaxDifference(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,
int "chan"=0, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int channel range [maximum - minimum difference] (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel
(0=R,1=G,2=B, RGB32 3=ALPHA)
Threshold is a percentage, stating how many percent of the pixels are allowed below minimum or above maximum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold defaults to 0.0
***
***
***
MRGBChanMedian(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int channel median [equiv MRgbChanMin(threshold=50.0)] (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel
(0=R,1=G,2=B, RGB32 3=ALPHA)
***
***
***
MRGBChanAve(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT average channel value (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA).
***
***
***
MRGBChanStdev(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT Standard Deviation channel value(0.0 -> 255.0) in frame(n+delta) for area x,y,w,h, and selected Chan channel
(0=R,1=G,2=B, RGB32 3=ALPHA)
Standard Deviation. http://en.wikipedia.org/wiki/Standard_deviation
***
***
***
MRGBChanInRange(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "lo"=128,int "hi"=lo,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT value (0.0 -> 1.0) being the amount of pixels in the range "lo" to "hi" (inclusive) in frame(n+delta) for area x,y,w,h,
and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA), 1.0 is equivalent to 100%.
Implemented as requested by Martin53 (thankyou), NOTE, differs from other funcs that return range 0.0 to 255.0.
NOTE, lo defaults to 128, "hi" defaults to "lo".
***
***
***
MRGBChanPNorm(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1, int "MaskMin"=128,"MaskMax"=255)
Return int -1 if no valid pixels in Mask clip.
Returns FLOAT value greater or equal to 0.0, being the "Minkowski P-norm" (range depends upon values of 'd' and 'u') for frame(n+delta)
area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
mu, Float, default 0.0 (0.0 -> 255.0)
d, int, default 1 (1 -> 255) # downscale
p, int, default 1 (1 -> 16) # power
u, int, default 1 (1 -> 255) # final upscale before returning result (experimental)
Formula is: sum_over_pixels[ ((pixel-mu)/d)^p ]^(1/p) * u
or in words: d and u are scaling aids. The differences between the pixel values and mu are scaled, taken to the power of p and added up
over the frame. The sum is taken to the p-th root and finally rescaled.
mu=0, d=1, p=1, u=1 yields the average.
mu=average, d=1, p=2, u=1 yields the standard deviation (uncorrected sample standard deviation).
Implemented as requested by Martin53 (thankyou). EXPERIMENTAL
http://en.wikipedia.org/wiki/P-norm#The_p-norm_in_finite_dimensions
http://en.wikipedia.org/wiki/Minkowski_distance
***
***
***
MRGBChanStats(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "threshold"=0.0,int "chan"=0,int "lo"=128,int "hi"=lo,int "flgs"=255,string "prefix"="MRCS_",int "MaskMin"=128,"MaskMax"=255,
float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1)
Returns multiple results as for above single frame RGB channel sampling functions as Global Variables (prefixed with the prefix string arg).
The args up to "interlaced", are as for all other clip functions, "threshold" used only for "MRgbChanMin", "MRgbChanMax" and
"MRGBChanMinMaxDifference" equivalent routines with same functionality.
"lo" and "hi" are used only with the "MRGBChanInRange" equivalent routine with same functionality.
"mu" and "d" and "p" and "u" are used only with the "MRGBChanPNorm" equivalent routine with same functionality.
The new arg "Flgs" selects which results you want returned and the string "Prefix" that is prepended
to the returned global variable names.
The actual return result is a copy of the flgs args with any non valid bits reset, ie the global variables that were set.
Global variables are NOT altered for any function not selected in flgs.
Returns 0 if no pixels found in search area of mask within MaskMin and MaskMax.
Flgs_Bit_Number Add_To_Flgs Equivalent_Function Global_Var_Set_Excluding_Prefix_and_Chan_postfix
0 1($01) MRGBChanMin() "Min" (0->255)
1 2($02) MRGBChanMax() "Max" (0->255)
2 4($04) MRGBChanMinMaxDifference() "MinMaxDiff" (0->255)
3 8($08) MRGBChanMedian() "Med" (0->255)
4 16($10) MRGBChanAve() "Ave" (0.0->255.0)
5 32($20) MRGBChanStdev() "Stdev" (0.0->255.0)
6 64($40) MRGBChanInRange() "InRng" (0.0->1.0)
7 128($80) MRGBChanPNorm() "PNorm" (0.0->??? depends upon d and u)
The Channel Postfix is of the form "_0", where 0 is RED, 1 is GREEN and 2 is Blue, 3 is ALPHA(RGB32 ONLY), and is appended to the
base name described above. So eg MRGBChanMin for RED channel 0 with default Prefix is "MRCS_Min_0".
MRGBChanstats() allows you to inquire multiple results simultaneously, with not much more overhead than calling a single individual
routine, however, you should not select sub functions that you dont need as there may be an additional unnecessary overhead.
The Default flgs=255($FF) are all bits set and so sets ALL global vars at once.
MRGBChanStats(flgs=1+2+16) would set global vars "MRCS_Min_0", "MRCS_Max_0" and "MRCS_Ave_0" for full frame current_frame, Red Channel.
In addition to above Global Variables, MRGBChanStats() sets an int Global variable (where default prefix) of "MRCS_PixelCount_0" being
the number of Red Channel pixels in mask area X,Y,W,H between MaskMin and MaskMax inclusive, or pixels scanned in X,Y,W,H area
where mask not used.
NOTE, MRGBChanStats() allows Chan to be -1, where ALL three R, and G, and B channels are processed simultaneouly for ALL functions
selected by flgs arg (ALPHA Channel is NOT processed).
A chan arg of -2 (RGB32 ONLY allowed) will additionally process the ALPHA channel as well as R+G+B.
Also Note, (where default Prefix) MRCS_PixelCount_x is also set (identically) for all channels when Chan == -1 or -2.
#############################################
StainlessS
StainlessS
18th August 2013, 06:53
Update v1.02beta.
Experimental version with additional DEBUG dll.
Added two MYPNorm simulating scripts [UPDATED].
1 MYStdev() simulation
# Requires RT_Stats()
Avisource("D:\avs\TEST.avi")
Mask=Avisource("D:\avs\TESTMASK.avi") # Create with eg Martin53_MakeMask.avs
#Mask=RT_Undefined() # Un-Comment: Test MASKLESS (ie full source frame scan)
MaskMin=128
MaskMax=255
############### PNorm Stdev simulated mode
#MU =0.0 # float, 0.0 -> 255.0, (default 0.0), for StdDev we use MU=MAverageLuma()
DIV =1 # int, 1 -> 255, (default 1)
POWER =2 # int, 1 -> 16, (default 1)
UPSCALE =1 # int, 1 -> 255, (default 1)
###############
FLG_STDEV = 32
FLG_PNORM = 128
MY_FLGS = FLG_STDEV + FLG_PNORM
S1="%d ]\n\aeNO VALID PIXELS IN MASK"
S2="%d ]\nStdev=%f\nPNorm=%f\n\nPixelCount=%d"
# *** WARNING ***, MUST explicitly supply BOTH clip args to use MASK, as MASK now optional 1 (or 0) clips interpreted as MASKLESS.
ScriptClip("""
MU=MAverageLuma(Last,Mask,MaskMin=MASKMIN,MaskMax=MASKMAX)
flgs=(MU<0) ? 0 : MYStats(Last,Mask,flgs=MY_FLGS,MaskMin=MASKMIN,MaskMax=MASKMAX,mu=MU,d=DIV,p=POWER,u=UPSCALE)
(flgs==0) ? RT_Subtitle(S1,current_frame) : RT_Subtitle(S2,current_frame,MYS_ystdev,MYS_yPNorm,MYS_PixelCount)
return Last
""")
return (Defined(Mask)) ? StackHorizontal(Mask) : Last
2 MAverageLuma() simulation.
# Requires RT_Stats()
Avisource("D:\avs\TEST.avi")
Mask=Avisource("D:\avs\TESTMASK.avi") # Create with eg Martin53_MakeMask.avs
#Mask=RT_Undefined() # Un-Comment: Test MASKLESS (ie full source frame scan)
MaskMin=128
MaskMax=255
############### PNorm AveLuma simulated mode (DEFAULT):
MU =0.0 # float, 0.0 -> 255.0 (default 0.0)
DIV =1 # int, 1 -> 255 (default 1)
POWER =1 # int, 1 -> 16 (default 1)
UPSCALE =1 # int, 1 -> 255 (default 1)
###############
FLG_AVE = 16
FLG_PNORM = 128
###############
MY_FLGS = FLG_AVE + FLG_PNORM
S1="%d ]\n\aeNO VALID PIXELS IN MASK"
S2="%d ]\nAve =%f\nPNorm=%f\n\nPixelCount=%d"
# *** WARNING ***, MUST explicitly supply BOTH clip args to use MASK, as MASK now optional 1 (or 0) clips interpreted as MASKLESS.
ScriptClip("""
flgs=MYStats(Last,Mask,flgs=MY_FLGS,MaskMin=MASKMIN,MaskMax=MASKMAX,mu=MU,d=DIV,p=POWER,u=UPSCALE)
(flgs==0) ? RT_Subtitle(S1,current_frame) : RT_Subtitle(S2,current_frame,MYS_yAve,MYS_yPNorm,MYS_PixelCount)
return Last
""")
return (Defined(Mask)) ? StackHorizontal(Mask) : Last
see first post
EDIT: Snippet of source of MYPNorm()
if(flgs & RTPNORM_F) {
const double mu_d =double(mu);
const double div_d =double(div);
const double power_d=double(power);
double Sum_DiffPowered = 0.0;
// At this point Pixels known to be > 0, otherwise function already returned 0
for (i=256;--i>=0;) {
const int count=cnt[i]; // EDIT: Count of pixels with value i
if(count) {
double diff = i - mu_d; // -255.0 -> 255.0
if (div>1)
diff /= div_d;
if (power>1)
diff = pow(diff, power_d); // (-255.0 -> 255.0) ^ power
// power may be even or odd, but integer. So diff can be positive or negative.
Sum_DiffPowered += diff * (double)count;
}
}
double DiffPowered = Sum_DiffPowered / Pixels;
double pn;
if(DiffPowered >= 0.0) {
pn = pow(DiffPowered, 1.0 / power_d);
} else {
pn = - (pow(- DiffPowered, 1.0 / power_d));
}
#ifdef _DEBUG
// floating point error flags (eg 1.0/3.0 gives _EM_INEXACT, we dont care)
unsigned int e = (_clearfp() & ~_EM_INEXACT);
if(e) {
dprintf("MYPNorm: ***ERROR*** E=%X mu=%f div=%d power=%d\n",e,mu_d,div,power);
dprintf("MYPNorm: DiffPowered=%f 1/p=%f pn=%f\n",DiffPowered, 1.0 / power_d,pn);
}
#endif
pn = pn * double(up);
// ensure fits in float for client
if(pn>0.0) {
if(pn > FLT_MAX) pn = FLT_MAX;
else if(pn < FLT_MIN) pn = FLT_MIN;
} else if(pn<0.0) {
if(pn < -FLT_MAX) pn = -FLT_MAX;
else if(pn > -FLT_MIN) pn = -FLT_MIN;
}
ylo.ddat[RTPNORM-RTAVE] = pn;
}
martin53
18th August 2013, 11:08
:thanks: StainlessS!
I implemented MYPNorm(), and the AWB script behaves as before, so there is no obvious bug (AviSynth V2.60 Jan 14 2013). Hopefully the plugin enhances the script precision, I'll keep you informed.
This is what the AWB script looked like before, and still was inaccurate:
...
cR = ShowRed(pixel_type="Y8")
cG = ShowGreen(pixel_type="Y8")
cB = ShowBlue(pixel_type="Y8")
# For the 'shades of gray' algorithm, its P-norm requires that the values are taken to the power of 6 before being averaged.
# The average statistics functions do not offer this feature. So, at the expense of resolution/precision, the whole clip luma is preprocessed.
# A luma value of 91 will produce a value a little above 0.5, i.e. will be a "1" luma in the target clip. (The formula is (91/255)^6 * 255)
# Luma below 91 produces zero, i.e. is not taken into account at all.
# To lose as little resolution as possible, luma is not generally divided by 255 here, but by the maximum luma of each plane.
# These varying scaling factors must be measured in the statistics evaluation.
# Mt_lutf(mode="max") evaluates the same number for the division, which is inefficient, but I see no way to measure only once.
GScript(""" # "
if (POWER != 1) {
s = mt_polish("(y/x)^"+string(POWER)+"*255")
cRP = mt_lutf(cR, cR, "max", expr=s)
cGP = mt_lutf(cG, cG, "max", expr=s)
cBP = mt_lutf(cB, cB, "max", expr=s)
} else {
cRP = cR # only dummies to satisfy GScriptClip's 'args' string
cGP = cG
cBP = cB
}
""") # "
...
GScriptClip("GScript("+chr(34)+chr(34)+chr(34)+""" # "
...
if (POWER != 1) {
fRscale = cR.YPlaneMax
fGscale = cG.YPlaneMax
fBscale = cB.YPlaneMax
}
...
# Retrieve the statistical process parameters from the statistics clips
if (POWER != 1) {
R_ = pow(cRP.MAverageLuma(cMGamut, x=border, y=border, w=dx, h=dy), 1.0/POWER) * fRscale/255
G_ = pow(cGP.MAverageLuma(cMGamut, x=border, y=border, w=dx, h=dy), 1.0/POWER) * fGscale/255
B_ = pow(cBP.MAverageLuma(cMGamut, x=border, y=border, w=dx, h=dy), 1.0/POWER) * fBscale/255
} else {
R_ = cR.MAverageLuma(cMGamut, x=border, y=border, w=dx, h=dy)
G_ = cG.MAverageLuma(cMGamut, x=border, y=border, w=dx, h=dy)
B_ = cB.MAverageLuma(cMGamut, x=border, y=border, w=dx, h=dy)
}
...
"""+chr(34)+chr(34)+chr(34)+")", args="c, cR, cG, cB, cRP, cGP, cBP, cMGamut, amount, border, tiles, sR, sG, sB, pt1, rules, haze, ExtColRange, POWER, P, THRESH, info")
Now it's just:
...
cR = ShowRed(pixel_type="Y8")
cG = ShowGreen(pixel_type="Y8")
cB = ShowBlue(pixel_type="Y8")
...
GScriptClip("GScript("+chr(34)+chr(34)+chr(34)+""" # "
...
# Retrieve the statistical process parameters from the statistics clips
R_ = cR.MYPNorm(cMGamut, x=border, y=border, w=dx, h=dy, d=255, p=POWER, u=255)
G_ = cG.MYPNorm(cMGamut, x=border, y=border, w=dx, h=dy, d=255, p=POWER, u=255)
B_ = cB.MYPNorm(cMGamut, x=border, y=border, w=dx, h=dy, d=255, p=POWER, u=255)
...
"""+chr(34)+chr(34)+chr(34)+")", args="c, cR, cG, cB, cMGamut, amount, border, tiles, sR, sG, sB, pt1, rules, haze, ExtColRange, POWER, P, THRESH, info")
StainlessS
18th August 2013, 17:16
:Hopefully the plugin enhances the script precision
Should be, as computation all done in double precision before conversion to float for return to Avisynth.
Give further instructions, like the 'u' optional upscale ?
Maybe could allow power 'p' up to eg 16 (test program used fails when 'p' taken up to 20, some kind of DENORMALIZATION error flag if I remember correctly). Would like to keep a little 'Chicken Factor'.
EDIT: Here the test program used (bit of a hack)
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#define POWER 12 // 19 power OK without Error
int main(int argc, char* argv[])
{
int err=0;
unsigned int e;
double mu;
int div,power;
int Pixels = 8192*8192; // BIG frame, Assuming ALL pixels valid in mask
int up,i;
up=255;
for(mu=255.0; mu>=0.0;mu -= 0.1) {
printf("MU=%f Err=%d\n",mu,err);
for(div=1;div<256;++div) {
for(power=1;power <= POWER;++power) {
const double div_d = (double)div;
const double power_d=double(power);
double Sum_DiffPowered = 0.0;
const int count = Pixels;
for (i=256;--i>=0;) {
e=0;
double diff = i - mu; // -255.0 -> 255.0
if (div>1)
diff /= div_d;
if (power>1)
diff = pow(diff, power_d); // (-255.0 -> 255.0) ^ power
// power may be even or odd, but integer. So diff can be positive or negative.
Sum_DiffPowered = diff * (double)count;
double DiffPowered = Sum_DiffPowered / Pixels; // undo previous line (count and pixels same)
double pn;
if(DiffPowered >= 0.0) {
pn = pow(DiffPowered, 1.0 / power_d);
} else {
pn = - (pow(- DiffPowered, 1.0 / power_d));
}
// floating point error flags (eg 1.0/3.0 gives _EM_INEXACT, we dont care)
e = (_clearfp() & ~_EM_INEXACT);
if(e) {
++err;
printf("1 Err=%d FLGS=%X mu=%f div=%d power=%d i=%d\n",err,e,mu,div,power,i);
printf("DiffPowered=%f 1/p=%f pn=%f\n",DiffPowered, 1.0 / power_d,pn);
}
pn = pn * double(up);
e |= (_clearfp() & ~_EM_INEXACT);
if(e) {
++err;
printf("2 Err=%d FLGS=%X mu=%f div=%d power=%d i=%d\n",err,e,mu,div,power,i);
printf("pn=%f\n",pn);
goto end;
}
}
}
}
}
end:
return 0;
}
Martin53, just curious, what purpose does this fulfill ?
GScript(""" # "
...
""") # "
You seem to use it a lot.
martin53
18th August 2013, 18:06
Martin53, just curious, what purpose does this fulfill ?
GScript(""" # "
...
""") # "
I edit .AVSI files in Notepad++. It has a syntax formatter for AviSynth (but not for GScript). The formatter loses track after triple quotes, displays all following text as string. The single quote comment puts Notepad++ on track again.
StainlessS
18th August 2013, 18:28
Thank you, that salves that itch.
StainlessS
18th August 2013, 23:25
M53
How bout missing mask clip arg, processes all ?
StainlessS
19th August 2013, 16:39
Update to v1.02b.
Can now call without mask where entire selected area processed.
(EDIT: faster than eg mask=source, Maskmin=0, Maskmax=255)
The optional mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is
in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed. The Mask must also be Planar but not
necessarily the same colorspace as clip c, also must be same dimensions and have at least the same number of frames as clip c.
NOTE, as Mask clip now optional, to supply a Mask, you MUST explicitly supply BOTH source clip and Mask clip args, a single clip
will be interpreted as source clip without mask (as will no clips at all, where implicit Last clip would be used as source clip).
Change MYPNorm power 'p' to 16 (from 12).
Added MYS_PixelCount Global variable (with default prefix) to MYStats() func.
In addition to above Global Variables, MYStats() sets an int Global variable (where default prefix) of "MYS_PixelCount" being
the number of pixels in mask area X,Y,W,H between MaskMin and MaskMax inclusive, or pixels scanned in X,Y,W,H area where mask
not used.
Scripts in post #3 updated.
martin53
19th August 2013, 19:46
Both very useful enhancements! Thanks you took the effort to implement them even without external request.
EDIT: I assume the p limit of 19 occurred with div<255? If so, could you recheck if the p limitation can be removed (loosened) in the case of d==255?
martin53
19th August 2013, 22:19
StainlessS,
there is a thing that I don't understand at the moment. With the following lines and constants
/*
ymin = 255 #user parameter
ymax = 255 #user parameter
border = 0 #user parameter
dx = clip.width
dy = clip.height
p = 6
cMGamut = c.YTo8() #in my situation also 0 for disallowed pixels in contrast to the simplified example here
cR = c.ConvertToRGB.ShowRed(pixel_type="Y8")
Rmax = cR.MYPlaneMax(cMGamut, x=border, y=border, w=dx, h=dy, MaskMin=1, MaskMax=255)
R_ = cR.MYPNorm(cMGamut, x=border, y=border, w=dx, h=dy, d=255, p=power, MaskMin=max(min(ymin, Rmax-10),0), MaskMax=ymax)
I get Rmax == 255, but R_ == -1.
When I measure Rmax before, so I get the max brightness of the masked pixels, shouldn't I get with MaskMin = Rmax-10, and MaskMax = 255 at least 1 pixel?
StainlessS
19th August 2013, 22:40
what is YTo8 ? [Y to Y8 ?]
StainlessS
20th August 2013, 00:41
I think you just sent me on a wild goose chase.
Say we got only 1 pixel (w=1,h=1) , value 255, and 1 mask pixel value 1, maskmin=1,maskmax=255, result RMax=255.
now maskmin=255-10,maskmax=255, result R_ =-1, not found, because the mask pixel is still only 1, a long way from 245->255 mask range we are searching for.
Nice hoax :)
EDIT:
PS, you should get same result R_ = -1 from any of the alternative funcs.
Maybe you ought to search with source = mask, and mask = mask (or maskless), maskmin=1,maskmax=255, to find max in mask.
martin53
20th August 2013, 17:37
Uh, thanks, seems I was overtired yesterday. Of course you're right, just because I find a pixel in the mask does not say anything about the mask itself --- if I give no additional information about the mask! And YTo8 :o, you guessed right.
The underlying problem I was trying to solve is this:
In real world, there are many colored objects, often walls etc. are painted/plastered/decorated in colors somewhere between vanilla and apricot.
The mask shows all pixels in a color range that could be something more or less white or grey, it masks out pixels in color ranges too blue, too red, to green etc. The previously mentioned colors are exposed by the mask.
In advance, the algorithm does not know the brightness of the brightest pixels exposed by the mask - that's what the Rmax= assignment is for.
With this knowledge, I'd like to ignore as many of the previously mentioned colored pixels, because they bias the colour estimation. Only bright spots are typically light sources or reflections and indicate the colour of the illuminant. That is why for the estimation step R_= ..., MaskMin should be set high in order to ignore the coloured pixels.
The mask is created in the following way, and this introduces an important relation between the source and the mask: If a pixel's colour is outside the interesting range, the mask is 0. Otherwise the mask is the luma of the pixel.
Now of course, just because the luma of the pixel is, say, 100, and thus the mask is 100, the red component R_ can still be far below 100. So I needed to create three masks, not with luma but with R, G and B, and then I could use Rmax to restrict MaskMin, I think.
martin53
20th August 2013, 17:42
StainlessS,
after you made the mask clip optional: do I feel right that MYStats is now a fully compatible superset of the similar RT_Stats functions?
What is your opinion about merging the two, so for future work, only one place needs rework, before many others use both plugins?
StainlessS
20th August 2013, 17:48
Well was about to say that I can up a test version of RGB channel variant, (still planar mask for RGB24/32),
maybe could do additional plug with eg RGB OR 3 planar masks where all masks have to be within range.
I'll try to up RGB variant within the hour, consider if RGB/3 Planar is required.
EDIT: Would break scripts, rather keep separate.
EDIT: I guess I could implement separate interfaces.
StainlessS
20th August 2013, 18:40
MRGBChanStats v1.02beta
LINK REMOVED
"MRGBChanMin", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMax", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMinMaxDifference", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMedian", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MAChanAve", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanStdev", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanInRange", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[lo]i[hi]i[MaskMin]i[MaskMax]i"
"MRGBChanPNorm", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[mu]f[d]i[p]i[u]i[MaskMin]i[MaskMax]i"
"MRGBChanStats","c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[lo]i[hi]i[flgs]i[prefix]s[MaskMin]i[MaskMax]i[mu]f[d]i[p]i[u]i"
MRGBChanStats(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "threshold"=0.0,int "Chan"=0,int "lo"=128,int "hi"=lo,int "flgs"=255,string "prefix"="MRCS_",int "MaskMin"=128,"MaskMax"=255,
float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1)
Flgs_Bit_Number Add_To_Flgs Equivalent_Function Global_Var_Set_Excluding_Prefix_and_Chan_postfix
0 1($01) MRGBChanMin() "Min" (0->255)
1 2($02) MRGBChanMax() "Max" (0->255)
2 4($04) MRGBChanMinMaxDifference() "MinMaxDiff" (0->255)
3 8($08) MRGBChanMedian() "Med" (0->255)
4 16($10) MRGBChanAve() "Ave" (0.0->255.0)
5 32($20) MRGBChanStdev() "Stdev" (0.0->255.0)
6 64($40) MRGBChanInRange() "InRng" (0.0->1.0)
7 128($80) MRGBChanPNorm() "PNorm" (0.0->??? depends upon d and u)
The Channel Postfix is of the form "_0", where 0 is RED, 1 is GREEN and 2 is Blue, 3 is ALPHA, and is appended to the
base name described above. So eg MRGBChanMin for RED channel 0 with default Prefix is "MRCS_Min_0".
MRGBChanstats() allows you to inquire multiple results simultaneously, with not much more overhead than calling a single individual
routine, however, you should not select sub functions that you dont need as there may be an additional unnecessary overhead.
The Default flgs=255($FF) are all bits set and so sets ALL global vars at once.
MRGBChanStats(flgs=1+2+16) would set global vars "MRCS_Min_0", "MRCS_Max_0" and "MRCS_Ave_0" for full frame current_frame, Red Channel.
In addition to above Global Variables, MRGBChanStats() sets an int Global variable (where default prefix) of "MRCS_PixelCount_0" being
the number of Red Channel pixels in mask area X,Y,W,H between MaskMin and MaskMax inclusive, or pixels scanned in X,Y,W,H area
where mask not used.
EDIT: Forgot something, above zip TAKE 2.
martin53
5th September 2013, 21:05
StainlessS,
it's great you implemented MRGBChanStats already - I almost forgot and was about to ask you for it.
I once promised to add a doc snippet to the PNorm, here is my suggestion:
MYPNorm(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1, int "MaskMin"=128,"MaskMax"=255)
Return int -1 if no valid pixels in Mask clip.
Returns FLOAT value greater or equal to 0.0, being the "Minkowski P-norm" (range depends upon values of 'd' and 'u').
Formula is: sum_over_pixels[ ((pixel-mu)/d)^p ]^(1/p) * u
or in words: d and u are scaling aids. The differences between the pixel values and mu are scaled, taken to the power of p and added up over the frame. The sum is taken to the p-th root and finally rescaled.
mu=0, d=1, p=1, u=1 yields the average.
mu=average, d=1, p=2, u=1 yields the standard deviation (uncorrected sample standard deviation).
Implemented as requested by Martin53 (thankyou).
http://en.wikipedia.org/wiki/P-norm#The_p-norm_in_finite_dimensions
http://en.wikipedia.org/wiki/Minkowski_distance
martin53
5th September 2013, 21:32
Please comment if I use the functions as intended.
Given task: to find the average R, G and B values of the brightest pixels in the frame.
Note: There can be any number of pixels sharing the 'same brightness' (having the same quantized Y) and they may still have slightly different individual R, G and B values.
Use the collective function to yield all values with one call.
c is the YUV input clip.
cRGB = c.ConvertToRGB()
Ymax = c.YPlaneMax()
MRGBChanStats(cRGB, c, Chan=0, MaskMin=Ymax)
MRGBChanStats(cRGB, c, Chan=1, MaskMin=Ymax)
MRGBChanStats(cRGB, c, Chan=2, MaskMin=Ymax)
RT_Debug("R G B of max Y", string(MRCS_Ave_0), string(MRCS_Ave_1), string(MRCS_Ave_2))
I am excited that the mask can be a non-RGB clip!
StainlessS
7th September 2013, 13:40
Please comment if I use the functions as intended.
Looks about right, although you would be using default flgs=$FF,
ie all function results returned at once (a bit slower, average function alone is handled separately as a special case [no count array needed] and so is faster). If you also request the eg min function, you might derive info about how good the average is, ie if same then meaningful result, not same then less meaningful. (EDIT: where multiple dissimilar pixels yielding similar YPlaneMax)
I am excited that the mask can be a non-RGB clip!
You foreigners are an excitable bunch. :)
PS, thanx for the docs.
EDIT: Oops, somehow MRGBChanAve got squished, and dont work:
"MRGBChanMin", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMax", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMinMaxDifference", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMedian", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MAChanAve", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanStdev", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanInRange", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[lo]i[hi]i[MaskMin]i[MaskMax]i"
"MRGBChanPNorm", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[mu]f[d]i[p]i[u]i[MaskMin]i[MaskMax]i"
"MRGBChanStats","c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[lo]i[hi]i[flgs]i[prefix]s[MaskMin]i[MaskMax]i[mu]f[d]i[p]i[u]i"
Fixing it it now and adding to MRGBChanStats chan = -1 option, to get R + G + B (NOT ALPHA) channels at once for all flgs functions.
StainlessS
8th September 2013, 03:57
M53, find here fix for previous post edit bug, + mods + Docs.
MRgbChanStats() v1.03Beta, Here:
LINK REMOVED
MRgbChanStats(), Avisynth v2.5 Plugin by StainlessS
RGB32, RGB24 source clip. (Optional Mask clip Planar ONLY [v2.6 colorpspaces OK])
The compiletime/runtime clip functions share some common characteristics:-
The source clip c must be RGB32 or RGB24.
The optional Planar mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is
in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed.
Mask MUST, be same dimensions and have at least the same number of frames as clip c.
NOTE, as Mask clip now optional, to supply a Mask, you MUST explicitly supply BOTH source clip and Mask clip args, a single clip
will be interpreted as source clip without mask (as will no clips at all, where implicit Last clip would be used as source clip).
A Maskless function call will process all pixels in the selected area.
The 'n' arg is an optional frame number and defaults to 'current_frame' if not specified.
The x,y,w,h, coords specify the source rectangle under scrutiny and are specified as for Crop(), the default 0,0,0,0 is full frame.
If 'interlaced' is true, then every other line is ommited from the scan, so if eg y=1, then scanlines 1,3,5,7 etc are scanned,
if eg y=4 then scanlines 4,6,8,10 etc are scanned. The 'h' coord specifies the full height scan ie same whether interlaced is true
or false, although it will not matter if the 'h' coord is specified as eg odd or even, internally the height 'h' is reduced by 1
when interlaced=true and 'h' is even.
The Chan arg specifies which R or G or B channel to process [the multi-functional MRgbChanStats() function also allows a Chan arg of -1,
which processes R and G and B simulaneously for all functions selected by flgs arg, also allowed is chan arg of -2 which additionally
processes the ALPHA channel if RGB32 but throws an error if RGB24].
Default Chan is 0 (Red), 1 = Green, 2=Blue channel and 3=ALPHA channel when RGB32 ONLY else error.
***
***
***
MRgbChanMin(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,
int "chan"=0, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int minimum value (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
Threshold is a percentage, stating how many percent of the pixels are allowed below minimum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0.
***
***
***
MRgbChanMax(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,
int "chan"=0, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int maximum value (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
Threshold is a percentage, stating how many percent of the pixels are allowed above maximum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold is optional and defaults to 0.0
***
***
***
MRGBChanMinMaxDifference(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
bool "interlaced"=false,float "threshold"=0.0,
int "chan"=0, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int channel range [maximum - minimum difference] (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel
(0=R,1=G,2=B, RGB32 3=ALPHA)
Threshold is a percentage, stating how many percent of the pixels are allowed below minimum or above maximum (ignore extreme pixels ie noise).
Threshold is % of all pixels in selected area if Maskless, OR % of valid mask pixels processed if Mask supplied.
The threshold defaults to 0.0
***
***
***
MRGBChanMedian(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns int channel median [equiv MRgbChanMin(threshold=50.0)] (0 -> 255) in frame(n+delta) for area x,y,w,h, and selected Chan channel
(0=R,1=G,2=B, RGB32 3=ALPHA)
***
***
***
MRGBChanAve(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT average channel value (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA).
***
***
***
MRGBChanStdev(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT Standard Deviation channel value(0.0 -> 255.0) in frame(n+delta) for area x,y,w,h, and selected Chan channel
(0=R,1=G,2=B, RGB32 3=ALPHA)
Standard Deviation. http://en.wikipedia.org/wiki/Standard_deviation
***
***
***
MRGBChanInRange(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,int "lo"=128,int "hi"=lo,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT value (0.0 -> 1.0) being the amount of pixels in the range "lo" to "hi" (inclusive) in frame(n+delta) for area x,y,w,h,
and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA), 1.0 is equivalent to 100%.
Implemented as requested by Martin53 (thankyou), NOTE, differs from other funcs that return range 0.0 to 255.0.
NOTE, lo defaults to 128, "hi" defaults to "lo".
***
***
***
MRGBChanPNorm(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "chan"=0,float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1, int "MaskMin"=128,"MaskMax"=255)
Return int -1 if no valid pixels in Mask clip.
Returns FLOAT value greater or equal to 0.0, being the "Minkowski P-norm" (range depends upon values of 'd' and 'u') for frame(n+delta)
area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA)
mu, Float, default 0.0 (0.0 -> 255.0)
d, int, default 1 (1 -> 255) # downscale
p, int, default 1 (1 -> 16) # power
u, int, default 1 (1 -> 255) # final upscale before returning result (experimental)
Formula is: sum_over_pixels[ ((pixel-mu)/d)^p ]^(1/p) * u
or in words: d and u are scaling aids. The differences between the pixel values and mu are scaled, taken to the power of p and added up
over the frame. The sum is taken to the p-th root and finally rescaled.
mu=0, d=1, p=1, u=1 yields the average.
mu=average, d=1, p=2, u=1 yields the standard deviation (uncorrected sample standard deviation).
Implemented as requested by Martin53 (thankyou).
http://en.wikipedia.org/wiki/P-norm#The_p-norm_in_finite_dimensions
http://en.wikipedia.org/wiki/Minkowski_distance
***
***
***
MRGBChanStats(clip c,clip "mask"=NOTUSED,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
float "threshold"=0.0,int "chan"=0,int "lo"=128,int "hi"=lo,int "flgs"=255,string "prefix"="MRCS_",int "MaskMin"=128,"MaskMax"=255,
float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1)
Returns multiple results as for above single frame RGB channel sampling functions as Global Variables (prefixed with the prefix string arg).
The args up to "interlaced", are as for all other clip functions, "threshold" used only for "MRgbChanMin", "MRgbChanMax" and
"MRGBChanMinMaxDifference" equivalent routines with same functionality.
"lo" and "hi" are used only with the "MRGBChanInRange" equivalent routine with same functionality.
"mu" and "d" and "p" and "u" are used only with the "MRGBChanPNorm" equivalent routine with same functionality.
The new arg "Flgs" selects which results you want returned and the string "Prefix" that is prepended
to the returned global variable names.
The actual return result is a copy of the flgs args with any non valid bits reset, ie the global variables that were set.
Global variables are NOT altered for any function not selected in flgs.
EDIT: Returns 0 if no pixels found in search area of mask within MaskMin and MaskMax.
Flgs_Bit_Number Add_To_Flgs Equivalent_Function Global_Var_Set_Excluding_Prefix_and_Chan_postfix
0 1($01) MRGBChanMin() "Min" (0->255)
1 2($02) MRGBChanMax() "Max" (0->255)
2 4($04) MRGBChanMinMaxDifference() "MinMaxDiff" (0->255)
3 8($08) MRGBChanMedian() "Med" (0->255)
4 16($10) MRGBChanAve() "Ave" (0.0->255.0)
5 32($20) MRGBChanStdev() "Stdev" (0.0->255.0)
6 64($40) MRGBChanInRange() "InRng" (0.0->1.0)
7 128($80) MRGBChanPNorm() "PNorm" (0.0->??? depends upon d and u)
The Channel Postfix is of the form "_0", where 0 is RED, 1 is GREEN and 2 is Blue, 3 is ALPHA(RGB32 ONLY), and is appended to the
base name described above. So eg MRGBChanMin for RED channel 0 with default Prefix is "MRCS_Min_0".
MRGBChanstats() allows you to inquire multiple results simultaneously, with not much more overhead than calling a single individual
routine, however, you should not select sub functions that you dont need as there may be an additional unnecessary overhead.
The Default flgs=255($FF) are all bits set and so sets ALL global vars at once.
MRGBChanStats(flgs=1+2+16) would set global vars "MRCS_Min_0", "MRCS_Max_0" and "MRCS_Ave_0" for full frame current_frame, Red Channel.
In addition to above Global Variables, MRGBChanStats() sets an int Global variable (where default prefix) of "MRCS_PixelCount_0" being
the number of Red Channel pixels in mask area X,Y,W,H between MaskMin and MaskMax inclusive, or pixels scanned in X,Y,W,H area
where mask not used.
NOTE, MRGBChanStats() allows Chan to be -1, where ALL three R, and G, and B channels are processed simultaneouly for ALL functions
selected by flgs arg (ALPHA Channel is NOT processed).
A chan arg of -2 (RGB32 ONLY allowed) will additionally process the ALPHA channel as well as R+G+B.
Also Note, (where default Prefix) MRCS_PixelCount_x is also set (identically) for all channels when Chan == -1 or -2.
#############################################
StainlessS
M53, Script similar to your previous post:
# Requires RT_Stats v1.23
Avisource("D:\avs\Test.avi") # Planar
cRGB = ConvertToRGB32()
Mask = Last # Use Planar clip Luma as Mask
S = """%d]
YMax=%d
rAve=%.1f:%.1f rMin=%d:%d rMax=%d:%d rGood=%.3f
gAve=%.1f:%.1f gMin=%d:%d gMax=%d:%d gGood=%.3f
bAve=%.1f:%.1f bMin=%d:%d bMax=%d:%d bGood=%.3f
AllGood=%f
Pixels=%d
"""
flgs = 1 + 2 + 16 # Min + Max + Ave
Channel = -1 # -1=R+G+B ::: -2=R+G+B(+ALPHA, RGB32 ONLY) ::: or 0 -> 3 == single channel (3 Only for RGB32)
cRGB.ScriptClip("""
Ymax = Mask.RT_YPlaneMax() # Highest Y value in clip
rAve=MRGBChanAve(Last, mask, Chan=0, MaskMin=Ymax)
rMin=MRGBChanMin(Last, mask, Chan=0, MaskMin=Ymax)
rMax=MRGBChanMax(Last, mask, Chan=0, MaskMin=Ymax)
gAve=MRGBChanAve(Last, mask, Chan=1, MaskMin=Ymax)
gMin=MRGBChanMin(Last, mask, Chan=1, MaskMin=Ymax)
gMax=MRGBChanMax(Last, mask, Chan=1, MaskMin=Ymax)
bAve=MRGBChanAve(Last, mask, Chan=2, MaskMin=Ymax)
bMin=MRGBChanMin(Last, mask, Chan=2, MaskMin=Ymax)
bMax=MRGBChanMax(Last, mask, Chan=2, MaskMin=Ymax)
MRGBChanStats(Last, mask, Chan=Channel, MaskMin=Ymax,MaskMax=Ymax,flgs=flgs)
rGood=(MRCS_Max_0==0) ? 1.0 : MRCS_Ave_0/MRCS_Max_0 # Approx 'goodness' of Red channel average (if max==0 then Ave must be 0)
gGood=(MRCS_Max_1==0) ? 1.0 : MRCS_Ave_1/MRCS_Max_1
bGood=(MRCS_Max_2==0) ? 1.0 : MRCS_Ave_2/MRCS_Max_2
AllGood = rGood * gGood * bGood
RT_Subtitle(S,
\ current_frame,
\ Ymax,
\ rAve,MRCS_Ave_0,rMin,MRCS_Min_0,rMax,MRCS_Max_0,rGood,
\ gAve,MRCS_Ave_1,gMin,MRCS_Min_1,gMax,MRCS_Max_1,gGood,
\ bAve,MRCS_Ave_2,bMin,MRCS_Min_2,bMax,MRCS_Max_2,bGood,
\ AllGood,
\ MRCS_PixelCount_0
\ )
return Last
""")
EDIT: Above, MRGBChanAve/Min/Max individual channel functions not necessary, just to show that multi-functional MRGBChanStats
provides identical results. Below unnecessary individual function calls stripped out:
# Requires RT_Stats v1.23
Avisource("D:\avs\Test.avi") # Planar
cRGB = ConvertToRGB32()
Mask = Last # Use Planar clip Luma as Mask
S = """%d]
YMax=%d
rAve=%.1f rMin=%d rMax=%d rGood=%.2f
gAve=%.1f gMin=%d gMax=%d gGood=%.2f
bAve=%.1f bMin=%d bMax=%d bGood=%.2f
AllGood=%f
Pixels=%d
"""
flgs = 1 + 2 + 16 # Min + Max + Ave
Channel = -1 # -1=R+G+B ::: -2=R+G+B(+ALPHA, RGB32 ONLY) ::: or 0 -> 3 == single channel (3 Only for RGB32)
cRGB.ScriptClip("""
Ymax = Mask.RT_YPlaneMax() # Highest Y value in clip
MRGBChanStats(Last, mask, Chan=Channel, MaskMin=Ymax,MaskMax=Ymax,flgs=flgs)
rGood=(MRCS_Max_0==0) ? 1.0 : MRCS_Ave_0/MRCS_Max_0 # Approx 'goodness' of Red channel average (if max==0 then Ave must be 0)
gGood=(MRCS_Max_1==0) ? 1.0 : MRCS_Ave_1/MRCS_Max_1
bGood=(MRCS_Max_2==0) ? 1.0 : MRCS_Ave_2/MRCS_Max_2
AllGood = rGood * gGood * bGood
RT_Subtitle(S,
\ current_frame,
\ Ymax,
\ MRCS_Ave_0,MRCS_Min_0,MRCS_Max_0,rGood,
\ MRCS_Ave_1,MRCS_Min_1,MRCS_Max_1,gGood,
\ MRCS_Ave_2,MRCS_Min_2,MRCS_Max_2,bGood,
\ AllGood,
\ MRCS_PixelCount_0
\ )
return Last
""")
martin53
10th September 2013, 21:20
StainlessS, could you please check:
ColorBars()
ScriptClip(""" #"
Try {
R = MRGBChanMin(last, chan=0)
R = MRGBChanMax(last, chan=0)
R = MRGBChanAve(last, chan=0)
return last
} catch (err_msg) {
RT_Debug(err_msg)
}
""") #"
[5288] RT_Debug: Script error: there is no function named "MRGBChanAve"
[5288] RT_Debug: ([ScriptClip], line 5)
although .cpp (TAKE2) is 4 seconds older than .dll and reads @line501:
AVSValue __cdecl MRGBChanAve(AVSValue args, void* user_data, IScriptEnvironment* env) {
MYLO mylo;
AVSValue undef;
// [9]=chan,threshold,lo,hi,[10]=maskmin,[11]=maskmax,mu,d,p,u
if(MRGBChanstatsLo(mylo,RTAVE_F,"MRGBChanAve: ",args,env,
args[9],undef,undef,undef,args[10],args[11],undef,undef,undef,undef)==0)
return -1;
return mylo.ddat[RTAVE-RTAVE];
}
StainlessS
10th September 2013, 22:26
EDIT: Oops, somehow MRGBChanAve got squished, and dont work:
"MRGBChanMin", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMax", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMinMaxDifference", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanMedian", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MAChanAve", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanStdev", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[MaskMin]i[MaskMax]i"
"MRGBChanInRange", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[lo]i[hi]i[MaskMin]i[MaskMax]i"
"MRGBChanPNorm", "c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[Chan]i[mu]f[d]i[p]i[u]i[MaskMin]i[MaskMax]i"
"MRGBChanStats","c[mask]c[n]i[delta]i[x]i[y]i[w]i[h]i[Interlaced]b[threshold]f[Chan]i[lo]i[hi]i[flgs]i[prefix]s[MaskMin]i[MaskMax]i[mu]f[d]i[p]i[u]i"
Fixing it it now and adding to MRGBChanStats chan = -1 option, to get R + G + B (NOT ALPHA) channels at once for all flgs functions.
and
M53, find here fix for previous post edit bug, + mods + Docs.
MRgbChanStats() v1.03Beta, Here:
http://www.mediafire.com/download/xxrxsbg6a6e534p/MRGBChanStats_dll_v1.03b_20130908.zip
Post before yours gives fixed dll.
EDIT: The hilited line above tells Avisynth the name of the function and args names and type (although function call removed from above text)
martin53
11th September 2013, 14:06
:thanks: going to test it tonight.
EDIT: a new issue occurs.
yup's test clip, following script lines
MRGBChanStats(cPre, cPre24, x=border, y=border, w=-border, h=-border, Chan=0, flgs=$12, prefix="fRGB_", MaskMin=fY_yMax-1)
MRGBChanStats(cPre, cPre24, x=border, y=border, w=-border, h=-border, Chan=1, flgs=$12, prefix="fRGB_", MaskMin=fY_yMax-1)
MRGBChanStats(cPre, cPre24, x=border, y=border, w=-border, h=-border, Chan=2, flgs=$12, prefix="fRGB_", MaskMin=fY_yMax-1)
if (info>0) { RT_Debug("Rmax Gmax Bmax", string(fRGB_Ave_0, "%23.1f"), string(fRGB_Ave_1, "%6.1f"), string(fRGB_Ave_2, "%6.1f")) }
up to MRGBStats V1.02b, debug output
RT_Debug: Rmax Gmax Bmax 244.7 231.5 204.5
which is credible (clip looks too warm).
Same clip, same script, V1.03b dll
RT_Debug: Rmax Gmax Bmax 204.5 231.5 244.7
R & B seem mixed up
EDIT2: chan=-1 is very helpful! R & B appear same as with single channels.
StainlessS
11th September 2013, 21:09
Sorry bout dat m53, dont you just hate little endian.
LINK REMOVED
Find here v1.4b and test avs, and also shown below:
#MRGBChanStats Tester
AviSource("D:\avs\test.avi")
#Colorbars()
#Blankclip(color=$FFCCAA)
BilinearResize(720,576)
M=ConvertToYV12()
CC=M.ConvertToRGB32()
#M=RT_Undefined() # Un-Comment for Maskless
S="""
Name Separate StatsChan Chan-1
R Min %4d %4d %4d
G Min %4d %4d %4d
B Min %4d %4d %4d
R Max %4d %4d %4d
G Max %4d %4d %4d
B Max %4d %4d %4d
R Dif %4d %4d %4d
G Dif %4d %4d %4d
B Dif %4d %4d %4d
R Med %4d %4d %4d
G Med %4d %4d %4d
B Med %4d %4d %4d
R Ave %6.2f %6.2f %6.2f
G Ave %6.2f %6.2f %6.2f
B Ave %6.2f %6.2f %6.2f
R Std %6.2f %6.2f %6.2f
G Std %6.2f %6.2f %6.2f
B Std %6.2f %6.2f %6.2f
R InR %6.2f %6.2f %6.2f
G InR %6.2f %6.2f %6.2f
B InR %6.2f %6.2f %6.2f
R PNm %6.2f %6.2f %6.2f
G PNm %6.2f %6.2f %6.2f
B PNm %6.2f %6.2f %6.2f
Pixels ------ %6d %6d
"""
flgs=$FF MMin=200 MMax=235 LO= 192 HI=255
NOPIXELS ="\nNO PIXELS FOUND IN MASK"
CHAN_ONE ="a_"
CHAN_MULTI ="b_"
CC.GScriptClip("""
GSCript("
C=Last
rmin=MRGBChanMin(C,M,chan=0,maskmin=MMin,maskmax=MMax)
if(rmin<0) {
RT_Subtitle(NOPIXELS)
} else {
gmin=MRGBChanMin(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bmin=MRGBChanMin(C,M,chan=2,maskmin=MMin,maskmax=MMax)
rmax=MRGBChanMax(C,M,chan=0,maskmin=MMin,maskmax=MMax)
gmax=MRGBChanMax(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bmax=MRGBChanMax(C,M,chan=2,maskmin=MMin,maskmax=MMax)
rdif=MRGBChanMinMaxDifference(C,M,chan=0,maskmin=MMin,maskmax=MMax)
gdif=MRGBChanMinMaxDifference(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bdif=MRGBChanMinMaxDifference(C,M,chan=2,maskmin=MMin,maskmax=MMax)
rmed=MRGBChanMedian(C,M,chan=0,maskmin=MMin,maskmax=MMax)
gmed=MRGBChanMedian(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bmed=MRGBChanMedian(C,M,chan=2,maskmin=MMin,maskmax=MMax)
rave=MRGBChanAve(C,M,chan=0,maskmin=MMin,maskmax=MMax)
gave=MRGBChanAve(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bave=MRGBChanAve(C,M,chan=2,maskmin=MMin,maskmax=MMax)
rstd=MRGBChanStdev(C,M,chan=0,maskmin=MMin,maskmax=MMax)
gstd=MRGBChanStdev(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bstd=MRGBChanStdev(C,M,chan=2,maskmin=MMin,maskmax=MMax)
rinr=MRGBChanInRange(C,M,chan=0,maskmin=MMin,maskmax=MMax,lo=LO,hi=HI)
ginr=MRGBChanInRange(C,M,chan=1,maskmin=MMin,maskmax=MMax,lo=LO,hi=HI)
binr=MRGBChanInRange(C,M,chan=2,maskmin=MMin,maskmax=MMax,lo=LO,hi=HI)
rpnm=MRGBChanPNorm(C,M,chan=0,maskmin=MMin,maskmax=MMax)
gpnm=MRGBChanPNorm(C,M,chan=1,maskmin=MMin,maskmax=MMax)
bpnm=MRGBChanPNorm(C,M,chan=2,maskmin=MMin,maskmax=MMax)
MRGBChanStats(C,M,chan=0, flgs=flgs,maskmin=MMin,maskmax=MMax,prefix=CHAN_ONE,lo=LO,hi=HI)
MRGBChanStats(C,M,chan=1, flgs=flgs,maskmin=MMin,maskmax=MMax,prefix=CHAN_ONE,lo=LO,hi=HI)
MRGBChanStats(C,M,chan=2, flgs=flgs,maskmin=MMin,maskmax=MMax,prefix=CHAN_ONE,lo=LO,hi=HI)
MRGBChanStats(C,M,chan=-1,flgs=flgs,maskmin=MMin,maskmax=MMax,prefix=CHAN_MULTI,lo=LO,hi=HI)
RT_Subtitle(S,
\ rmin, a_Min_0, b_Min_0,
\ gmin, a_Min_1, b_Min_1,
\ bmin, a_Min_2, b_Min_2,
\ rmax, a_Max_0, b_Max_0,
\ gmax, a_Max_1, b_Max_1,
\ bmax, a_Max_2, b_Max_2,
\ rdif, a_MinMaxDiff_0, b_MinMaxDiff_0,
\ gdif, a_MinMaxDiff_1, b_MinMaxDiff_1,
\ bdif, a_MinMaxDiff_2, b_MinMaxDiff_2,
\ rmed, a_Med_0, b_Med_0,
\ gmed, a_Med_1, b_Med_1,
\ bmed, a_Med_2, b_Med_2,
\ rave, a_Ave_0, b_Ave_0,
\ gave, a_Ave_1, b_Ave_1,
\ bave, a_Ave_2, b_Ave_2,
\ rstd, a_Stdev_0, b_Stdev_0,
\ gstd, a_Stdev_1, b_Stdev_1,
\ bstd, a_Stdev_2, b_Stdev_2,
\ rinr, a_InRng_0, b_InRng_0,
\ ginr, a_InRng_1, b_InRng_1,
\ binr, a_InRng_2, b_InRng_2,
\ rpnm, a_PNorm_0, b_PNorm_0,
\ gpnm, a_PNorm_1, b_PNorm_1,
\ bpnm, a_PNorm_2, b_PNorm_2,
\ a_PixelCount_0, b_PixelCount_0
\ )
}
")
return Last
""")
return Last
EDITED: Moved pixel count into correct columns.
StainlessS
15th September 2013, 20:14
MYStats v1.05beta. New version see 1st post.
v1.05b, Added YUY2 and RGB24/32. Added Matrix arg for RGB. Sped up.
Added several test scripts.
Here results of a test timer:-
00000005 1.48367798 RT_Debug: MYStats And RT_Stats Comparison Test Timer
00000006 1.48369825 RT_Debug: Timing 24x5(120) runs on 2500 Frames (Total Frames=300000)
00000007 1.82623863 RT_Debug: RT_YankChain 0.068Secs :36945.81FPS :: Basic GetFrame() [ADJUSTMENT]
00000008 17.67099571 RT_Debug: YPlaneMin 3.167Secs : 789.47FPS :: ADJUSTED 3.099Secs 806.71FPS
00000009 28.43142319 RT_Debug: RT_YPlaneMin 2.156Secs : 1159.38FPS :: ADJUSTED 2.089Secs 1196.94FPS
00000010 38.60767746 RT_Debug: MYPlaneMin 2.031Secs : 1230.72FPS :: ADJUSTED 1.964Secs 1273.13FPS
00000011 54.49916077 RT_Debug: YPlaneMax 3.177Secs : 786.91FPS :: ADJUSTED 3.109Secs 804.03FPS
00000012 65.30001068 RT_Debug: RT_YPlaneMax 2.156Secs : 1159.55FPS :: ADJUSTED 2.088Secs 1197.13FPS
00000013 75.47039795 RT_Debug: MYPlaneMax 2.031Secs : 1230.92FPS :: ADJUSTED 1.963Secs 1273.34FPS
00000014 92.12580872 RT_Debug: YPlaneMinMaxDif 3.328Secs : 751.20FPS :: ADJUSTED 3.260Secs 766.79FPS
00000015 102.99511719 RT_Debug: RT_YPlaneMinMaxDif 2.172Secs : 1151.01FPS :: ADJUSTED 2.104Secs 1188.02FPS
00000016 113.16596222 RT_Debug: MYPlnMnMxDiff 2.031Secs : 1230.92FPS :: ADJUSTED 1.963Secs 1273.35FPS
00000017 128.98162842 RT_Debug: YPlaneMedian 3.162Secs : 790.72FPS :: ADJUSTED 3.094Secs 808.02FPS
00000018 139.77700806 RT_Debug: RT_YPlaneMedian 2.156Secs : 1159.55FPS :: ADJUSTED 2.088Secs 1197.12FPS
00000019 149.93418884 RT_Debug: MYPlaneMedian 2.031Secs : 1230.72FPS :: ADJUSTED 1.964Secs 1273.13FPS
00000020 156.48509216 RT_Debug: AverageLuma 1.307Secs : 1912.78FPS :: ADJUSTED 1.239Secs 2017.22FPS
00000021 160.90562439 RT_Debug: RT_AverageLuma 0.880Secs : 2840.91FPS :: ADJUSTED 0.812Secs 3077.56FPS
00000022 163.33396912 RT_Debug: MAverageLuma 0.484Secs : 5161.72FPS :: ADJUSTED 0.417Secs 5999.98FPS
00000023 174.12857056 RT_Debug: RT_YPlaneStdev 2.156Secs : 1159.55FPS :: ADJUSTED 2.088Secs 1197.12FPS
00000024 184.28181458 RT_Debug: MYPlaneStdev 2.031Secs : 1230.92FPS :: ADJUSTED 1.963Secs 1273.34FPS
00000025 195.05416870 RT_Debug: RT_YInRange 2.156Secs : 1159.55FPS :: ADJUSTED 2.088Secs 1197.12FPS
00000026 205.19453430 RT_Debug: MYInRange 2.031Secs : 1230.92FPS :: ADJUSTED 1.963Secs 1273.35FPS
00000027 276.00216675 RT_Debug: Avisynth_ALL 14.157Secs : 176.60FPS :: ADJUSTED14.089Secs 177.44FPS
00000028 286.96133423 RT_Debug: RT_Avisynth_ALL 2.187Secs : 1142.95FPS :: ADJUSTED 2.120Secs 1179.43FPS
00000029 298.01794434 RT_Debug: RT_ALL 2.213Secs : 1129.52FPS :: ADJUSTED 2.146Secs 1165.14FPS
00000030 308.51885986 RT_Debug: MYStats_ALL 2.099Secs : 1191.04FPS :: ADJUSTED 2.031Secs 1230.72FPS
00000031 308.51953125 RT_Debug: Total Runtime = 5.12 Mins
RT_ALL contains a couple of funcs not available in built-in runtime funcs.
MYStats_ALL contains an additional func not yet available in RT_Stats.
Will at some point integrate MYStats and RGBChanStats into RT_Stats. Above timings done on Maskless MYStats colorbars YV12 clip.
EDIT: Above Avisynth built-in funcs produce a lot better results with a nearly empty plugins directory,
presume loaded plugins appears earlier in function list, so are accessed quicker.
StainlessS
25th September 2013, 19:52
MyStats + MRgbChanStats Combo v1.06, perhaps final version. See 1st and 2nd posts.
v1.06, added MRgbChanStats.
Will soon be integrated into RT_Stats.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.