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.

 Doom9's Forum Additive downscaling - any easy way?
 Register FAQ Calendar Search Today's Posts Mark Forums Read

 27th March 2013, 02:03 #1  |  Link blubb444 Registered User   Join Date: Mar 2012 Posts: 40 Additive downscaling - any easy way? I have some videos that were shot in a rather dark setting, 1920x1080p50. In order to make them brighter without introducing too much noise I'd like to downscale them to exactly half the resolution (960x540p50) but instead of most other resizing algorithms that average neighbouring pixels (that'd be bilinear, right?) or fitting some functions through them (bicubic, sinc, spline...?) I want the luma values of 4 pixels to simply add up to form 1 new pixel. I'm not familiar enough with the Avisynth code and neither with C(++), I only learned some Pascal/Delphi back in school so this is how the pseudo-code would look like: Code: ```//Vin/Vout = current input/output video frame //Vin.Y and Vout.Y are 2D arrays which store the luma values at given pixel (x,y) function ClampToByte(i: integer): byte; //this is just to make sure that there's no overshooting begin if i > 255 then result := 255 else if i < 0 then result := 0 else result := i; end; Vout.width := Vin.width div 2; Vout.height := Vin.height div 2; //if input levels are 16..235, call levels() to make them 0..255 beforehand for x := 0 to (Vout.width - 1) do for y := 0 to (Vout.height - 1) do Vout.Y[x,y] := ClampToByte(Vin.Y[2*x, 2*y] + Vin.Y[2*x+1, 2*y] + Vin.Y[2*x, 2*y+1] + Vin.Y[2*x+1, 2*y+1]); //U and V values can be resized normally or left as-is if you wish to go from 4:2:0 to 4:4:4``` Any way to "translate" that into Avisynth? Or is there already a function which does this? (And I'm not talking about regular BilinearResize() and then multiplying luma by 4 as this would introduce unnecessary banding because of rounding errors, or technically reduce the bit depth from 8 to 6 which I don't want)
27th March 2013, 11:51   #2  |  Link
Gavino
Avisynth language lover

Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
 Originally Posted by blubb444 Any way to "translate" that into Avisynth? Or is there already a function which does this? (And I'm not talking about regular BilinearResize() and then multiplying luma by 4 as this would introduce unnecessary banding because of rounding errors, or technically reduce the bit depth from 8 to 6 which I don't want)
Can't you avoid this by doing the downsizing after the luma multiplication by 4 (which can be done using Levels() or ColorYUV())?
__________________
GScript and GRunT - complex Avisynth scripting made easier

27th March 2013, 17:13   #3  |  Link
blubb444
Registered User

Join Date: Mar 2012
Posts: 40
Quote:
 Originally Posted by Gavino Can't you avoid this by doing the downsizing after the luma multiplication by 4 (which can be done using Levels() or ColorYUV())?
Of course this should work too! Seems like I couldn't see the wood for the trees here, thanks!
And does BilinearResize(width/2, height/2) do exactly that? (As in use exactly those 4 pixels to make 1 new)

27th March 2013, 18:12   #4  |  Link
Gavino
Avisynth language lover

Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
 Originally Posted by blubb444 And does BilinearResize(width/2, height/2) do exactly that? (As in use exactly those 4 pixels to make 1 new)
No - it actually uses 16 pixels (4x4) to make each new one.
There is also ReduceBy2() which uses 9 (3x3) pixels.
Each of these will give better antialiasing of the output, but if you still want your original scheme, I think it can be achieved directly via:

GeneralConvolution(matrix="0 0 0 0 1 1 0 1 1", auto=false)
PointResize(width/2, height/2)
__________________
GScript and GRunT - complex Avisynth scripting made easier