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 26th February 2011, 07:22   #1  |  Link
um3k
Registered User
 
Join Date: May 2007
Posts: 220
Resize to 1 pixel wide?

Is it possible to resize a frame to 1 pixel wide in avisynth? I'm getting the error "source image too small for this resize method". The frame I'm starting with is 704 pixels wide. The goal is to average the pixels horizontally, so if there is an alternative way to do that, I'd be fine with it.
um3k is offline   Reply With Quote
Old 26th February 2011, 12:18   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,384
For technical reasons, the final width must be greater than the number of 'taps' on the resize filter used, so a width of 1 is not possible with any of the resizers (except of course PointResize).

But even if it was permitted, it wouldn't give you a plain average anyway - it would be a weighted average, with different weights for each pixel depending on its distance from the centre.

One way to get what you want is a horizontal box blur with a box whose width is equal to the image width, and then crop out the centre column as your final result. However this only works exactly if your initial image width is an odd number.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 26th February 2011, 13:19   #3  |  Link
jmac698
Registered User
 
Join Date: Jan 2006
Posts: 1,867
Hi,
That's not too hard. First, you can get a full pixel average in masktools,
Code:
a=blankclip(pixel_type="YV12",color_yuv=$808080)
b=blankclip(pixel_type="YV12",color_yuv=$408080)
stackhorizontal(a,b)
mt_lutf(last,last,mode="avg",yexpr="x")
The test video has squares of 64 and 128 brightness, the average should be 96. The lutf command returns the pixel average, which is 96 everywhere. But now you need to work only on each line, so use my split lines function with it:
Code:
#Line Average v0.1 by jmac698 
#Averages each horizontal line.  Doesn't change video resolution.
#Requires GRunT, MaskTools v2
#set your source here
splitlines(1)
mt_lutf(last,last,mode="avg",yexpr="x")
MergeLines(480)

function SplitLines(clip c, int n) {#duplicates then crops each copy in a different spot
  Assert(c.height%n == 0, "Clip height not a multiple of 'n'")
  Assert(!(c.IsYV12() && n%2==1), "'n' must be even for YV12 clips")
  nStrips = c.height/n
  c = c.ChangeFPS(nStrips*Framerate(c)).AssumeFPS(c) # Repeat each frame 'nStrips' times
  BlankClip(c, height=n) # template for ScriptClip result
  GScriptClip("c.Crop(0, (current_frame%nStrips)*n, 0, n)", args="c, nStrips, n")
}

function MergeLines(clip c, int n) {MergeLines2(c,n,n)}

function MergeLines2(clip c, int n,int i) {
  i<2?c.SelectEvery(n):stackvertical(MergeLines2(c,n,i-1),c.SelectEvery(n, i))
}

Last edited by jmac698; 26th February 2011 at 13:24.
jmac698 is offline   Reply With Quote
Old 26th February 2011, 14:11   #4  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,384
Quote:
Originally Posted by jmac698 View Post
Code:
splitlines(1)
mt_lutf(last,last,mode="avg",yexpr="x")
Catch 22!
Single lines are only possible with RGB, but mt_lutf requires YV12 (or planar).

However, you could do this:
Code:
h = height
PointResize(width, h*2).ConvertToYV12()
splitlines(2)
mt_lutf(last,last,mode="avg",yexpr="x")
MergeLines(h)
ConvertToRGB().PointResize(width, h)
# or use PointResize(1, h) to get 1-pixel wide result
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 26th February 2011 at 15:47.
Gavino is offline   Reply With Quote
Old 26th February 2011, 16:59   #5  |  Link
um3k
Registered User
 
Join Date: May 2007
Posts: 220
Thanks, guys. I found a workaround on my own, simply resizing to the minimum (8 pixels), then using HorizontalReduceBy2 three times to get it down to 1 pixel. I'm sure it's nowhere near exact, but the results were satisfactory for my purposes. If you're interested, here's a peek:


Based on this website: http://moviebarcode.tumblr.com/

Script:
Code:
function MovieBarcode(clip src, int w, int h)
{
GScript("""
    src = src.ConvertToRGB24()
    comp = src.BlankClip(width=1, height=h)
    for(f=1,w,1)
    {
        fc = src.framecount
        cf = (fc / w) * f
        s = src.SelectEvery(fc, cf).BilinearResize(8, h).HorizontalReduceBy2().HorizontalReduceBy2().HorizontalReduceBy2()
        comp = StackHorizontal(comp, s)
    }
    return comp.Crop(1, 0, 0, 0).Trim(0,1)
""")
}
Thanks, Gavino, for GScript. I probably could have done this particular script with recursion, but the for loop was much more straightforward.

The movie is the one in my sig...
um3k is offline   Reply With Quote
Old 27th February 2011, 13:00   #6  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,384
Quote:
Originally Posted by um3k View Post
Thanks, guys. I found a workaround on my own, simply resizing to the minimum (8 pixels), then using HorizontalReduceBy2 three times to get it down to 1 pixel. I'm sure it's nowhere near exact, but the results were satisfactory for my purposes.
Actually, the minimum for BilinearResize is 2 pixels, so you could have got away with a single HorizontalReduceBy2. What you have certainly isn't a mathematical average (as pixels nearer the centre of the frame will have more weight), but if you're just looking for some way to blur all pixels horizontally into one, that's fine.

BTW If the idea was to create a single frame result, the Trim(0,1) at the end of your code should be Trim(0, -1). (The second frame consists of repeated strips from the last frame of the source.)
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 3rd March 2017, 17:26   #7  |  Link
spoRv
Registered User
 
Join Date: Nov 2016
Posts: 112
I made a small revision; now each single bar is not a resized frame, but its average color; result is really similar, but now it's "smoother", and, when saved as image, takes a lot see space.

Code:
function MovieBarCode2(clip clip, int "w", int "h")
{
GScript("""
w=default(w,1280)	h=default(h,480)

	       clip.ConvertToYV24
    src  = mt_lutf(last, mode="avg", expr="x", u=3, v=3)
    comp = src.BlankClip(width=1, height=h)

    for(f=1,w,1)
    {
        fc   = src.framecount
        cf   = (fc / w) * f
        s    = src.SelectEvery(fc, cf).PointResize(1, h)
		comp = StackHorizontal(comp, s)
    }

    return comp.Crop(1, 0, 0, 0).Trim(0,-1)

""")

}
spoRv is offline   Reply With Quote
Old 3rd March 2017, 17:42   #8  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 405
just because ...

mt_luts(last,last,mode="avg",pixels=mt_rectangle(0,height),expr="y",u=3,v=3)
martin53 is offline   Reply With Quote
Old 3rd March 2017, 22:44   #9  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 1,840
"Fingerprinting" was previously covered here:

http://forum.doom9.org/showthread.php?t=167769

There's a plugin in there somewhere, though it probably won't work for very long clips.
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline   Reply With Quote
Old 4th March 2017, 00:47   #10  |  Link
spoRv
Registered User
 
Join Date: Nov 2016
Posts: 112
Thanks, it was pointed also in my other thread here: https://forum.doom9.org/showthread.php?t=174358 - a very nice plugin indeed!

@martin53: I'm a bit more than a smart monkey, so the added code was merely a copy&paste I found somewhere here - can't remember where, though... (EDIT: found here, thanks Gavino!) so, I replaced that line of code with yours, but result is identical...

Last edited by spoRv; 4th March 2017 at 02:17.
spoRv is offline   Reply With Quote
Old 4th March 2017, 15:53   #11  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 405
After reading your function more thoroughly, I think my post was a bit off topic. There, mt_luts() will make the columns of an already existing frame the average of all pixels in the column. But your script builds a single fingerprint frame from a frame sequence input clip, so it's not the same.
martin53 is offline   Reply With Quote
Reply

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 10:13.


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