View Full Version : RT_Stats, Compile-time/Runtime Functions v1.43 - 08 Oct 2014
Pages :
1
[
2]
3
4
5
6
7
8
9
10
11
StainlessS
15th October 2012, 19:29
@Martin53,
Sorry about not responding earlier, got a bit waylaid.
About to be sidetracked again (just decided to make a plugin to both auto crop and/or auto level) so decided
to answer briefly before going offline for perhaps a while.
Are you still dealing with the above problem, I've never used the Mdepan func with logfile (dont think).
Dont know whether log file creating on fly, with each frame or at destruction.
Either way, probably not available (or open file) and maybe requires 2 pass.
But perhaps, if you step through the MDepan frames using GScript, as a prescan stage (long timeout) and then
IF log file is complete, might be able to use RT_ReadTextFromFile to retrieve it, and throw away the original result clip.
Stepping through frames examples here:
http://forum.doom9.org/showthread.php?t=165694
RT_ReadTextFromFile reads possibly multiline [Chr(10) separated] string from a text file.
RT_FileQueryLines, gives number of lines in the multiline string (EDIT In file).
RT_TxtGetLine, extracts a single line from a multiline string.
Multiline string input and parse example:
http://forum.doom9.org/showthread.php?p=1588523#post1588523
EDIT: MDepan() also writes the motion data into the topmost line of the output clip. With RT_AverageLuma(w=1,h=1) it is already possible to do "pixel peeking
RT_AverageLuma(w=1,h=1) would return a value via this code:
return (float)((double)acc / Pixels)
as
return (float)((double)the_pixel_value / 1.0) # as Pixels (1) is coerced to double, division done, and then rounded to float.
Should return float representation of the int pixel value, although rounded conversion to int might be a good idea (probably NOT necessary).
EDIT: Rough guess, untested.
VideoFileName ="D:\AVS\AVI\1.d2v"
c=MPEG2Source(VideoFileName)
c
MDepan(...)
GScript("""
for (n=0,Framecount-1) {
RT_AverageLuma(n,w=1,h=1) # frame force read
}
""")
c # Hopefully destructor of temp last clip called here and log file available after here
As I learned from your explanation on the Call() plugin:
Dont place too much faith in that, mostly based on guesswork.
StainlessS
16th October 2012, 00:26
@Martin53, the below extracts the MDepan data as required, I'll leave the rest to you.
c=MPEG2Source("D:\AVS\AVI\1.d2v").Trim(0,5)
c
LOGFILE = "LogFile.Log"
LINEFILE = "C:\Temp\MotionData.log"
COMMAND = """cmd /c find /N " # " """ + LOGFILE + " >" + LINEFILE
v=MSuper().MAnalyse(isb = false)
gm=MDepan(v, log=LOGFILE, zoom=true, rot=true, range=1, thSCD1=960)
GScript(""" # Force MDepan analysis
for (n=0,Framecount-1) {
gm.RT_AverageLuma(n,w=1,h=1) # Force frame read of Global Motion clip, and MDepan testing.
}
""")
gm=0 # Destructor of temp Global Motion clip called here and log file available after here (created in Destructor)
c
CallCmd(COMMAND,"0,0",Insert="#",digits=1,Hide=true,Debug=true) # Extract line of motion data from log file prior each frame to scriptclip.
ScriptClip("""
MotionData=GetMotionData(LINEFILE)
return last
""",After_Frame=true) # NOTE, After_Frame
return last
Function GetMotionData(String fn) {
LOGSTR=RT_ReadTxtFromFile(fn,Lines=1,Start=2) # Skip blank line and "---------- LOGFILE.LOG" line.
LOGSTR=StrReplace(LOGSTR,Chr(10),"") # Remove Newline ie Chr(10)
RT_DEBUG("LOGSTR ='"+LOGSTR+"'")
LOGSTR=StrReplace(StrReplace(LOGSTR,"[",""),"]","") # Remove Line markers
RT_DEBUG("UNLINEMARKED ='"+LOGSTR+"'")
LOGSTR=StrReplaceDeep(LOGSTR," "," ") # Convert SPACE pairs to single SPACE
RT_DEBUG("SPACECOMPACTED='"+LOGSTR+"'")
LOGSTR=StrReplace(LOGSTR," ",",") # Convert SPACE to COMMA
RT_DEBUG("COMMACONVERTED='"+LOGSTR+"'")
MotionData = "Select(i, " + LOGSTR +")"
RT_DEBUG("MotionData ='"+MotionData+"'")
return MotionData
}
Function StrReplace(string s,string find,string replace) # Repeated, string replacements
# Original:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 By Vampiredom, Gavino, IanB
#{i=s.FindStr(find)return(i==0?s: s.LeftStr(i-1)+replace+s.MidStr(Strlen(find)+i).StrReplace(find,replace))}
# Converted to use RT_Stats RT_StrAddStr() to avoid 2.58/2.6a3 string concatenation bug:-
{i=s.FindStr(find) return(i==0?s:RT_StrAddStr(s.LeftStr(i-1),replace,s.MidStr(Strlen(find)+i).StrReplace(find,replace)))}
Function StrReplaceDeep(string s,string find,string replace) # DEEP Repeated, string replacements
# When replacing eg pairs of SPACE characters by single SPACE, StrReplace can leave some pairs non replaced.
# Assumes that you want to rescan where replaced string could constitute part of a new find substring,
# Length of replace must be shorter than length of find, else will call StrReplace instead.
# Based On:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 By Vampiredom, Gavino, IanB
# {i=s.FindStr(find)return i==0?s:s.LeftStr(i-1)+( strlen(replace)<strlen(find)? \
# StrReplaceDeep(replace+s.MidStr(Strlen(find)+i),find,replace) : replace+StrReplace(s.MidStr(Strlen(find)+i),find,replace))}
# Converted to use RT_Stats RT_StrAddStr() to avoid 2.58/2.6a3 string concatenation bug:-
{i=s.FindStr(find)return i==0?s:RT_StrAddStr(s.LeftStr(i-1),( strlen(replace)<strlen(find)? \
StrReplaceDeep(RT_StrAddStr(replace,s.MidStr(Strlen(find)+i)),find,replace) : \
RT_StrAddStr(replace,StrReplace(s.MidStr(Strlen(find)+i),find,replace))))}
Debug stuff
00000002 1.81485665 [2956] CallCmd: Constructor IN
00000003 1.81489933 [2956] CallCmd: CallCmd: v1.00 - 08 Oct 2012 - by StainlessS
00000004 1.81494594 [2956] CallCmd: Command for Frames = 'cmd /c find /N " # " LogFile.Log >C:\Temp\MotionData.log'
00000005 1.81499493 [2956] CallCmd: FRAMES: About to Parse Frames String
00000006 1.81504369 [2956] CallCmd: FRAMES: Line 1:1 0,5 $0,0
00000007 1.81509042 [2956] CallCmd: Doing command on 6 Frames
00000008 1.81513464 [2956] CallCmd: Constructor OUT
00000009 2.16997981 [2956] CallCmd: GetFrame(0) on command 'cmd /c find /N " 0 " LogFile.Log >C:\Temp\MotionData.log'
00000010 2.37153673 [2956] CallCmd: SUCCESS Creating Process
00000011 2.37663078 [2956] RT_Debug: LOGSTR ='[1] 0 0.00 0.00 0.000 1.00000'
00000012 2.38259101 [2956] RT_Debug: UNLINEMARKED ='1 0 0.00 0.00 0.000 1.00000'
00000013 2.41031384 [2956] RT_Debug: SPACECOMPACTED='1 0 0.00 0.00 0.000 1.00000'
00000014 2.42110348 [2956] RT_Debug: COMMACONVERTED='1,0,0.00,0.00,0.000,1.00000'
00000015 2.42123628 [2956] RT_Debug: MotionData ='Select(i, 1,0,0.00,0.00,0.000,1.00000)'
00000016 2.47051644 [2956] CallCmd: GetFrame(1) on command 'cmd /c find /N " 1 " LogFile.Log >C:\Temp\MotionData.log'
00000017 2.59828448 [2956] CallCmd: SUCCESS Creating Process
00000018 2.60344887 [2956] RT_Debug: LOGSTR ='[2] 1 -0.01 0.00 0.000 1.00000'
00000019 2.60861468 [2956] RT_Debug: UNLINEMARKED ='2 1 -0.01 0.00 0.000 1.00000'
00000020 2.63412428 [2956] RT_Debug: SPACECOMPACTED='2 1 -0.01 0.00 0.000 1.00000'
00000021 2.64520335 [2956] RT_Debug: COMMACONVERTED='2,1,-0.01,0.00,0.000,1.00000'
00000022 2.64533710 [2956] RT_Debug: MotionData ='Select(i, 2,1,-0.01,0.00,0.000,1.00000)'
00000023 2.67647266 [2956] CallCmd: GetFrame(2) on command 'cmd /c find /N " 2 " LogFile.Log >C:\Temp\MotionData.log'
00000024 2.80067348 [2956] CallCmd: SUCCESS Creating Process
00000025 2.80581069 [2956] RT_Debug: LOGSTR ='[3] 2 0.01 0.00 0.000 1.00000'
00000026 2.81096816 [2956] RT_Debug: UNLINEMARKED ='3 2 0.01 0.00 0.000 1.00000'
00000027 2.83819222 [2956] RT_Debug: SPACECOMPACTED='3 2 0.01 0.00 0.000 1.00000'
00000028 2.84876084 [2956] RT_Debug: COMMACONVERTED='3,2,0.01,0.00,0.000,1.00000'
00000029 2.84887767 [2956] RT_Debug: MotionData ='Select(i, 3,2,0.01,0.00,0.000,1.00000)'
00000030 2.84958386 [2956] CallCmd: GetFrame(3) on command 'cmd /c find /N " 3 " LogFile.Log >C:\Temp\MotionData.log'
00000031 2.97924876 [2956] CallCmd: SUCCESS Creating Process
00000032 2.98432541 [2956] RT_Debug: LOGSTR ='[4] 3 -0.01 0.28 0.033 1.00011'
00000033 2.98958492 [2956] RT_Debug: UNLINEMARKED ='4 3 -0.01 0.28 0.033 1.00011'
00000034 3.01530290 [2956] RT_Debug: SPACECOMPACTED='4 3 -0.01 0.28 0.033 1.00011'
00000035 3.02687788 [2956] RT_Debug: COMMACONVERTED='4,3,-0.01,0.28,0.033,1.00011'
00000036 3.02699447 [2956] RT_Debug: MotionData ='Select(i, 4,3,-0.01,0.28,0.033,1.00011)'
00000037 3.02782226 [2956] CallCmd: GetFrame(4) on command 'cmd /c find /N " 4 " LogFile.Log >C:\Temp\MotionData.log'
00000038 3.15263963 [2956] CallCmd: SUCCESS Creating Process
00000039 3.15752482 [2956] RT_Debug: LOGSTR ='[5] 4 -0.10 0.43 0.004 0.99982'
00000040 3.16313744 [2956] RT_Debug: UNLINEMARKED ='5 4 -0.10 0.43 0.004 0.99982'
00000041 3.18898296 [2956] RT_Debug: SPACECOMPACTED='5 4 -0.10 0.43 0.004 0.99982'
00000042 3.19961834 [2956] RT_Debug: COMMACONVERTED='5,4,-0.10,0.43,0.004,0.99982'
00000043 3.19973421 [2956] RT_Debug: MotionData ='Select(i, 5,4,-0.10,0.43,0.004,0.99982)'
00000044 3.20040274 [2956] CallCmd: GetFrame(5) on command 'cmd /c find /N " 5 " LogFile.Log >C:\Temp\MotionData.log'
00000045 3.35947132 [2956] CallCmd: SUCCESS Creating Process
00000046 3.36437130 [2956] RT_Debug: LOGSTR ='[6] 5 0.30 0.35 -0.009 0.99970'
00000047 3.37089896 [2956] RT_Debug: UNLINEMARKED ='6 5 0.30 0.35 -0.009 0.99970'
00000048 3.40061140 [2956] RT_Debug: SPACECOMPACTED='6 5 0.30 0.35 -0.009 0.99970'
00000049 3.41689062 [2956] RT_Debug: COMMACONVERTED='6,5,0.30,0.35,-0.009,0.99970'
00000050 3.41767979 [2956] RT_Debug: MotionData ='Select(i, 6,5,0.30,0.35,-0.009,0.99970)'
00000051 6.74900341 [2956] CallCmd: Destructor IN
00000052 6.75118876 [2956] CallCmd: Destructor OUT
EDITED: Moved contents of scriptclip text extraction/converting into a script function (precompiled).
EDIT: We could have loaded entire LogFile.Log into (EDIT: big) string and extracted single line at a time from it using
LINESTR=RT_TxtGetLine(LOGSTRING,current_frame) in ScriptClip, and avoid the CallCmd call to FIND the string.
travolter
28th October 2012, 10:15
@StainlessS
Im replying you from this thread
http://forum.doom9.org/showthread.php?p=1597871#post1597871
QueryBorderCrop() freezed image, and QueryLumaMinMax() not..
When I use robolevels(QBC=false) it does not freeze image but there is a problem. The image only show 5 colors: pink/orange/green/blue/white (remember me CGA) ;)
Im using your RT_Stats 20121003 and I use potplayer but also verified with mplayer. Using YV12 color space and overlay mixer as render.
No message appear when I write robolevels(QBC=false, Debug=true)
I only need to correct the levels.. maybe there is a workaround to solve the problem.
StainlessS
29th October 2012, 00:45
travolter,
Get this (MS DebugView):
http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx
Allows you to see messages coming out of scripts and other programs/filters.
And try
QueryLumaMinMax(debug=true) # for levels info
and
QueryBorderCrop(debug=true) # for test why fail
or
RoboLevels(QBC=false,debug=true) # for test why fail
A short sample that gives problems might be a good idea. Thanks.
EDIT:, you could also add this line just before the Levels() line near the end of RoboLevels function:
(DEBUG)? RT_Debug("Levels("+String(ALMin)+",1.0,"+String(AlMax)+","+String(CSMin)+","+String(CSMax)+",Coring=False)"):NOP
StainlessS
16th November 2012, 18:39
RT_TxtSort() error in docs, 'sort' should read 'mode'.
RT_TxtSort(String,int 'mode'=0)
Non-clip function.
Function to sort a Chr(10) separated multiline string.
The String arg is the name of the string, and 'mode' can be in range 0 to 7.
0 = Sort ascending, case insignificant
1 = Sort ascending, case significant
2 = Sort decending, case insignificant
3 = Sort decending, case significant
4 = Sort ascending, Filenames, digits sorted by value
5 = Sort ascending, Filenames, old style as for Windows 2000
6 = Sort decending, Filenames, digits sorted by value
7 = Sort decending, Filenames, old style as for Windows 2000
martin53
24th November 2012, 14:13
@Martin53, the below extracts the MDepan data as required, I'll leave the rest to you.
StainlessS,
thank you very much indeed for the work you put into this script!:thanks:
The task was part of my script FSubstitute - to get global pan/zoom/rotate information between two arbitrary frames of a clip.
I decided to also try a third option (besides of using MMask kind=5), because - according to what I found - the extraction script needs to be in a different RTE than MDepan, otherwise MDepan keeps the file handle locked and the file cannot be read from. In my case, MDepan must run in the RTE. Also, MDepan only delivers the values for two adjacent frames, so numerous extractions and further calculations would have been neccessary.
The third option is really cool: RT_LumaCorrelation between two frames typically has a maximum over varying x,y offset when the x,y is the global pan between these frames. I implemented a stepwise seek loop, and it is not even sooo slow. And what's best: with the same idea, but applied to the four quarters of the frame, you get data to calculate zoom and rotation. As if this were not enough, a real quadrilateral transformation that is possible with these data gives superior results than restriction to zoom & rotation. I.e. the third option excels the possibilities of MDepan, and it even opens the way for an idea of a deshaker based (almost) completely on AviSynth script level and existing plugins: That deshaker will maybe able to compensate tilt - something I don't know from any existing deshaker.
My apologies, if you feel disappointed that the extraction script is not used in my project. I hope you are compensated by the extraordinary value RT_LumaCorrelation has for my work.
StainlessS
24th November 2012, 15:26
My apologies, if you feel disappointed that the extraction script is not used in my project.
Not at all, it was an interesting exercise and resulted in the StrReplaceDeep mod which is a very useful alternative to StrReplace.
Good luck with your monster script. :)
martin53
2nd December 2012, 17:52
StainlessS,
thanks to your suggestions, mainly because of the destructor tricks I think, I was able to integrate MDepan into my 'monster script'. It produces good motion estimation and runs faster than the RT_LumaCorr approximation.
martin53
4th December 2012, 18:46
StainlessS,
could you extend RT_TxtWriteFile(String,String,bool "append") to be able to append to an existing file?
StainlessS
4th December 2012, 18:57
Yo, I hear you but not well able to tie a shoelace right now, will try again when a little less unable.
martin53
4th December 2012, 19:14
StainlessS,
I wondered if RT_[R,G,B,A]Plane... functions would be useful for RGB32 clips.
Especially for this advanced challenge: BlankClip(color=...) allows to create a 1x1 RGB32 clip with color being a 32bit variable.
ColorBars(pixel_type="RGB32")
Layer(BlankClip(pixel_type="RGB32",color=$60101010))
I.e. the 4 [A,R,G,B] bytes could be used to store one frame specific value with a reasonable resolution for many integer or float applications.
As an alternative and opposed to a ConditionalReader or RT_ReadTxtFromFile file, the clip benefits from AviSynth's frame cache, does not suffer from file system overhead, and should to my expectation not slow down too much with very high frame numbers.
With a function like RT_AverageARGB() or RT_ARGBPlanesMin() or whatever, the full 32bit value could hopefully be retrieved and used.
With StackHorizontal(), multiple 1x1 clips could be assembled to one and be read out with RT_AverageRGBA(x=..., w=1,h=1).
Too weird? :)
jmac698
5th December 2012, 09:35
Hi,
I've finally had an opportunity to use your plugin! But I'm having problems.
I have an rgb clip and I want to autocrop all the way around, per frame. In other words, this is a kind of tracking object thing.
Even worse, I need to scan all frames, find the max size, then render all frames at this max size and center each frame inside it.
Think of it this way, it's a video of a planet that's moving across the frame. The entire frame is black except one object. I need to show only this object centered on each frame. The frame size has to be consistent.
Think you could come up with something like that?
jmac698
5th December 2012, 09:52
I haven't been able to get it to crop at all. If I set samples too high it takes several minutes. Maybe this can't be done without a plugin?
Here's my files:
http://www.sendspace.com/file/wlcoa8
And my script:
dir="C:\Users\StainlessS\Pictures\moon\"
#IMG_5245 IMG_5288
s=5245
e=5288
imagereader(dir+"IMG_%04d.jpg",s,e,24,true)
#~ Function QueryBorderCrop(clip c,int "Samples",Float "Thresh",bool "Laced",int "XMod",int "YMod",int "WMod",int "HMod", \
#~ bool "Relative", String "Prefix",int "RLBT",bool "DEBUG",float "Ignore",int "Matrix")
v=QueryBorderCrop(samples=1,laced=false,xmod=1,ymod=1,wmod=1,hmod=1)
#messageclip(v)
eval(v)
#QBCropX=8 QBCropY=8 QBCropW=640 QBCropH=480
Crop(QBCropX,QBCropY,QBCropW,QBCropH)
StainlessS
5th December 2012, 10:39
Jmac, see here: http://forum.doom9.org/showthread.php?p=1589022#post1589022
I modded QueryBorderCrop for that script and made it super sensitive for single frames. Give it a whirl.
(by the way, QueryBorderCrop is way better than AutoCrop).
StainlessS,
could you extend RT_TxtWriteFile(String,String,bool "append") to be able to append to an existing file?
Good as done. (thinking about other suggestions).
jmac698
5th December 2012, 11:09
It's sort of working, fails after frame 17 though. Maybe there's some bright pixel entering the frame. But for the frames that it works, it's jumping around a lot.
StainlessS
5th December 2012, 12:09
Try the update just posted, not any great improvement, just allows using exact crop coords (RGB).
I'll keep playing with it for a bit.
EDIT: The main problem is, the autocrop is intended to remove real borders, and there aint any.
You would need to find a good Thresh setting.
StainlessS
5th December 2012, 12:38
Jmac, you have white edges left and bottom, crop them off in scripts and perhaps try an explicit rather than auto Thresh.
EDIT: Forget above, I forgot there is protection against just a very thin line at edges.
We are getting somewhere, I shall post a slight amendment to the QueryBorderCrop
script soon that should ONLY be used on this as a one off.
StainlessS
5th December 2012, 13:51
Jmac, make this temporary mod to QueryBorderCrop
#Rgt=w/2 Bot=h/2 Lft=Rgt-1 Top=Bot-1
Rgt=Int(w*0.1) Bot=Int(h*0.1) Lft=Int(w*0.9) Top=Int(h*0.9) # Mod For JMAC698
Normally searches only left half of image for left border, mod allows search 90% of width instead for your ODD requirement,
same for other sides.
Make this mod
AUTOCROP_THRESH = -3.0 # Default -32
CROPMODE = 0
To this script: http://forum.doom9.org/showthread.php?p=1604043#post1604043
Not prefect BUT, works pretty damn good [better than I might have expected] :)
StainlessS
5th December 2012, 15:07
Jmac, Use This Version
# EDIT To Suit (Requires QueryBorderCrop v1.09 & QueryLumaMinMax v1.01 & RT_Stats v1.06)
VID = False # True == Video : False == Pics, see IN_FILES directories/wildcards
IN_FILES = (VID) ? "D:\VID\*.AVI|MPG|MPEG" : "D:\MOON\*.BMP|JPG|JPEG|PNG" # Added '|' Pipe separator for multiple Wildcard in Extensions ONLY.
AUTOCROP = True # Crop off black borders.
AUTOCROP_THRESH = 0.6 # Default 0.0 allows QueryBorderCop to auto set super sensitive mode for single images, use default 0.0 normally
SHOWBORDER = True # True Show replaced border in Red, else Black. (Test AUTOCROP)
AUTOLEVEL_STRENGTH = 1.0 # AutoLevel Strength 0.0 -> 1.0
SHOWAUTOLEVEL = False # Right Hand Side Only AutoLeveled
#
#FAR = 4/3.0 # Required Frame Aspect Ratio
FAR = 1.0 # Required Frame Aspect Ratio
SzLimit = 0 # Limit shorter size (usually height, see FAR). 0 Does NOT Resize.
DEBUG = True # Debug
CROPMODE = 0 # 0=CropExact(RGB Only), 1=CropLess, 2=CropMore, 3=CropPlus
WMOD = 2
HMOD = 2
# ---------------------
# Lesser changed settings
BORDER = (SHOWBORDER) ? $FF0000: (VID) ? $101010 : $000000 # Color for replaced borders.
SUBS = False # Subtitles on clips/images
DEBUG_QBC = False # Debug QueryBorderCrop
DEBUG_QLMM = False # Debug QueryLumaMinMax
FPS = (VID) ? 30000.0/1001.0 : 1.0 # Whatever.
OUT_FILE = "FILE.List" # Dont need to change really, just a name.
SCANPERC = 90.0 # Percentage of each side to scan in AutoCrop, see below link for reason.
# # http://forum.doom9.org/showthread.php?p=1604004#post1604004
#--------------------------------------------------------------------------------
GScript("""
picclip = 0 # Dummy for now
result=RT_WriteFileList(IN_FILES,OUT_FILE) # Create a listing file of Pic files
Assert((result!=0), "No files found")
FILELIST=RT_ReadTxtFromFile(OUT_FILE) # Get list of files
FILES=RT_TxtQueryLines(FILELIST) # Query Number of lines in String ie number of files.
(DEBUG) ? RT_Debug("Found files = " + String(FILES)) :NOP
# Prescan to ascertain max wid/hit of all files, also Autocrop & Auto Levels
MAXH=0 MAXW=0 # init max wid and hit
CROPCOORDS="" # Clear results array (string)
AUTOLEVELS="" # Clear AutoLevels array (string)
AUTOLEVEL=(AUTOLEVEL_STRENGTH>0.0) # Adjust using Levels.
QBCTrailer=Select(CROPMODE,"=","L=","M=","P=")
For(i=0,FILES-1) {
FN=RT_TxtGetLine(FILELIST,i) # Filename of pic/vid file i
(DEBUG)?RT_Debug(String(i+1)+"/"+String(FILES)+") Getting File dimensions",FN):NOP
if(VID) {
k=DirectshowSource(FN)
k=k.ConvertToYUY2().Trim(0,0)
} else {
k=ImageReader(FN,end=0).ConvertToRGB32() # With Bmap, some come up as RGB24 bit some RGB32.
}
OrgW=k.width OrgH=k.height
W=OrgW H=OrgH # Pre-Duplicate in case of no AUTOCROP
if (AUTOCROP) {
if(AUTOCROP_THRESH == 0.0) { # Call without Thresh arg, allows use of auto super sensitive setting for single frame images
QBC = k.QueryBorderCrop(samples=24,laced=VID,debug=(DEBUG&&DEBUG_QBC),ScanPerc=ScanPerc)
} else { # Will prevent auto super sensitive from working, use on images with real borders
QBC = k.QueryBorderCrop(samples=24,Thresh=AUTOCROP_THRESH,laced=VID,debug=(DEBUG&&DEBUG_QBC),ScanPerc=ScanPerc)
}
Eval(QBC) # Set Avisynth vars
k=k.Crop(QBCropXM,QBCropYM,QBCropWM,QBCropHM) # OVERCROP using CropMore
QBC = RT_TxtGetLine(QBC,CROPMODE) # Extract REQUIRED mode, CropLess, CropMore etc
QBC1=StrReplace(QBC,QBCTrailer,"=") # Change all to style without a trailer eg QBCropXM to QBCropX.
QBC2=StrReplace(QBC1,"QBC","C") # Change all style QBCropX to CropX
Eval(QBC2) # Get the required cropmode into CropX,CropY,CropW,CropH
W=CropW H=CropH # The actual required crop mode dimensions.
CROPCOORDS=RT_TxtAddStr(CROPCOORDS,QBC2) # Avisynth Bugfix, same as CROPCOORDS = CROPCOORDS + QBC + Chr(10)
}
if (AUTOLEVEL) {
QLMM = k.QueryLumaMinMax(debug=(DEBUG&&DEBUG_QLMM)) # Query luma levels (on overcropped clip if AUTOCROP)
Eval(QLMM) # Set Avisynth vars
AUTOLEVELS=RT_TxtAddStr(AUTOLEVELS,QLMM) # Avisynth Bugfix, same as AUTOLEVELS = AUTOLEVELS + QLMM + Chr(10)
}
If(MAXW<W) {MAXW=W}
If(MAXH<H) {MAXH=H}
if (DEBUG) { # KEEP main debug messages together
RT_Debug ("Orig Width =",String(orgW),"Orig Height =",String(OrgH))
if((W != OrgW) || (H != OrgH)) { # Was Caused by AUTOCROP
RT_Debug("AutoCrop Width =",String(W),"AutoCrop Height =",String(H))
(AUTOLEVEL) ? RT_Debug("AutoLevel On Cropped : Min=",String(QLMMMin)," Max =",String(QLMMMax)) : NOP
} else {
(AUTOCROP) ? RT_Debug("AutoCrop Found no borders") : NOP
(AUTOLEVEL)? RT_Debug("AutoLevel NonCropped : MinLuma=",String(QLMMMin)," MaxLuma =",String(QLMMMax)) : NOP
}
RT_Debug("MAX Width So Far =",String(MAXW),"MAX Height So Far =",String(MAXH))
RT_Debug(" ----------------------------- ") # line separator
}
}
maxFAR = Float(MAXW) / MAXH
if(FAR >= maxFAR) {
# Required Frame Aspect Ratio greater or same as maximum accumulated dimensions. Need to pad horizontal
if(SzLimit == 0) { # NO SIZE LIMITING, Pad Only
canvasheight = Int((MAXH + (HMOD/2)) / HMOD) * HMOD
canvaswidth = Int((canvasheight * FAR + (WMOD/2)) / WMOD) * WMOD
} else { # Resize with SIZE LIMITING
canvasheight = (MAXH < SzLimit) ? Int((MAXH + (HMOD/2)) / HMOD) * HMOD : MAXH
canvasheight = (canvasheight > SzLimit) ? SzLimit : canvasheight # enforce SzLimit max
canvaswidth = Int((canvasheight * FAR + (WMOD/2)) / WMOD) * WMOD
}
} else { # Need to pad vertical
if(SzLimit == 0) { # NO SIZE LIMITING, Pad Only
canvaswidth = Int((MAXW + (WMOD/2)) / WMOD) * WMOD
canvasheight = Int((canvaswidth / FAR + (HMOD/2)) / HMOD) * HMOD
} else { # Resize with SIZE LIMITING
canvaswidth = (MAXW < SzLimit) ? Int((MAXW + (WMOD/2)) / WMOD) * WMOD : MAXW
canvaswidth = (canvaswidth > SzLimit) ? SzLimit : canvaswidth # enforce SzLimit max
canvasheight = Int((canvaswidth / FAR + (HMOD/2)) / HMOD) * HMOD
}
}
if(DEBUG){RT_Debug("SETTING CanvasWidth =",String(canvaswidth)," CanvasHeight =",String(canvasheight))}
if(DEBUG){RT_Debug(" ----------------------------- ")} # line separator
For(i=0,FILES-1) {
FN=RT_TxtGetLine(FILELIST,i) # Filename of pic/vid file i
if(DEBUG){RT_Debug(string(i+1)+"/"+String(FILES)+")","Processing File",FN)}
if(VID) {
k=DirectshowSource(FN).ConvertToYUY2().Trim(0,0)
} else {
k=ImageReader(FN,end=0).ConvertToRGB32() # RGB24 problems with addborders
}
OrgH=k.height OrgW=k.width
if (AUTOLEVEL) {
# We do AUTOLEVELS before crop, because of SHOWAUTOLEVEL
QAT = RT_TxtGetLine(AUTOLEVELS,i)
Eval(QAT)
if(k.IsYUV()) {
CSMin = 16
CSMax = 235
} else {
CSMin = 0
CSMax = 255
}
TMP_K=k
ALMin = Int(CSMin - ((CSMin - QLMMMin) * AUTOLEVEL_STRENGTH) + 0.5) # Round Up
ALMax = Int(CSMax - ((CSMax - QLMMMax) * AUTOLEVEL_STRENGTH)) # Round down
k = k.Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DONT EVER USE Coring
(DEBUG) ? RT_Debug("Levels("+String(ALMin)+",1.0,"+String(AlMax)+","+String(CSMin)+","+String(CSMax)+",Coring=False)") : NOP
if(SHOWAUTOLEVEL) {
tmpw=int((k.width/4)*2)
Left = TMP_K.Crop(0,0,tmpw,-0)
Right= k.Crop(tmpw,0,-0,-0)
k=StackHorizontal(Left,Right)
}
}
if (AUTOCROP) {
QBC = RT_TxtGetLine(CROPCOORDS,i) # Get required coords from first pass
Eval(QBC) # Set variables in Avisynth, ie CropX etc
k=k.Crop(CropX,CropY,CropW,CropH)
(DEBUG)? RT_Debug("Crop("+String(CropX)+","+String(CropY)+","+String(CropW)+","+String(CropH)+")") : NOP
}
iWidth=k.Width() iHeight=k.Height()
cFAR = Float(canvaswidth) / canvasheight
iFar = Float(iWidth) / iHeight
Left=0 Top=0 Right=0 Bot=0
if(SzLimit==0) {
Left = (canvaswidth-iWidth) / 2
Right = canvaswidth-iWidth - Left
Top = (canvasheight-iHeight) / 2
Bot = canvasheight-iHeight-Top
owid = iWidth
oHit = iHeight
(DEBUG) ? RT_Debug("AddBorders("+String(Left)+","+String(Top)+","+String(Right)+","+String(Bot)+")") : NOP
k = k.Addborders(Left,Top,Right,Bot,BORDER)
} else {
if(cFAR >= iFAR) { # Canvas Aspect ratio greater (proportionally wider), resize to vertical and pad horizontal
oHit = canvasheight
oWid = Int(oHit*iFAR/4)*4
Left = (canvaswidth-oWid) / 2
Right = canvaswidth - oWid - Left
} else { # Canvas Aspect ratio smaller (proportionally taller), resize to horizontal and pad vertical
oWid = canvaswidth
oHit = Int(oWid/iFAR/4)*4
Top = (canvasheight-oHit) / 2
Bot = canvasheight - oHit - Top
}
if(DEBUG) {
RT_Debug("Spline36Resize("+String(oWid)+","+String(oHit)+")")
RT_Debug("AddBorders("+String(Left)+","+String(Top)+","+String(Right)+","+String(Bot)+")")
}
k = k.Spline36Resize(oWid,oHit).Addborders(Left,Top,Right,Bot,BORDER)
}
k=k.assumefps(fps)
if(SUBS) {
k=k.subtitle(String(i) + "/"+String(FILES-1) +" " + FN)
k=k.subtitle("Orig width=" + string(orgW) +" " + "Orig height=" + string(orgH) +" FAR="+String(Float(orgW) /orgH, "%.2f"),20,20)
if (AUTOCROP) {k=k.subtitle("Crop width=" + string(iWidth) +" " + "Crop height=" + string(iHeight) +" FAR="+String(Float(iWidth) /iHeight, "%.2f"),20,40)
} else {k=k.subtitle("NO AUTOCROP",20,40)}
k=k.subtitle("New width=" + string(oWid) +" " + "New height=" + string(oHit)+" FAR="+String(Float(oWid)/oHit,"%.2f"),20,60)
k=k.subtitle("Out width=" + string(k.Width) +" " + "Out height=" + string(k.Height)+" FAR="+String(Float(k.Width)/k.Height,"%.2f"),20,80)
if(AUTOLEVEL) {
k=k.subtitle("QLMMMin = " + String(QLMMMin) + " QLMMMax = " +String(QLMMMAx),20,120)
k=k.subtitle("AUTOLEVEL @ " + String(AUTOLEVEL_STRENGTH*100.0,"%.0f") + "%",20,140)
k=k.subtitle("Auto Levels(" + String(ALMin) + ",1.0," + String(ALMAx) + "," + String(CSMin) + "," + String(CSMax) + ")",20,100)
} else {k=k.subtitle("NO AUTOLEVEL",20,100)}
}
picclip = (IsClip(picclip)) ? picclip ++ k : k # Append to clip so far
if(!VID){k=k.ConvertToRGB24()}
if(DEBUG){RT_Debug(" ") RT_Debug(" ----------------------------- ")} # line separator
}
""")
PicClip
return Last
Function StrReplace(string s,string find,string replace) # Repeated, string replacements
# Original:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 By Vampiredom, Gavino, IanB
#{i=s.FindStr(find)return(i==0?s: s.LeftStr(i-1)+replace+s.MidStr(Strlen(find)+i).StrReplace(find,replace))}
# Converted to use RT_Stats RT_StrAddStr() to avoid 2.58/2.6a3 string concatenation bug:-
{i=s.FindStr(find) return(i==0?s:RT_StrAddStr(s.LeftStr(i-1),replace,s.MidStr(Strlen(find)+i).StrReplace(find,replace)))}
Function StrReplaceDeep(string s,string find,string replace) # DEEP Repeated, string replacements
# When replacing eg pairs of SPACE characters by single SPACE, StrReplace can leave some pairs non replaced.
# Assumes that you want to rescan where replaced string could constitute part of a new find substring,
# Length of replace must be shorter than length of find, else will call StrReplace instead.
# Based On:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 By Vampiredom, Gavino, IanB
# {i=s.FindStr(find)return i==0?s:s.LeftStr(i-1)+( strlen(replace)<strlen(find)? \
# StrReplaceDeep(replace+s.MidStr(Strlen(find)+i),find,replace) : replace+StrReplace(s.MidStr(Strlen(find)+i),find,replace))}
# Converted to use RT_Stats RT_StrAddStr() to avoid 2.58/2.6a3 string concatenation bug:-
{i=s.FindStr(find)return i==0?s:RT_StrAddStr(s.LeftStr(i-1),( strlen(replace)<strlen(find)? \
StrReplaceDeep(RT_StrAddStr(replace,s.MidStr(Strlen(find)+i)),find,replace) : \
RT_StrAddStr(replace,StrReplace(s.MidStr(Strlen(find)+i),find,replace))))}
Updated, needs RT_Stats 1.06
EDIT: See PlanetCrop() available in RT_Stats zip (much better for this purpose).
StainlessS
5th December 2012, 16:35
Modified previous post.
jmac698
5th December 2012, 17:05
You're amazing, thanks for the effort! I really think that is a useful script though, there is a need in astrophotography sometimes to crop out and track planets. That's because our software, like any other, has to search the entire image to align frames, and it's very slow, and can be beyond the search radius for matching. So this type of "pre-alignment" really speeds up the programs.
I can also see me making use of this in moviemaking, to keep the frame centered on an object just by mounting a light on it. It can be used to deshake in certain situations.
StainlessS
5th December 2012, 17:12
The Video Joining capability of the script is pretty handy too.
I'll implement the QueryBorderCrop mod today and do the Martin53 requested mod to RT_Stats and up within a couple of hours.
(And you said that QueryBorderCrop() would never work, hehehehe) :)
jmac698
5th December 2012, 18:30
Ok, I've tried it now, and it fails on frame 13. It also seems like it's being resized.
martin53
5th December 2012, 21:12
... and do the Martin53 requested mod to RT_Stats ...
don't hurry! Btw., I was able to write a 'proof of concept':
#==========================================
# Luma2argb puts the average luma of clip 'cMeasured' into the ARGB bytes of container clip
#
function Luma2argb(clip cMeasured) {
cContainer = blankclip(cMeasured, pixel_type="RGB32", width=1, height=1)
return cContainer.GScriptClip("""
longVal = round($1000000*cMeasured.RT_AverageLuma(Matrix=2)) #longVal is supposed to be 4 bytes long: $aa,rr,gg,bb.
return Blankclip(last, color=longVal) #Put high byte to alpha, next bytes to red,gren,blue: easy because color parameter of function BlankClip does just this!)
""", args="cMeasured")
}
#==============================================
# Argb2float returns a float value from ordered alpha, red, green and blue channels in the range 0...255.99999999
# inputs: clip, frame delta and current frame numbers
# output: quality
#
function Argb2float(clip c, int delta, int currentframe) {
a = c.ShowAlpha().RT_AverageLuma(n=currentframe, delta=delta, Matrix=2)
r = c.ShowRed().RT_AverageLuma(n=currentframe, delta=delta, Matrix=2)
g = c.ShowGreen().RT_AverageLuma(n=currentframe, delta=delta, Matrix=2)
b = c.ShowBlue().RT_AverageLuma(n=currentframe, delta=delta, Matrix=2)
return a + r/$100 + g/$10000 + b/$1000000
}
c = something...
cAL = c.Luma2argb() #cAL holds the AverageLuma of C with 32bit res.
c.GScriptClip("""
subtitle(string(cAL.Argb2float(1, current_frame))) #displays AverageLuma of following frame :) :) :)
""", args="cAL")
StainlessS
5th December 2012, 22:31
RT_Stats v1.06, see 1st post.
Jmac, Post #70 updated, still playing with it, converting to CropExact has some other probs that dont quite work.
I'll try to mod for your purpose in addition to current usage.
The original script is intended to do resizing, its function is to join dissimilar pics/vids together and resizing/addborders to a required
aspect ratio and size limit. Going to the pub now, and as I have been up since about 2:00AM, probably not do anything else today.
Martin53, have updated RT_stats with append update, the RGB stuff was what I was pondering.
Dont think a good idea as suggested, AverageLuma is float return and your suggested func would not be precise enough for
uses that it may be put to. Anyways, take a look at Showchannels updated today, easily used with scriptclip.
Cheers. :)
EDIT: The pubs shut way too early.
StainlessS
7th December 2012, 20:11
Jmac, post #70 updated, added No Resize functionality by setting SzLimit=0
notes here (too big for post 70, overflows limit) :
# Single Frame Super Sensitive, switched on when samples == 1 or single frame, intention to make as sensitive as possible hopefully without overcrop.
# Single frame Super Sensitive AutoThresh (arg Thresh = -ve), internally sets AutoThresh to -0.5, ie relative to YPlaneMin, == YPlaneMin + 0.5.
# Single frame Super Sensitive AutoThresh would have worked fine, was the halfway scan (ie SCANPERC==50.0%) that inhibited detection.
# YPlaneMin=0 All images, so AutoThresh of Little Use, Equivalent to Thresh = 0.5 on all frames.
# With SzLimit == 0 (NO RESIZING, Crop & AddBorders Only, and FAR == 1.0 [Frame Aspect Ratio 1:1])
# 0.5 keeps good margin all around without coming close to chopping off any Moon (954x954).
# 0.6 Close but clear margin Top, rest, bigger margin (922x922)
# 0.75 Just about touches top of moon, other sides good margin (862x862)
Still working on it but is pretty good right now, try with AUTOCROP_THRESH = 0.6
Going to try to implement keeping some of the margins instead of adding synthetic borders, to fit the
required aspect ratio (ie partially ignoring the crop coords where possible) to keep as much of the original
image as we can.
There is a problem (only with your type task). You will see that it detects very close to top/bottom of
the moon, but quite a margin left/right. This is due to the fact that we scan top and bot to find borders,
and then left and right, BUT, left/right scan only scans between the already established top and bottom
borders. With the top/bot scan a small number of lighter pixels in a vast expanse of black line requires
a very low threshold, but when we scan a much reduced vertical line length in the lft/rgt scan
(due to limiting to top/bot borders), so any approx same number or lighter pixels in the much reduced
sample line length does not require such a small thresh.
I shall try to rectify this, perhaps by adding some kind of threshold scaler based on scanline length
compared with perhaps full image width to try and achieve a comparable thresh.
Give it a whirl, works great and getting better.
martin53
7th December 2012, 21:23
the RGB stuff ... Dont think a good idea as suggested
StainlessS,
never mind. I think similar - it would be not generic as suggested. The 'proof of concept' works excellent. We could still get back to it and maybe handle exponent and signs of mantissa and exponent in a way that would really allow a floating point number, and maybe use 2 pixels to store 64 bits - if it fulfills a certain need better than other solutions.
:thanks: for the 'append'. Cheers - enjoy the pub!
StainlessS
7th December 2012, 21:45
Can always implement an eg RGB_AverageR etc, returning all three at once possible in string but would not really want to encourage scanning every pixel of a clip especially as strings are never released until close. Guess RGB24 could be returned in int, but not RGB32 which I'm guessing might produce some kind of overflow error when trying to extract alpha in script (maybe not, vb would overflow).
Might even be possible to take some args and manufacture a float.
(assume for your hinting thing).
Cheers - enjoy the pub!
and Cheers to you sir, I always enjoy the pub, on my way presently. :)
StainlessS
8th December 2012, 21:29
@Martin53,
Hows about this. Func to return combined rgb data (as for single clip Luma funcs, excluding comparison funcs), for all channels,
eg ave, max, min, YInRange, YPlaneMedian, YPlaneMinMaxDifference, all as Global Variables, with a user supplied Prefix.
Should be reasonably fast and no string accumulation probs. A Similar luma func could also be of use, and avoid multiple
func calls in some situations. Implemented as for RT_ luma funcs with eg laced arg and x,y,w,h.
EDIT:
@Jmac, got both "keep margin" and "thresh scaling" done, works brilliant, just a bit of tidying up to do.
Here's something to try.
EDIT: Link Removed.
jmac698
9th December 2012, 11:55
Tried it, working great! Wonder why it jumps a little though, did you see something in the background to mess it up?
jmac698
9th December 2012, 12:38
Ok,
I've tried another example and now I'm having a lot of trouble. I can't get it to work at all, and when changing around some parameters, sometimes it makes a letterbox on the video, I don't know why.
You've done so much, but it would be great if you could help me figure out this one:
http://www.sendspace.com/file/f4qh1v
StainlessS
9th December 2012, 16:47
Wonder why it jumps a little though
Who knows, maybe starlight making minor differences.
The moon is a little dark at the top and hence the close cropping there, and the bottom has
a bit of a halo around it hence the not quite so close cropping.
It's not a de-jitterer, it just crops when the scaled thresh is broken for 3 consecutive scanlines (h/v).
Shall download the 2nd sample and have a play.
PS, the "Insert Link" button works fine in Quick Reply.
martin53
9th December 2012, 16:58
@Martin53,
Hows about this. Func to return combined rgb data (as for single clip Luma funcs, excluding comparison funcs), for all channels,
eg ave, max, min, YInRange, YPlaneMedian, YPlaneMinMaxDifference, all as Global Variables, with a user supplied Prefix.
If you don't mind, please have a look at the 'proof of concept' code.
The intention and use case I had in mind is this:
You need a number that is frame specific. Today, you have the options
- Store it in a text file in a prior pass and read it in, e.g. with ConditionalReader() or with RT_Stats.
____Not so nice since you need multiple passes and have to create (unique) file names.
- Evaluate it directly from where it comes from.
____Slow and memory consuming if the evaluation is complicated.
- Use a veeerrry long string as comma separated list and Eval("Select(..." it.
____Not applicable to my experience with really long clips. Slow, I suspect.
The 'new' idea is, to store a floating point variable in a clip, because the clip has the neccessary property to be an 'array', the frame number being the index into the array, and AviSynth's frame cache will provide fast access to several elements of the array, as long as they are accessed frequently before being kicked out of the cache.
I started with 32 bits resolution and fixed point (range 0...256) for the variable. Of course, a real floating point variable would rather have bits for the signs of mantissa end exponent and fields of some width to store mantissa and exponent themselves.
What I really would like to point out, is, that one argb pixel can really be regarded as one variable. With two pixels of rgb24 etc, finer resolutions are easy to think of. I dont know what the AviSynth resolution of type float is. But the typical 6 digit display does not need more than 20 bits for the mantissa, so another 10 bits would be free for the exponent, thus allowing -1,048,576e-1024...1,048,575e1023 with an accurracy of 6 digits to be stored in the 1x1argb clip. A pair of functions that just stored the bits from a float variable into the - say - 8 bytes of a 1x2 argb clip and retrieved it to a float variable again would make a fine interface to use the kind of 'array of float' that I decribed above.
jmac698
9th December 2012, 20:24
Yeah, the same idea is used in avsLib where this is all done for you. Or you could move to Vapoursynth.
StainlessS
10th December 2012, 02:06
Martin53,
Function Luma2argb(clip cMeasured) {
cContainer = blankclip(cMeasured, pixel_type="RGB24", width=1, height=1)
return cContainer.GScriptClip("""
FV=cMeasured.RT_AverageLuma(Matrix=2)
longVal = round($10000*FV) #longVal is supposed to be 3 bytes : $rr,gg,bb.
RT_Debug("FV="+String(FV),"LONGVAL="+String(LongVal))
return Blankclip(Last, color=longVal) #Put high byte to red,then green,blue
""", args="cMeasured")
}
Function Argb2float(clip c, int delta, int currentframe) {
r = c.RGB_ChanAve(n=currentframe, delta=delta, chan=0)
g = c.RGB_ChanAve(n=currentframe, delta=delta, chan=1)
b = c.RGB_ChanAve(n=currentframe, delta=delta, chan=2)
RT_Debug("R="+String(R),"G="+String(G),"B="+String(B))
return r + g/$100 + b/$10000
}
c = ColorBars().Trim(0,-2) # With Matrix=0(rec601)==97.900780 : Matrix=2(pc601)=95.287369
cAL = c.Luma2argb() #cAL holds the AverageLuma of C with 24bit res.
c.GScriptClip("""
subtitle(string(cAL.Argb2float(1, current_frame))) #displays AverageLuma of following frame :) :) :)
""", args="cAL")
return last
Above uses only RGB24, 24 bits, same as mantissa in Avisynth float.
Note, Max value return by AverageLuma & RT_AverageLuma is 255.0 not 255.99999
I knocked up a temp func, RGB_ChanAve() as for RT_AverageLuma but without the matrix arg but additional chan arg (0-3==RGBA [0==R]).
EDIT: Link Removed.
In original script, dont think I noticed any value in the blue channel at all (other than 0).
Here a Jmac thread on float/int conversion:
http://forum.doom9.org/showthread.php?t=163038&highlight=mantissa
EDIT: You might want to edit the func names (remove the "A"), may or may not want to pack into RGB32.
martin53
10th December 2012, 18:51
StainlessS,
I appreciate RGB_ChanAve()! Thank you!
If I asked you if you can make a function that just 'typecasts' float-->RGBA and another one that 'typecasts' RGBA-->float, i.e the first takes a float and returns a valid 'color' in range 0 ...$ff.ff.ff.ff without further calculation, just the 4 bytes, the 2nd one is like RGB_ChanAve, say 'RGB_2float()' and directly returns type float from the 4 channels of the pixel, would you like to help me with that?
Edit: assume to only allow RGB_2float(w=1, h=1)
martin53
10th December 2012, 19:11
Yeah, the same idea is used in avsLib
... with that, you mean the very long string, right? Then, as only one matter, the string concatenation issue of AviSynth 2.6 affects AVSLib too, and makes the whole lib practically useless.
Or you could move to Vapoursynth.
Vapoursynth interests me very much, but I didn't take time to read more thoroughly through the doc. Can you please say a word about runtime environment in Vapoursynth ('ScriptClip()' etc). Is that supported?
StainlessS
10th December 2012, 20:09
('ScriptClip()' etc). Is that supported?
So far as I know, Avisynth script is not supported and so neither would ScriptClip be. (leastwise not yet)
But perhaps a Vapoursynth similar func is available.
(gonna sleep a few days and come back and read other posts).
StainlessS
11th December 2012, 18:33
@Martin53,
Done what you require but adding it and other stuff to RT_Stats (eg RT_BitAND, RT_BitSet, RT_Hex).
I've implemented as RT_RgbChanAve, RT_RGB32AsFloat, and RT_FloatAsRGBA, if you dont like names,
then suggest others.
RT_RGB32AsFloat() given args similar to eg RT_AverageLuma excluding w,h interlaced and matrix, so you could
store a two dimensional array of float using StackHorizontal/Vertical (presume thats what you wanted).
@Jmac,
Gonna have another crack at your moon prob soon as I get this RT_Stats stuff out of the way, need to
attack from a different direction.
EDIT:
so you could store a two dimensional array of float using StackHorizontal/Vertical.
Three dimensional if you count frame number.
martin53
11th December 2012, 22:00
RT_RgbChanAve, RT_RGB32AsFloat, and RT_FloatAsRGBA
magnificent! :thanks:
I am going to test it tomorrow or Thursday.
StainlessS
12th December 2012, 00:42
Temporary version RT_Stats 1.07beta.
New funcs noted here:
RT_Stats Avisynth Plugin by StainlessS
RT_RgbChanAve(clip,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)
Return the average value for an RGB channel (RGB 24/32). (default = 0 = R [RGBA])
RT_FloatAsRGBA(float)
Given a float arg, returns an int formatted as for use as a color to eg BlankClip.
Can later be recovered from that clip using RT_RGB32AsFloat().
RT_RGB32AsFloat(clip,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0)
Given an RGB32 clip that had a pixel value created via RT_FloatAsRGBA(), gets that pixel and returns as the
original float given to RT_FloatAsRGBA. By creating single pixel clips and stacking them horizontally/vertically,
you can use frames as a two dimensional array of float, perhaps use the frame number for a third dimension.
RT_GraphLink(clip source, clip c1, ... , clip cn, bool b1, ... , bool bn)
Standard filter function.
This function is a standard filter graph function, not a runtime/compile time function.
It takes a compulsory source clip which it will return unchanged.
The clips, c1 to cn (one or more, at least one of them) are by default forcibly linked into
the filter graph. The bools b1 to bn are optional (zero or more) and would default to True
if not supplied. These bools will if false, switch OFF the forcible linking into the filter graph
for the corresponding clip c1 to cn.
Avisynth does not normally process any filter chains that do not contribute to the output clip,
this filter allows you to select graph chains that you wish to forcibly process.
The usual way to force process an unused chain is to do a stackHorizontal/Vertical and a crop.
All args un-named.
Example: [will only render the TestA" and TestC images]
a=ImageSource("d:\avs\1.jpg",end=0) # Single frame
TmpA = a.subtitle("TestA").ImageWriter("d:\avs\TestA_", type="png") # Written
TmpB = a.subtitle("TestB").ImageWriter("d:\avs\TestB_", type="png") # Skipped
TmpC = a.subtitle("TestC").ImageWriter("d:\avs\TestC_", type="png") # Written
RT_GraphLink(a,TmpA,TmpB,TmpC,True,false) # 3rd bool defaults true
return Last
RT_Hex(int , int "width"=0)
First arg is an integer to convert to a hexadecimal string.
'width' is the minimum width of the returned string.
eg RT_Hex(255,4) returns "00FF".
RT_HexValue(String)
Returns an int conversion of the supplied hexadecimal string.
Fixes a HexValue bug in 2.58 & 2.6a3.
RT_BitNOT(int)
Returns the integer result of a bitwise NOT operation on it's int argument.
RT_BitAND(int, int)
Returns the integer result of a bitwise AND operation on the two int arguments.
RT_BitOR(int, int)
Returns the integer result of a bitwise OR operation on the two int arguments.
RT_BitXOR(int, int)
Returns the integer result of a bitwise XOR operation on the two int arguments.
RT_BitLSL(int, int)
Returns the integer result of a Logical Shift Left on the first integer, by a shift count of the second int.
An Arithmetic Shift Left and a Logical Shift Left, are essentially the same.
RT_BitLSR(int, int)
Returns the integer result of a Logical Shift Right on the first integer, by a shift count of the second int.
Logical shift right will shift zeros into the high bits.
RT_BitASL(int, int)
Returns the integer result of an Arithmetic Shift Left on the first integer, by a shift count of the second int.
An Arithmetic Shift Left and a Logical Shift Left, are essentially the same.
RT_BitASR(int, int)
Returns the integer result of an Arithmetic Shift Right on the first integer, by a shift count of the second int.
Arithemtic shift right will shift into the high bits, zeros for a +ve number and ones for a -ve number, so -ve
numbers will stay -ve and +ve stay +ve.
RT_BitTST(int, int)
Returns the bool result of a bit test on first integer, the bit number is given in the second int.
A zero in the bit returns False and a 1 returns True.
RT_BitCLR(int, int)
Returns the integer result of a bit clear (make 0) on first integer, the bit number is given in the second int.
RT_BitSET(int, int)
Returns the integer result of a bit Set (make 1) on first integer, the bit number is given in the second int.
RT_BitCHG(int, int)
Returns the integer result of a bit change (0->1, 1->0) on first integer, the bit number is given in the second int.
RT_BitROR(int, int)
Returns the integer result of a bit Rotate Right on first integer, the bit rotate count is given in the second int.
RT_BitROL(int, int)
Returns the integer result of a bit Rotate Left on first integer, the bit rotate count is given in the second int.
http://www.mediafire.com/?lejdpznk631hdnd
Martin53, Testem all out if you can, Not had much testing here, done all of the funcs bar RT_RgbChanAve()
today, and I'm a bit whacked out.
EDIT: You interested in storing ints in a clip too ?
EDIT:
so you could store a two dimensional array of float using StackHorizontal/Vertical.
Three dimensional if you count frame number.
With a little thought you could have 4 dimensions using n and delta.
EDIT: Have now implemented RT_RGB32AsInt(), no need for a sister func.
StainlessS
16th December 2012, 22:14
Jmac, see below PlanetCrop() works great, even with your 2nd moon image set.
#import("D:\AVS\BANK\QueryLumaMinMax.avsi")
Fn="D:\MOON\*.JPG|BMP"
BAFFLE = 12 # Number of consecutive scanlines that need to pass, below considered noise.
BLK = 32 # Where black sky can vary in brightness
GROW_W = 256 # Enlarge canvas width by GROW_W pixels (keep surround area, Use with KEEP_MARGIN)
GROW_H = 256 # Enlarge canvas height by GROW_H pixels
FAR = 1.0 # Frame Aspect Ratio
STRENGTH = 1.0 # AutoLevel Strength 0.0 -> 1.0
SHOWAL = True # Right Hand Side Only AutoLeveled
KEEP = true # True tries to keep some of the cropped area instead of AddBorders
SHOWKEEP = true # Show Kept margin
SHOWBORDER = true # True Show replaced border in Red, else Black. (FAR affects) (Test CROP)
DEBUG = True
Return PlanetCrop(Fn,BAFFLE,BLK,GROW_W,GROW_H,FAR,STRENGTH,SHOWAL,KEEP,SHOWKEEP,SHOWBORDER,DEBUG)
#--------------------------------------------------------------------------------
Function PlanetCrop(String "FileName",int "Baffle",Int "BlackRange",int "Grow_W",int "Grow_H",Float "FAR", \
Float "AutoLevelStrength",bool "ShowAutoLevel",bool "KeepMargin",bool "ShowMargin",bool "ShowBorder",bool "Debug") {
# PlanetCrop v1.0 - 16 Dec 2012
#
# Requires GScript, RT_Stats and QueryLumaMinMax.avs
#
# Given a series of time lapse planetoid images, locates those images in frame, crops out and joins them all together into
# a video clip of required Frame Aspect Ratio, 1 FPS, with optional Auto Luma Levelling.
# First scans each image establishing maximum dimensions for whole sequence (after cropping out the planets). Optionally 'grows' those
# dimensions to maintain some of the area around the cropped planets. A 'canvas' size is then established to contain the now maximum
# dimensions and respecting the desired Frame Aspect Ratio, synthetic black borders are added where necessary.
# Borders are the areas added to maintain aspect ratio and can be hi-lited in red. Margins are areas that use the
# original image content instead of synthetic black borders (where possible), they replace synthetic borders, and can be hi-lited
# in green. Margins are the areas between the established crop coords and synthetic borders.
# --------------------------------------
# Args:-
# Filename: Default "*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF". Image Path and wildcard with mulitple pipe separated extensions.
# Baffle: Default 12. Number of scanlines that must break a threshold to be accepted as 'planet'. Avoids noise.
# BlackRange: Default 32. Where background (sky) can vary in luminance by a significant amount.
# Grow_W,Grow_H: Default 128. Size in pixels by which to 'grow' the accumulated maximum dimensions once all planets have been identified.
# FAR: Default 4.0/3.0. Frame Aspect Ratio.
# AutoLevelStrength: Default 0.0. Auto luma leveling, range 0.0 -> 1.0. 0.0 is OFF.
# ShowAutoLevel: Default False. If true then shows Auto leveling on right hande side of image ONLY.
# KeepMargin: Default True. When padding to maintain Frame Aspect Ratio, tries to keep image instead of adding borders.
# ShowMargin: Default False. If True, shows kept margins in Green.
# ShowBorder: Default False. When padding to maintain Frame Aspect Ratio, borders are shown in red.
# Debug: Default False. Show debug info via DebugView. Need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027
#
VERS="PlanetCrop v1.0 - 16 Dec 2012"
FileName= Default(FileName,"*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF")
Baffle=Default(Baffle,12)
BlackRange=Default(BlackRange,32)
Grow_W=Default(Grow_W,128)
Grow_H=Default(Grow_H,128)
FAR=Float(Default(FAR,4.0/3.0))
AutoLevelStrength=Float(Default(AutoLevelStrength,0.0))
ShowAutoLevel=Default(ShowAutoLevel,false)
KeepMargin=Default(KeepMargin,True)
ShowMargin=Default(ShowMargin,False)
ShowBorder=Default(ShowBorder,False)
DEBUG=Default(DEBUG,False)
# Lesser changed stuff Hardcoded
BORDER = (ShowBorder) ? $FF0000 : $000000 # Color for replaced borders.
MARGINBORDER= $00FF00 # Color for KEEP_MARGIN borders.
DEBUG_QLMM = False # Debug QueryLumaMinMax
FPS = 1.0 # Whatever.
WMOD = 1
HMOD = 1
OUT_FILE = "PLANET.List"
Assert(Baffle>0,"Baffle must be 1 or more")
Assert(BlackRange>=0,"BlackRange must be 1 or more")
Assert(Grow_W>=0,"Grow_W Cannot be -ve")
Assert(Grow_H>=0,"Grow_H Cannot be -ve")
Assert(FAR>0.0,"FAR must be greater than 0.0")
Assert(AutoLevelStrength>=0.0 && AutoLevelStrength <= 1.0,"AutoLevelStrength must be 0.0 -> 1.0")
#
GScript("""
Function QPC(clip c,int Baffle) {
c
Thresh=0.04 # 4%, Baffle should remove need to change
w=Width h=height
got = 0 x1 = 0 x2 = w-1 Cnt=0
For(x=0,w-1) {
th=RT_YInRange(0,x=x,y=4,w=1,h=-4,lo=2,hi=255,Matrix=2) # PC levels and skip end 4 pixels (crud around frame edge)
if(got==0) {
if(th > Thresh) {
Cnt=Cnt+1
if(Cnt >= Baffle) {
x1=x-Baffle+1
Cnt=0
got=1
}
} else {
Cnt = 0
}
} else {
if(x2 == w-1 && th <= Thresh) {
Cnt=Cnt+1
if(Cnt >= 2) { # Weak BAFFLE on transition to black
x2=x-2
x=w
}
}
}
}
got=0 y1 = 0 y2 = h-1 Cnt=0
For(y=0,h-1) {
th=RT_YInRange(0,x=4,y=y,w=-4,h=1,lo=2,hi=255,Matrix=2)
if(got==0) {
if(th > Thresh) {
Cnt=Cnt+1
if(Cnt >= Baffle) {
y1=y-Baffle+1
Cnt=0
got=1
}
} else {
Cnt = 0
}
} else {
if(y2 == h-1 && th <= Thresh) {
Cnt=Cnt+1
if(Cnt >= 2) { # Weak BAFFLE on transition to black
y2=y-2
y=h
}
}
}
}
Return "PC_X="+String(x1)+" PC_Y="+String(y1)+" PC_W="+String(x2-x1+1)+" PC_H="+String(y2-y1+1)
}
#
if(DEBUG){ RT_Debug(" ") RT_Debug(VERS,"- By StainlessS") RT_Debug(" ") }
picclip = 0 # Dummy for now
result=RT_WriteFileList(FileName,OUT_FILE) # Create a listing file of Pic files
Assert((result!=0), "No files found")
FILELIST=RT_ReadTxtFromFile(OUT_FILE) # Get list of files
NFILES=RT_TxtQueryLines(FILELIST) # Query Number of lines in String ie number of files.
(DEBUG) ? RT_Debug("Found files = " + String(NFILES)) :NOP
# Prescan to ascertain max wid/hit of all files, also Autocrop & Auto Levels
MAXH=0 MAXW=0 # init max wid and hit
CROPCOORDS="" # Clear results array (string)
AUTOLEVELS="" # Clear AutoLevels array (string)
AUTOLEVEL=(AutoLevelStrength>0.0) # Adjust using Levels.
For(i=0,NFILES-1) {
FN=RT_TxtGetLine(FILELIST,i) # Filename of pic/vid file i
(DEBUG)?RT_Debug(String(i+1)+"/"+String(NFILES)+") Getting File dimensions",FN):NOP
k=ImageReader(FN,end=0).ConvertToRGB32()
OrgW=k.width OrgH=k.height
# For QPC
Grey=k.GreyScale()
MinLum=Grey.RT_YPlaneMin(0,threshold=0.2,Matrix=2)
Grey=Grey.Levels(MinLum+BlackRange,1.0,MinLum+BlackRange+1,0,255,Coring=false)
#
PCS=Grey.QPC(Baffle)
Eval(PCS)
k=k.Crop(PC_X,PC_Y,PC_W,PC_H)
CROPCOORDS=RT_TxtAddStr(CROPCOORDS,PCS)
if (AUTOLEVEL) {
QLMM = k.QueryLumaMinMax(debug=(DEBUG&&DEBUG_QLMM)) # Query luma levels (on cropped clip)
Eval(QLMM) # Set Avisynth vars
AUTOLEVELS=RT_TxtAddStr(AUTOLEVELS,QLMM) # Avisynth Bugfix, same as AUTOLEVELS = AUTOLEVELS + QLMM + Chr(10)
}
If(MAXW<PC_W) {MAXW=PC_W}
If(MAXH<PC_H) {MAXH=PC_H}
if (DEBUG) { # KEEP main debug messages together
RT_Debug ("Orig Width =",String(orgW),"Orig Height =",String(OrgH))
if((PC_W != OrgW) || (PC_H != OrgH)) { # Was Caused by AUTOCROP
RT_Debug("Crop Width =",String(PC_W),"Crop Height =",String(PC_H))
}
RT_Debug("MAX Width So Far =",String(MAXW),"MAX Height So Far =",String(MAXH))
(AUTOLEVEL)? RT_Debug("AutoLevel MinLuma=",String(QLMMMin)," MaxLuma =",String(QLMMMax)) : NOP
RT_Debug(" ----------------------------- ") # line separator
}
}
if(Grow_W>0 || Grow_H > 0) {
(DEBUG)?RT_Debug("Enlarging Max Width,Height to enlarge canvas"):NOP
MAXW=MAXW+Grow_W
MAXH=MAXH+Grow_H
}
maxFAR = Float(MAXW) / MAXH
if(FAR >= maxFAR) {
# Required Frame Aspect Ratio greater or same as maximum accumulated dimensions. Need to pad horizontal
canvasheight = Int((MAXH + (HMOD/2)) / HMOD) * HMOD
canvaswidth = Int((canvasheight * FAR + (WMOD/2)) / WMOD) * WMOD
} else { # Need to pad vertical
canvaswidth = Int((MAXW + (WMOD/2)) / WMOD) * WMOD
canvasheight = Int((canvaswidth / FAR + (HMOD/2)) / HMOD) * HMOD
}
if(DEBUG){
RT_Debug("SETTING CanvasWidth =",String(canvaswidth)," CanvasHeight =",String(canvasheight))
RT_Debug(" ----------------------------- ") # line separator
}
For(i=0,NFILES-1) {
FN=RT_TxtGetLine(FILELIST,i) # Filename of pic/vid file i
if(DEBUG){RT_Debug(string(i+1)+"/"+String(NFILES)+")","Processing File",FN)}
k=ImageReader(FN,end=0).ConvertToRGB32()
OrgW=k.width OrgH=k.height
Eval(RT_TxtGetLine(CROPCOORDS,i))
Left = (canvaswidth-PC_W) / 2 # Borders
Right = canvaswidth-PC_W - Left
Top = (canvasheight-PC_H) / 2
Bot = canvasheight-PC_H-Top
Left2=0 Right2=0 Top2=0 Bot2=0 # Init keep margin borders
if(KeepMargin) {
Left2 = ((PC_X<Left) ? PC_X : Left) / WMOD *WMOD
if(Left2>0) {
Left=Left-Left2
}
Right2 = (((OrgW-PC_X-PC_W)<Right) ? (OrgW-PC_X-PC_W) : Right) / WMOD * WMOD
if(Right2>0) {
Right=Right-Right2
}
Top2 = ((PC_Y<Top) ? PC_Y : Top) / HMOD *HMOD
if(Top2>0) {
Top=Top-Top2
}
Bot2 = (((OrgH-PC_Y-PC_H)<Bot) ? (OrgH-PC_Y-PC_H) : Bot) / HMOD * HMOD
if(Bot2>0) {
Bot=Bot-Bot2
}
if(!ShowMargin) {
PC_X=PC_X-Left2
PC_W=PC_W+Left2+Right2
PC_Y=PC_Y-Top2
PC_H=PC_H+Top2+Bot2
}
}
(DEBUG)? RT_Debug("Crop("+String(PC_X)+","+String(PC_Y)+","+String(PC_W)+","+String(PC_H)+")") : NOP
k=k.Crop(PC_X,PC_Y,PC_W,PC_H)
if (AUTOLEVEL) {
QAT = RT_TxtGetLine(AUTOLEVELS,i)
Eval(QAT)
if(k.IsYUV()) {
CSMin = 16
CSMax = 235
} else {
CSMin = 0
CSMax = 255
}
TMP_K=k
ALMin = Int(CSMin - ((CSMin - QLMMMin) * AutoLevelStrength) + 0.5) # Round Up
ALMax = Int(CSMax - ((CSMax - QLMMMax) * AutoLevelStrength)) # Round down
(DEBUG) ? RT_Debug("Levels("+String(ALMin)+",1.0,"+String(AlMax)+","+String(CSMin)+","+String(CSMax)+",Coring=False)") : NOP
k = k.Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DONT EVER USE Coring
if(ShowAutoLevel) {
tmpw=k.width/4*2
LeftClip = TMP_K.Crop(0,0,tmpw,-0)
RightClip= k.Crop(tmpw,0,-0,-0)
k=StackHorizontal(LeftClip,RightClip)
}
}
if(KeepMargin && ShowMargin) {
(DEBUG) ? RT_Debug("KeepMargin AddBorders("+String(Left2)+","+String(Top2)+","+String(Right2)+","+String(Bot2)+")") : NOP
k = k.Addborders(Left2,Top2,Right2,Bot2,MARGINBORDER)
}
(DEBUG) ? RT_Debug("AddBorders("+String(Left)+","+String(Top)+","+String(Right)+","+String(Bot)+")") : NOP
k = k.Addborders(Left,Top,Right,Bot,BORDER).assumefps(fps)
picclip = (IsClip(picclip)) ? picclip ++ k : k # Append to clip so far
k=k.ConvertToRGB24() # Addborders done (bug in AddBorders rgb24)
if(DEBUG){RT_Debug(" ") RT_Debug(" ----------------------------- ")} # line separator
}
""")
return PicClip
}
Given args are just to demo the border/margin stuff.
Updated PlanetCrop() in RT_Stats zip.
martin53
17th December 2012, 07:54
StainlessS,
:thanks: - How could you know that I just needed RT_BitTST() and RT_BitSET() ! It was exactly what I intended to use to replace some string operations.
RT_FloatAsRGBA() and RT_RGB32AsFloat() seem to work flawless.
I'm sure the hexfunctions will come in handy at least for subtitles.
StainlessS
17th December 2012, 09:39
Thank you for the report. As you probably know, 2.6a3 has bit type operations, however few will use in
general scripts because they are not available in 2.58, the RT_ versions overcome that as available to all.
Also several of the bit ops are not implemented in 2.6 (rotates and bitchg, I think). I did not use identical names to
2.6, I'm more comfortable with the Motorola MC68000 assembler mnemonics for the bit ops.
In QueryBorderCrop, I ended up splitting a flags int into multiple separate bools to be able to test,
bit ops make some things so much easier.
Hope you noticed that I used the RT_YInRange func as suggested by you, in previous post script, would not
have been able to implement that script without it, thank you again. :)
Forensic
27th December 2012, 17:33
StainlessS, this is brilliant. I haven't done much coding since my 6502 days and have yet to develop the skills to write my own DLLs. Implementing your tools just gave me a huge speed improvement over using the internal runtime functions. My next task is extracting Mediainfo using your RT_Call. Thank you.
StainlessS
27th December 2012, 18:04
You're very welcome kind sir. :)
The built in's are clearly faster than RT_stats raster funcs for full frame, but RT is intended for partial frame/scanline/pixel
reading, and are probably faster than repeatedly chopping out individual scanlines/pixels and testing them.
I did a tiny-weeny bit of 6502/6809/8080 in 81 but not much, later did Z80A for about 3/4 years, would hate to do that again.
M68K spoilt me for assy progging and I just hate little endian, did not really know any different when I did Z80.
Will up a new version RT within a few days, with a few additional funcs to those previously posted for v1.07beta.
(By the way, no real problems found in v1.07 beta although I changed some parts a little.)
RT_GetFrame(clip,int "n"=current_frame,int "delta"=0) # Name might change : Changing to RT_YankChain()
Compile/runtime clip function.
n (default = current_frame) frame number.
delta (default = 0), frame number offset.
Process frame (n + delta) of a clip ie forcibly process the filter graph chain for frame n + delta.
Replaces need for eg RT_AverageLuma(n=i,w=1,h=1) to sample a single pixel from frame n to do the same.
RT_NumberString(int ,int "base"=10, int "width"=0)
First arg is an integer to convert to a number base/radix string.
Base, (10, 2 -> 36), is the number base or radix, eg 2 == Binary, 8 == Octal, 10 == Denary/Decimal, 16 == Hexadecimal.
The default of 10 (decimal) will just convert a number to its decimal string equivalent possibly with a '-' minus sign.
All number bases with the exception of decimal, will be unsigned form, ie -1 to hexadecimal will produce "FFFFFFFF",
(the sign is in the digits rather than as separate 'sign and magnitude' used in decimal representation).
Here the digits used for the base, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ". Binary uses first two; decimal, the first 10;
Hexadecimal the first 16; base 36 all 36 digits.
Width, (0, 0 -> 32) is the minimum width of the returned string.
eg RT_NumberString(255,16,4) returns "00FF".
RT_NumberValue(String,int "base"=10)
Returns an int conversion of the supplied number base string.
Base, (10, 2 -> 36) is the number base that the string uses.
Conversion will cease at the first non legal number base digit, without producing an error.
eg RT_NumberValue("1100",2) returns 12 from the binary string.
RT_RGB32AsInt(clip,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0)
Compile/Runtime clip function.
Given an RGB32 clip that had a pixel value created from an Int, gets that pixel and returns as the
original Int. By creating single pixel clips and stacking them horizontally/vertically,
you can use a frame as a two dimensional array of Int, perhaps use the frame number for a third dimension.
Peace Bro :)
EDIT: The built in's are clearly faster than RT_stats raster funcs
As it turns out, actually they are not faster.
StainlessS
27th December 2012, 20:04
@mastrboy,
Could I possibly ask you to delete your post #2 and repost again. I shall then repost my reply to you.
This is so that I can use my post #3 as an extension to the first post.
That might well break some links, but the limit in the Usage forum is 16K (20K I think in Developer),
but the current text description for RT is now at 23kb. Thank you.
(Unless a moderator has an alternative solution)
Happy New Year to one and all, and may your God smile upon you.
Forensic
30th December 2012, 09:55
@StainlessS
DOS BAT file (works great)
set var=test.avi
MediaInfo_CLI\MediaInfo.exe "%CD%\%var%" > %var%.txt
RT_Call in AVS file to get the same output (fails)
a="test.avi"
Cmd="MediaInfo_CLI\MediaInfo.exe "+chr(34)+"%CD%\"+a+chr(34)+" > "+a+".txt"
RT_Call(Cmd,Hide=True)
I can't figure out what I am doing wrong. Any suggestions?
StainlessS
30th December 2012, 11:50
At a guess I'de say that it has no idea where MediaInfo_CLI\ is nor Test.avi,
Try using full path to both. DOS knows where it is, and so can use paths relative to itself,
RT_Call does not have a clue where DOS is/was.
I'll add a debug option to the func, to give a better clue as to what went wrong.
EDIT: I'll give it try myself, and check it out.
StainlessS
2nd January 2013, 04:25
@Forensic, (sorry about the delay in getting back to you)
The main problem in you usage of RT_Call is the mixing of MediaInfo commands and DOS commands.
You are calling MediaInfo and supplying it with %CD% and redirection ">", neither of which means anything to MediaInfo.
This is more like what you want
a="test.avi"
#SetWorkingDir("D:\Whatever")
Dir=_GetWorkingDir()
Cmd_1=QuoteStr(Dir+"MediaInfo_CLI\MediaInfo.exe") + " " + QuoteStr(Dir+a) + " --LogFile=" + QuoteStr(Dir+a+".1.txt")
Cmd_2=QuoteStr("MediaInfo_CLI\MediaInfo.exe") + " " + QuoteStr(a) + " --LogFile=" + QuoteStr(a+".2.txt")
RT_Call(Cmd_1,Hide=true)
RT_Call(Cmd_2,Hide=true)
return colorbars
# _GetWorkingDir(), Get Current Working Directory as used by Avisynth for easy importing of scripts:- By StainlessS
Function _GetWorkingDir(){Try{Import("?\")}Catch(_){s=FindStr(_,Chr(34))_=MidStr(_,s+1,FindStr(_,"?")-s-1)}_}
Function QuoteStr(string s) {return Chr(34)+s+Chr(34)}
Might though be better to give an explicit directory for MediaInfo rather than scriptdir relative.
EDIT: Oops, removed the "debug=true" arg which is not as yet available in public releases.
ALSO NOTE, below previously given MediaInfo usage in RT_Stats doc
Example to write Aspect Ratio in form "1.333" to file D:\OUT\MEDINFO.TXT.
RT_Call("D:\TEST\MediaInfo.Exe" + " --LogFile=" + "D:\OUT\MEDINFO.TXT" + " --Output=Video;%AspectRatio% " + "D:\VID\1.mpg")
I think I got the above from the MediaInfo included doc, but, --Output and %AspectRatio% seem to be deprecated (missing from
MediaInfo built in help) but still work ok.
Below the currently non deprecated usage, (using '--Inform' and '%DisplayAspectRatio%')
RT_Call(QuoteStr("D:\TEST\MediaInfo.Exe") + " --LogFile=" + Quotestr("D:\OUT\MEDINFO.TXT") + \
" --Inform=Video;%DisplayAspectRatio% " + Quotestr("D:\VID\1.mpg"))
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.