Author V. C. Mohan
Date 23 Aug 2020
All my plugins are available for free download from "here".

vcmod plugin for vapoursynth version r50+, is free and the author does not give any guarentee for its operation. It may be downloaded and used at the users risk.

vcmod has functions named median, variance, amp, gBlur, mBlur, neural, fan, saltPepper, veed and hist. These are thread safe.These are ported with improvements from the original avisynth plugins. All the functions in this plugin modify pixel values as per some criteria, and hence the name.



the script call for amp is

vcmod.amp( clip, [ int useclip = 0] [,clip sclip] [,int connect4 = 1] ,int sh=[int,int,int], int sm = [int,int,int]])

clip:Input constant format Excepting Compat color.
useclip: if not set to 0, a smoothed clip to be used for segmentation and must be specified.
sclip: smoothed version of input clip.Must be specified if useclip was not set to zero
connect4: if set 0, 8 point and if set 1, 4 point connect is used for segmentation.
sh: Sharpening can be -5 to 5, but preferably 1, to be spcified for each plane or atleast for first plane.
sm: smoothening can be 0 to 10 and to be specified for each plane or at least for first plane.

amp function segments image on watershed principle. Smoothing is done if not set to 0, restricting to boundaries within each basin. Sharpening is by spiking watershed boundaries and so must use small values. As watershed is known to over segment an image, the inputclip should be clean or smooth. If useclip parameter is not 0, sclip a pre smoothed version of the input clip(eg: blurred with gBlur function) for segmentation. This segmentation is used to process the input clip and will yeild better results.



The call is:-

vcmod.hist(clip [, clip clipm, int mf = 0][,int type=1][,int table=[int,int,.....] ][ ,int window = 0][,int limit = 0] )

clip: YUV or Gray format only.
clipm: frame on this clip to be matched with. Must specify if type = 2.
mf: Frame number of clipm to be used for matching.
type: 1. Equalization, 2.Match with frame fm of clipm 3. Match with given table of luma %age, and population %age values 4. match with a table of luma %age and cummulative population %age.
table: for type = 3, array of pairs of integer values giving Luma as %age and %age of occurance. For type 4 Luma as %age and cummulative population as %age. Luma and cummulative %age should increase monotonously 0 to 100. Minimum 2 pairs and maximum 20 pairs can be specified.
window: 0. for full frame and 1 for windowed processing. If the frame dimensions are not large enough for windowed process, reverts to full frame process.
limit: 0. No limit. %age change in value to be allowed.

hist can equalize whole frame or with moving window (slow) or match entire clip with a given frame or match with specified histogram. Equalization may be severe for certain inputs, so a parameter limit which limits %age of change is provided. limit value of 0 means no limit.



The Script call is:-

vcmod.median (clip[, int maxgrid = 5] [,int plane=[1,0,0] ] );

clip: input clip all formats except Compat.
maxgrid: maximum size of square grid to which grid can grow fom 3x3 for getting statistics. Odd number 3 to 9.
plane: input clip color planes to be processed. 1 process, 0 do not. All 3 values must not be simultaneously specified as zero.

median Filter is for eliminating certain types of impulsive noise. It uses local statistics (minimum, maximum and median values) of a moving local grid, and changes grid size depending on local statistics.

As per theory
Quote "Ordinary median filters perform well as long as the spatial density of impulsive noise is small. Adaptive Median filter can handle impulsive noise having larger probablity. An additional benefit is this seeks to preserve detail while smoothing nonimpulse noise something that the traditional median filter does not do.

The algorithm used has three purposes.
1.To remove salt and pepper (impulse) noise.
2.To smooth other noise which may not be impulsive
3.To reduce distortion such as excessive thinning or thickening of object boundaries.
" unquote



the script call is

vcmod.gBlur(clip [, int ksize = 5][,float sd = 1.5])

clip: input all formats except Compat.
ksize: Kernel size 3 to 11 odd number
sd: standard deviation allowed.

A separable Gaussian kernel of odd number size 3 to 11 is designed for blurring. For constant integer formats if ksize and sd combination become ineffictive to outer values of grid, warns.



The script call is: [ , int span = 5][ ,int edge = 1][ ,int uv = 1 ][,plus = 0.02][,minus = 0.02])

clip: input all except Compat format allowed.
span: width of fan operator. Odd number between 3 and 51
edge: If set to 1, protects edges and if set 0 smooths over.
uv: if set 0, uv planes not filtered. If set 1 u, v planes are filtered.
plus: Plus tolerance. 0.0 to 0.5.
minus: minus tolerance 0.0 to 0.5.

In some videos, especially those transcribed from VHS sometimes regular frequency noise is seen across the frame. Sometimes either vertical or horizontal white streaks are also seen. This function filters out such regular noise and streaks. This function works scan line by scan line. Hence if the streaks are horizontal, input may be turned left and after fan removes the streaks turned right to restore

In case of regular noise Fan need to examine data over a span (odd number from 3 to 51) of apparent wavelength(along horizontal). The central point of this span is either replaced by average or using given tolerances edges are preserved. For streaks shorter span and smaller plus tolerance can be spcified.In case YUV data process of u and v planes are optional. R,G,B planes of RGB are processed. A is just copied.



The script call is:

vcmod.MBlur(clip [ , int type = 1][ ,int x = 5][ ,int y = 5 ])

clip: Input all except Compat formats
type: 1. for linear, 2. for rectangular and 3. for circular (focus) blur
x: x coordinate of end point of linear, corner of rectangle or radius of circle. -100 to 100.
y: y coordinate for linear and rectangle.- 100 to 100.

The x and y coordinates are with respect to center. For circular x is treated as radius. x and y both should not be set to zero



The call script is :-

vcmod.variance(clip,int lx,int wd,int ty,int ht [,int fn = 0][,int uv = 0][,int xgrid = 5][,int ygrid = 5])

clip: input clip of constant format. Compat input not accepted.
lx: Left x coordinate of window
wd: width of window
ty: top y coordinate of window
ht: height of window
fn: frame number in which window is located.
uv: If set 0 u and v planes of YUV format not processed.
xgrid: grid size along width. Minimum 3
ygrid: grid size along height. Minimum 3.

From a given representative window, the global variance is determined. In a moving grid the local variance is determined and the center of the grid point is modified in relation to these two variances. The algorithm ensures that local edges are not destroyed. Repeated use of this function cleans image and may be used for very noisy clips. For RGB all 3 planes are processed. The window should be as large as possible but have near uniform luma for YUV or Gray formats or uniform color and intensity for RGB format



The call script is :-

vcmod.neural(clip,[str txt = "none"[ ,str fname][,clip tclip]] [,int iter = 200][ ,int bestof = 1][, int wset = 0][,int xpts = 3][, int ypts = xpts][, int tlx = xpts][, int trx = width - xpts][, int tty = ypts][, int tby = height - ypts][, int rgb = 1])

clip: Inpt clip all formats except Compat accepted.
txt: can be either "none", "read" or "save". In case of read or save fname with full path and file name be given to read from or save to. If "none" it neither saves nor reads a file. if "save" relevant parameters and training progress (error sum) will be saved to a file. If "read", then it gets all parameters and best weights to use from the previously saved file. None of following parameters need to be specified then.
tclip: clip on which desired data is available. neural finds optimum weights to match the tclip.
iter: number of iterations for training
bestof: best of is number of times process repeated with new starting weight sets and use wights which resulted in least error.
wset: if set to 0, uses internal random numbers and If set to 1, uses current time seeded random numbers as starting wights.
xpts, ypts: number of input points along width and height. A max of xpts * ypts = 225 and minimum of 9 can be specified. xpts and ypts must be odd positive numbers.
tlx, trx, tty, tby: top left x, right x top y and bottom y co of window for training., trx, tty, tby are left x, right x, top y, bottom y coordinates of window to use for training. Time for training is proportional to xpts * ypts * (trx - tlx - xpts) * (tby - tty - ypts) * iter * bestof.
rgb: with RGB input if set to 0, red, if set to 1 green and if set to 2 blue color plane is used for training. For YUV, or Gray only Y is processed.

Given an input ( first frame of clip) and its corresponding desired output ( first frame of tclip which has been obtained through some linear processing), Neural trains itself to get an output as close to desired output as possible. Training window should represent all possible input variations and be as small as possible. Given input grid size ( xpts * ypts) to work on and corresonding desred center points, through repeated iterations and different starting weight sets it finds weights that result in minimum error. The weight set can be saved in a text file and later used for same or similar data . This saves training time that can take several seconds to a few minutes. The input clip is then processed using these weights.

for test used following script.
# input was blurred by GBlur to use as desired output.
ret2 = core.vcmod.GBlur(ret,ksize=7,sd=2)
ret1 = core.vcmod.Neural(ret, txt ="save", fname = r'c:\temp\modNeural.txt', tclip = ret2,xpts = 7, iter = 200, bestof = 10,wset = 0,tlx = 250, trx = 450, tty = 100, tby = 300,rgb = 0 )



vcmod.saltPepper(clip [,planes = [3,3,3]][,tol = 3][,avg= 1] )

clip: Input clip. All formats except Compat accepted.
planes: array of 3 values specifying type of process for that plane. The plane set to 0 : no process, 1: Desalt, 2: DePepper, 3 : DeSalt and Depepper.All 3 should not be set to zero.
tol: tolerance above or below surrounding pixels to accept. Max 5.
avg: if salt or pepper found and if avg is set to 1, pixel value will be replaced by average of surrounding. If set to 0, nearest valid pixel value will be used.



vcmod.veed(clip[,rad = 5][,float str = 5] [,int planes = [1,1,1]][,int plimt = 3][,int mlimit = 3] )

clip: input clip of all excepting Compat format accepted.
rad: radius of gaussian influence. 1 to 8
str: strength of gaussian influence. 1 to 8.
planes: Array of 3 values. Plane set to 0 is not processed.
plimit: Plus side limit. 0 to 10
mlimit: minus limit. 0 to 10.

veed filter originally developed to remove some greenish hue seen. Later it was extended with option for any or all color planes.Uses gaussian predicted value of the center in a circular area of radius rad, filter strength str. Any plane set to 0 is not processed. If set to 1 filtered. plus and minus limits to accept can be specified.

Example code and results. Input on left, output on right.
# hist

# variance

# median
core.vcm.median(ret, maxgrid = 5, plane=[1,0,0])

# amp Extreme right difference of input and output heightened
#smoothened by gBlur
ret2 = core.vcm.gBlur(ret,ksize=5,sd=2)
ret1 = core.vcm.amp(ret,sh=[2,0,0],sm=[10,0,0], useclip=1,sclip=ret2)
ret2 = core.std.MakeDiff(ret1,ret)
#Difference heightened by equalization
ret2 = core.vcm.hist(ret2)

To my index page down load plugin To vapoursynth