LigH
27th March 2016, 19:01
To get a good still result of a YouTube video which was encoded as a long sequence of that still frame, with probably rather progressive quality (more or less CBR, the first I frame is probably coarse), I thought of averaging a longer range of frames, omitting a few dozen from the start.
Which kind of filter would you recommend — some temporal average (http://avisynth.nl/index.php/TTempSmooth) (arithmetic or more or less Gaussian if possible), or rather Median with small spatial but large temporal radius (http://avisynth.nl/index.php/MedianBlur2#MedianBlurTemporal)? I would even consider a "merge cascade".
Reel.Deel
27th March 2016, 19:20
Try ClipBlend (http://forum.doom9.org/showthread.php?t=168048).
LigH
27th March 2016, 19:44
Sounds great for a variable range.
For a quick & dirty approch, a "merge cascade" worked well already.
c0 = Trim(frame, -1)
c1 = Trim(frame+1, -1)
c2 = Trim(frame+2, -1)
c3 = Trim(frame+3, -1)
c4 = Trim(frame+4, -1)
c5 = Trim(frame+5, -1)
c6 = Trim(frame+6, -1)
c7 = Trim(frame+7, -1)
Merge(Merge(Merge(c0, c1), Merge(c2, c3)), Merge(Merge(c4, c5), Merge(c6, c7)))
StainlessS
27th March 2016, 21:48
General thread on similarish:- http://forum.doom9.org/showthread.php?p=1631552&highlight=clipblend#post1631552
ClipBlend with delay=0 does average on all frames played so far.
RGBAmplifier (RGB only) can do temporal average of radius frames +- from current (as can DavidHorman equivalent filter, forgot what its called, YUV too).
From Clipblend
ClipBlend(clip,"delay"=0) # 8 bit Planar, YUY2, RGB
ClipBlend16(clip,"delay"=0) # 16 bit, Stack16 Planar, YUY2, RGB (see Dither Tools)
Added Delay arg to plugin.
Delay, default = 0, == ALL frames played so far blended.
1 = blend with previous frame ie two frames blended.
10 = blend with 10 previous frames, ie 11 frames blended, etc.
Accumulator resets at frame 0.
To get average of all frames 0 to frame 300
# ------------------------
FRM =300 # Required frame number
Avisource("D:\avs\test.avi")
ClipBlend() # Default delay=0 ie all previous frames
Trim(FRM,-1) # Get Required frame
return Last
# ------------------------
Or to get a single frame average of all frames in a clip
# ------------------------
Avisource("D:\avs\test.avi")
ClipBlend()
return Trim(FrameCount-1,-1)
# ------------------------
How ClipBlend it works
ClipBlend() uses a single 32 bit accumulator (unsigned int) for each channel of each pixel x,y position in the clip frame.
With a maximum possible value per pixel/channel being 255 ie 8 bits, this leaves 24 bits available for accumulating
the sum of values for that pixel/channel position, ie adding the values for that pixel/channel from every selected frame
in the blended range. The additional 24 bits would allow for up to ~16 Million (2^24) frames to be summed, however we also
need another bit to maintain maximum precision possible for 8 bit result, so reducing maximum possible frame range to
~8 million frames.
Code:
Return Avisource("test.avi").ClipBlend(delay=0).Trim(999,-1) # 1000 frames, 1000 values per accumulator, ie max 1000*255
Above would sum (each channel/pixel) with maximum possible sum for an accumulator being 1000*255 (about 18 bits, 2^10=1024,2^8=256)
As clipblend scans frames, it adds the channel/pixel values at each x,y position to the accumulators, for all of the
required frames. If delay = 0, it just adds next frame values to the accumulators. If eg delay=10, and current scanned range is already
10, it subtracts the channel/pixel values of the oldest frame (lowest number) and then adds the values for the next frame to the
accumulators. When delivering the result (delay=whatever), it just divides the accumulated sum by the number of sample frames to
get the average, and writes it to the relevant pixel/channel/x/y position, could not be simpler.
Implementation is equivalent to this:
int(accumulator / Float(FramesDone) + 0.5)
The actual implementation and reason for the extra needed bit that was mentioned (ie accumulator*2):
((accumulator*2) + FramesDone) / (FramesDone*2)
The *2 pair and addition of FramesDone is the integer equivalent of division, adding 0.5 and taking Int() whist maintaining max possible
precision at 8 bits result.
NOTE, The ClipBlend16() filter was written before I realized that there is no support for either RGB or YUY2 and Stack16 format, so
it works ok, but would need extra work to convert for use with Dither package.
EDIT: DavidHorman plug 'Amp' (+YUV) here:- http://forum.doom9.org/showthread.php?p=1703332#post1703332
The DavidHorman comment below
Inspired by RgbAmplifier, which I couldn't get to work, I've written a plugin called amp.
Was referring to the original AVS script prototype and not the RgbAmplifier plugin. (David was unaware of RgbAmplifier plugin)
From memory, the RgbAmplifier plugin is also about 7,500 times faster than the original script prototype.
[EDIT: Above RgbAmplifier edited, originally said ClipBlend by mistake]
EDIT: And Clipblend here:- http://forum.doom9.org/showthread.php?t=168048
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.