Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 16th August 2013, 21:00   #1  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
MYStats v1.06, Masked YStats + RgbChanStats Combo

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
Code:
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.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 25th September 2013 at 19:57. Reason: Update
StainlessS is offline   Reply With Quote
Old 16th August 2013, 21:01   #2  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Part 2 of Masked YStats + RgbChanStats Combo plugin

Code:
-------------------------------------------------------------
-------------------    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
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 25th September 2013 at 19:56.
StainlessS is offline   Reply With Quote
Old 18th August 2013, 06:53   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Update v1.02beta.

Experimental version with additional DEBUG dll.

Added two MYPNorm simulating scripts [UPDATED].

1 MYStdev() simulation
Code:
# 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.
Code:
# 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()

Code:
        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;
        }
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 22nd August 2013 at 18:58. Reason: Update
StainlessS is offline   Reply With Quote
Old 18th August 2013, 11:08   #4  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
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:
Code:
...
	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:
Code:
...
	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")
martin53 is offline   Reply With Quote
Old 18th August 2013, 17:16   #5  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by martin53 View Post
: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)

Code:
#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 ?
Code:
	GScript("""	# "
              ...
	""")	# "
You seem to use it a lot.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 18th August 2013 at 17:47.
StainlessS is offline   Reply With Quote
Old 18th August 2013, 18:06   #6  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Quote:
Originally Posted by StainlessS View Post
Martin53, just curious, what purpose does this fulfill ?
Code:
	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.
martin53 is offline   Reply With Quote
Old 18th August 2013, 18:28   #7  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Thank you, that salves that itch.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 18th August 2013, 23:25   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
M53
How bout missing mask clip arg, processes all ?
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 19th August 2013 at 01:30.
StainlessS is offline   Reply With Quote
Old 19th August 2013, 16:39   #9  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Update to v1.02b.

Can now call without mask where entire selected area processed.
(EDIT: faster than eg mask=source, Maskmin=0, Maskmax=255)

Code:
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.
Code:
  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.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 19th August 2013 at 17:11.
StainlessS is offline   Reply With Quote
Old 19th August 2013, 19:46   #10  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
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?

Last edited by martin53; 19th August 2013 at 20:36.
martin53 is offline   Reply With Quote
Old 19th August 2013, 22:19   #11  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
StainlessS,
there is a thing that I don't understand at the moment. With the following lines and constants
Code:
/*
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?
martin53 is offline   Reply With Quote
Old 19th August 2013, 22:40   #12  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
what is YTo8 ? [Y to Y8 ?]
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 20th August 2013, 00:41   #13  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
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.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 20th August 2013 at 00:56. Reason: edit
StainlessS is offline   Reply With Quote
Old 20th August 2013, 17:37   #14  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
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 , 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 is offline   Reply With Quote
Old 20th August 2013, 17:42   #15  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
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?
martin53 is offline   Reply With Quote
Old 20th August 2013, 17:48   #16  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
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.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 20th August 2013 at 18:11.
StainlessS is offline   Reply With Quote
Old 20th August 2013, 18:40   #17  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
MRGBChanStats v1.02beta
LINK REMOVED
Code:
"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.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 25th September 2013 at 19:53.
StainlessS is offline   Reply With Quote
Old 5th September 2013, 21:05   #18  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
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


Last edited by martin53; 5th September 2013 at 21:45.
martin53 is offline   Reply With Quote
Old 5th September 2013, 21:32   #19  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
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.
Code:
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!
martin53 is offline   Reply With Quote
Old 7th September 2013, 13:40   #20  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by martin53 View Post
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)

Quote:
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:
Code:
"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.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 8th September 2013 at 03:53.
StainlessS is offline   Reply With Quote
Reply

Tags
averageluma, mask, rt_stats

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:50.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.