Log in

View Full Version : RoboCrop, v1.13 - 07 Feb 2020


Pages : [1] 2 3

StainlessS
12th June 2013, 13:46
RoboCrop v1.13, v2.58, avs/+ v2.60, x86 and x64 dll's.
Requires VS2008 CPP Runtimes.

V1.13 Docs overflow 16kb limit, so left at v1.0 docs below.
See post #37 for v1.13 Docs over two posts. Here: http://forum.doom9.org/showthread.php?p=1696703#post1696703

RoboCrop()

To Protect And Serve - by StainlessS @ Doom9:- http://forum.doom9.org/showthread.php?t=168053

VIDEO: Planar, YUY2, RGB.
AUDIO: No change.

Plugin's for both Avisynth v2.5 and v2.6.

RoboCrop is an automatic cropping solution to crop black borders from video clips, loosely based on (but using no code from)
Autocrop by Glenn Bussell.

For the most part, you can just call it with RoboCrop(clip) and not bother with any other arguements, it is intended to be pretty
much autonomous in its decisions. You might however want to alter eg WMod and HMod if your encoder has special requirements, and
perhaps Laced if your source is likely to be fully progressive.

Borders are detected by sampling at Samples frames, at scanlines (h/v) using AverageLuma (RGB is converted to Luma Y at either TV or
PC levels, See Matrix). This sampling is done on all 4 sides of the frame.
If a scanline Average luma is below or equal to Thresh, then is considered possible black border, above considered possible image,
if Baffle [default=4] adjacent scanlines above Thresh, then it IS image.

Function RoboCrop(clip c,int "Samples"=32,Float "Thresh"=-32,bool "Laced"=true,int "WMod",int "HMod",int "RLBT"=15,bool "Debug"=false, \
float "Ignore"=0.2,int "Matrix"=(c.width<=720?2:3), int "Baffle"=4, bool "ScaleAutoThreshRGB"=true,bool "ScaleAutoThreshYUV"=false, \
int "CropMode"=2,bool "Blank"=false,bool "BlankPC"=false,bool "Align"=false,bool "Show"=false,String "LogFn"="",bool "LogAppend"=false, \
Float "ATM"=4.0)


Args:-

Samples=32, Number of frames to sample from source clip c.
As an observation, most clips have good border recogition within the 1st 2 sampled frames using the default -32.0 AUTOTHRESH
although have noticed some dark clips that required ~8 samples (maybe more) for full recognition @ default Thresh = -32.0
We use a default Samples=32, because we are intrinsically paranoid.
If clip more than 250 frames, will ignore the first 5% and last 10% of frames when both auto-thresholding and crop sampling to
try to negate effects of artificial black in titles and end credits. (Even without this feature, it always skips beginning and end
where possible like this "00100100100" where 1 represents sampled frames when sampling 3 frames from 11).

Thresh: Default= -32.0 (==DEFAULT AUTOTHRESH, any -ve Thresh is AUTOTHRESH where Thresh adjustments are automatic).

Thresh > 0: (Explicit Threshold)
A user supplied +ve Thresh should be at correct TV/PC levels for the the clip being worked on ie 16->235 for TV levels and
0->255 for PC Levels (RGB, as appropriate for matrix being used).

Thresh <= 0: (AUTOTHRESH)
When Thresh <= 0, the clip will be sampled over Samples frames to find the minimum YPlaneMin (using Matrix if RGB) which
we will call MINLUMA and an Explicit Threshold calculated by adding MINLUMA to abs(Thresh), after that it is processed
as for Thresh > 0: (Explicit Threshold) as noted above, but, before adding MINLUMA, some AUTOTHRESH massaging occurs.

Here AUTOTHRESH Thresh massaging occurs in sequence:-
1 ) if (Thresh == DEFAULT AUTOTHRESH && ATM < 32.0) (DEFAULT AUTOTHRESH = -32.0, defaulted OR user supplied):
Let FrameRange = FrameEnd-FrameStart+1 (after skipping titles and end Credits, also Samples limited to FrameRange).
Samples_massage = (Samples>=16) ? 1.0 : (Samples-1) * (1.0/(16-1))
Range_massage =(Float(frmend-frmstart+1)/samples >= 250) ? 1.0 :(Float(frmend-frmstart)/samples * (1.0/(250-1)))
Thresh = -(((Samples_massage * Range_massage) * (32.0 -ATM)) + ATM)
The adjustment to Auto Thresh is to reduce the possibility of overcropping on eg a dark low 'Samples' clip, or where
source FrameRange (ie temporal frame set) is too small to take a reliable sample from.
Resulting massaged Thresh will range between -ATM and -32.0.
Although massaging is intended to reduce overcropping, it could result in not cropping enough border (less disastrous),
its a bit of a balancing act really. See also ATM.
2 ) If RGB AND PC matrix(default) AND ScaleAutoThreshRGB==True(default) then
Thresh= Thresh*(255.0/(235-16))
3 ) If YUV AND ScaleAutoThreshYUV==True(default=false) then
Thresh= Thresh*(255.0/(235-16))

Steps 2) and 3) above, by default treat a -ve AUTOTHRESH as being @ TV Levels and so Scale RGB Thresh to PC levels but not YUV.
If you want to supply a PC levels AUTOTHRESH Thresh for RGB, then simply set ScaleAutoThreshRGB=false to inhibit scaling.
Note, if a TV levels Matrix is supplied for RGB, then scaling will always be inhibited.
If your clip is YUV at PC levels and you want to use eg DEFAULT AUTOTHRESH (-32.0, which is considered to be @ TV levels),
then set ScaleAutoThreshYUV=True to enable Thresh scaling.
If your clip is YUV at PC levels and you want to use a PC levels AUTOTHRESH (-ve) then leave ScaleAutoThreshYUV at default false
which does not scale Thresh.
After any scaling, MINLUMA is then added to abs(Thresh) and processed as for +ve Explicit Threshold as noted above.
NOTE, RoboCrop 'massages' DEFAULT THRESH (exactly -32.0) if low samples count or if short clip. Reason being to avoid
overcropping when insufficient data available for reliable cropping. It is considered better to not crop enough or at all, than
to overcrop. You can override by simply setting an explicit threshold (+ve) of eg 40.0, or setting a NON-DEFAULT auto thresh (-ve)
eg -16.0 or -32.1, where YPlaneMin is established for the sampled frames and then abs(thresh) is added to that value which is
then used as an explicit thresh.

Laced:, Default=true, true for Interlaced.
RoboCrop automatically deduces colorspace cropping restrictions and sets internal XMod and YMod,
eg XMod and YMod would both be set to 2 for YV12, for YUY2 Xmod=2, YMod=1, etc.
If Laced==true, then internal YMod is doubled so as not to destroy chroma.
Below WMod and HMod are both defaulted to internal XMod and YMod respectively after the Laced hint is applied to YMod.

WMod:, Default=The natural chroma cropping restriction of the colorspace concerned, eg 2 for YV12.
HMod:, Default=The natural chroma cropping restriction of the colorspace concerned, BUT, doubled if laced=true.
The above WMod,HMod sets rounding for legal cropping coords for colorspace concerned.
WMod MUST be a multiple of internal XMod as described under Laced above, or it will throw an error.
HMod MUST be a multiple of internal YMod as described under Laced above, or it will throw an error. If eg colorspace is
YV12 then YMod would be set to 2, and if Laced, then YMod would be doubled to 4, so HMod MUST be a multiple of 4.
Some encoders may require an WMod/HMod of eg 8 or 16, and if set thus, would crop off more or less depending upon
which CropMode is set, if later resizing will be done, then encoder requirements can be satisfied during the resize.
NOTE, Some players and VirtualDubMod (Helix YV12 decoder) dont like WMOD less than 4 (Vdub latest, OK, internal decoder).

RLBT:=15=All Borders, Bitflags of edges to crop, 15 ($0F) crops all four. Each letter in the name 'RLBT' represents an edge and bit position
starting with 'R' in bit 3 representing the value 8 (2^3=8). 'L' = bit 2=4 (2^2=4), 'B' = bit 1=2 (2^1=2), 'T' = bit 0=1 (2^0=1).
To calculate the RLBT bitflags, for 'R'(Right) add 8, for 'L'(Left) add 4, for 'B'(Bottom) add 2, and for 'T'(Top) add 1.
Add all of the bit flags together 8+4+2+1 (=15) crops all four edges, 8+4 crops only Right & Left, and 2+1 crops only Bottom & Top.

DEBUG:=False=No Debug. Set True for debugging info, need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027

Ignore:=0.2, Percentage of darkest pixels to ignore during AutoThresh scan to detect minimum luma pixel of all sampled frames.
(ignores noise, as Threshold in YPlaneMin).

Matrix:, RGB ONLY. For conversion of RGB to YUV-Y, 0 = Rec601, 1 = Rec709, 2 = PC601, 3 = PC709
Default for RGB is 2(PC601) if clip width <= 720 else 3(PC709) : YUV not used
The defaults are for PC601 & PC709 range 0-255.
So as to not require different AutoThresh for RGB, if clip c is RGB AND matrix is PC Levels AND Thresh < 0.0 and ScaleAutoThreshRGB=true,
then Thresh will be scaled to RGB full range ie Thresh = Thresh * (255.0/(235.0-16.0)) ONLY when AutoThresh (ie Thresh < 0.0,
YPlaneMin relative).
When +ve Thresh is explicitly supplied (Thresh > 0.0) it is not scaled and assumed to be already correct range TV or PC levels.

Baffle:=4, Number of scanlines (h/v) that must break threshold to be considered image (avoids noise). Does not usually need changing.

ScaleAutoThreshRGB: bool default True. If true and RGB and Matrix at PC levels, and Thresh -ve (autothresh) then thresh will (after any low
samples count scaling) be scaled to PC levels. By default, -ve Auto Thresh is considered to be at TV levels, and so will be scaled to
to PC levels to match the matrix setting. If ScaleAutoThreshRGB is False Then autothresh is considered to be at PC levels and not scaled.

ScaleAutoThreshYUV: bool default False. If true and YUV and Thresh -ve (autothresh) then thresh will (after any low samples count scaling)
be scaled to PC levels. By default, -ve Auto Thresh is considered to be at TV levels, this allows you to change that assumption when
source clips are at PC levels. If supplying PC levels clip and PC levels autothresh then leave this setting at false (no scaling).
The above seemingly awkward settings are due to having to deal with YUV @ TV levels and RGB @ PC levels with the possibility of
YUV @ PC levels.

Cropmode: default=2 == CropMore. 1 = CropLess. Range 1 -> 2.
1 (CropLess) crops a little less border if the exact cropping coords do not comply with XMod/YMod/WMod/HMod as
described earlier. May leave a little border edge.
2 Default, (CropMore) crops a little extra where exact coords do not comply XMod/YMod/WMod/HMod requirements.
You may lose a little of the image edges.

Blank: Default False. If true, then Blanks the borders, ie sets border to RGB(0,0,0) or YUV(16,128,128) instead of cropping.
Is overridden if Show == true.

BlankPC: default false. If Blanking then blanks to YUV(0,128,128) instead of default YUV(16,128,128).

Align: Default false. If true, then aligns frames in memory when cropping, for eg SSE2 16-byte alignment required by some
filters, particularly smoothing filters (filters following after RoboCrop). See Docs for Crop().
Only Applies if Cropping, ie Blank==false AND Show==false.

Show: Default false. If true, then does no cropping, just shows a little info on frame. Overrides both Blank and Align.

LogFn: Default "". Filename of Log file. Will output crop coords eg "10 16 700 544". Crop coords will be output whether
cropping or not (Blank/Show).

LogAppend: Default false. If true then appends log to any existing log file.

ATM: Float default 4.0 (0.5 -> 32.0). Silently limited to valid range.
ATM allows user to set the DEFAULT AUTOTHRESH massaging minimum. When eg samples = 1, then auto thresholding is of course quite
unreliable and so auto thresh would be 'massaged' to -ve(ATM), other values of Samples below 16 will likewise have auto thresh
massaged but to a lesser degree, linearly between -ve(ATM) for Samples == 1 and -ve(32.0) for Samples == 16.
Previous (Fixed) default for ATM was 0.5, for maximum safety so that a single Samples scan would NOT overcrop. The new ATM arg default
of 4.0 is a less paranoid safety setting which should in most cases work well but with a very short clip or eg single image then
user might be better off giving the minimum ATM of 0.5. An ATM of 32.0 will switch OFF default auto thresh massaging.
So long as your clips are about 6 mins or more (and Samples == default 32) then there will be no auto thresh massaging and current
default is unlikely to need changed, with very short clips or reduced Samples count, then you might want to reduce ATM, for maximum
paranoia, set ATM=0.5. See Thresh.


Cropping will likely fail on END CREDITS ONLY clips, where on black background, and will probably crop off the sides that are no
different in average luma to any letterbox borders, if you cannot see the borders, then neither can RoboCrop(), even setting the
auto Thresh to eg -1.0 or 0.0 is quite likely to fail. (See RLBT edge bitflags).

If cropping too much border, then increase Samples or reduce Thresh or lower ATM if short clip.
If not cropping enough border then border is being seen as image, increase Thresh.
To speed up, you may want to leave Auto-Thresh alone and reduce samples, but there is danger that it will not detect all borders (overcrop).
NOTE, The plugin AutoCrop() uses a Thresh of 40.0 and samples == 5 by default (No AutoThresh), but the base logic is not too dissimilar.

Final NOTE, the args to especially note are:- WMod, you might want to supply WMod=4 if using VDubMod (some players might try to download codec),
And Laced=False if you always process progressive or deinterlaced, And ATM set between 0.5 and 4.0 if very short clips/single-image.

StainlessS


Show=true v1.06
https://s20.postimg.cc/vk7jwv799/robo0_zpsfzfpfakr.jpg (https://postimg.cc/image/sq4ejf52x/)
Show=true v1.10+
https://s20.postimg.cc/b7qcuw2gt/cab2_zpsjgrrflzt.png (https://postimg.cc/image/vf3sn6zy1/)
Bottom image above: Left edge, single dots line, other edges a bit wiggly ie cropping moved inwards [CROPMORE] to adhere to X/Y/W/H Mod requirements.

See Mediafire in sig.

mastrboy
12th June 2013, 15:40
very interesting plugin.
I usually use applyrange to fix cropping in sources when it's not a static value, like:
ApplyRange(25760,26183,"c_bottom")
ApplyRange(26220,27286,"c_bottom")
ApplyRange(27394,27605,"c_bottom")
ApplyRange(27702,28529,"c_top")

function c_top (clip c) {
c
return crop(0,2,0,0).Spline36Resize(width,height)
}

function c_bottom (clip c) {
c
return crop(0,0,0,-4).Spline36Resize(width,height)
}

function c_top_right (clip c) {
c
return crop(0,2,-4,0).Spline36Resize(width,height)
}

function c_right (clip c) {
c
return crop(0,0,-4,0).Spline36Resize(width,height)
}


Could this plugin replace that tedious work?
And if yes, is there a way to log in a file all the frames/ranges which where cropped by RoboCrop?

StainlessS
12th June 2013, 16:16
Sorry Mastrboy, No.

RoboCrop is a sort of drop in replacement for AutoCrop. Where croppings differ, will pick the outermost cropping (EDIT: that it finds, by default it only samples 24 frames).

I did do a little script using GScript and RT_Stats a few months back to fix dynamically changing borders on some anime.
I got it working to do the job, but would not say it was complete (I got sick of it, especially as I have zero interest in cartoons).
Perhaps you can make use of parts of it, search on "BorderTorture", I think you should get a hit on that (it was a test clip generator,
cant remember what I called the actual cropping func).
EDIT: See Here:- http://forum.doom9.org/showthread.php?t=167531&highlight=bordertorture

As I remember, it produced a file of crop coords and a sister fuinc, read them in and did the cropping.

EDIT: It might make an interesting little project though, I'll have to think about that for a little while.
The previously mentioned anime was interlaced, you got same prob ?
I dont really have any source like that, that I can think of, except for one, and that one has scene blends
which cause additional problems. hard to tell where the scene change is and where to alter cropping, also, that source
is a tube flv file so lousy quality to begin with.

creaothceann
12th June 2013, 19:34
This looks very useful! :)

Definitely going to come in handy with my anime.

mastrboy
13th June 2013, 15:49
Sorry Mastrboy, No.
The previously mentioned anime was interlaced, you got same prob?


It's related to anime indeed, but not specifically interlaced anime, I have noticed it on different anime's usually created around 2000-2003. Usually it's only about 2-4px borders, so not very noticeable. But when noticed, you can't "un-notice" it :P

StainlessS
13th June 2013, 23:37
This world is plagued by perfectionists.

I personally miss the days when you could accuse someone of being witch, and next day you could burn them.
Good times.

EDIT: I'll see what I can do with a plugin to generate list of crops.

mastrboy
14th June 2013, 18:22
Indeed, I blame this forum for making me into one, a perfectionist that is :P .
If such a plugin arises, just let me know. I would be happy to test it out.

StainlessS
14th June 2013, 20:56
From the link previously given, perhaps of some use. Just need to give clip trims, will auto crop and resize.

EDIT:- SCRIPT REMOVED, See Next post.

Perhaps use ConvertToYV24() beforehand.

StainlessS
17th June 2013, 01:48
Mastrboy,

Perhaps handy for Dynamic cropping of Progressive stuff.

Script removed, see posts #14 to #16

StainlessS
17th June 2013, 18:36
Previous post script updated.

StainlessS
18th June 2013, 04:42
RoboCrop v0.10, update. see 1st post.

Small mod for Auto Thresh Massaging


Here AUTOTHRESH Thresh massaging occurs in sequence:-
1 ) if Thresh == DEFAULT AUTOTHRESH (-32.0, defaulted OR user supplied):
Let FrameRange = FrameEnd-FrameStart+1 (after skipping titles and end Credits, also Samples limited to FrameRange).
Samples_massage = (Samples>=12) ? 1.0 : (Samples-1) * (1.0/(12-1))
Range_massage = (FrameRange >= 1000) ? 1.0 : (FrameRange-1) * (1.0/(1000-1))
Thresh = -(((Samples_massage * Range_massage) * 31.5) + 0.5)
The adjustment to Auto Thresh is to reduce the possibility of overcropping on eg a dark low 'Samples' clip, or where
source FrameRange (ie temporal frame set) is too small to take a reliable sample from.
Resulting massaged Thresh will range between -0.5 and -32.0.
Although massaging is intended to reduce overcropping, it could result in not cropping enough border (less disastrous),
its a bit of a balancing act really.
2 ) If RGB AND PC matrix(default) AND ScaleAutoThreshRGB==True(default) then
Thresh= Thresh*(255.0/(235-16))
3 ) If YUV AND ScaleAutoThreshYUV==True(default=false) then
Thresh= Thresh*(255.0/(235-16))


Blue text describes (badly) the mod, Much safer now in eg DynaCrop script in earlier post.
On synthetic BorderTorture created clip, source had several 18 frame scenes which did not
previously crop well, now crops spot on. clip was a sort of photo shoot with black backdrops
which made it difficult to find cropping on an 18 frame scene. Also, scene change in DynaCrop
script does not get fooled by single white frame flash photography (was already flash proof).

Really happy how it is performing. :)

Now I would like to know how DynaCrop (and by extension RoboCrop) performs on non synthetic dynamic borders.

EDIT: Mastrboy, I'll add a crop log to DynaCrop(), perhaps in form

"Trim(s,e).Crop(x,y,-w,-h)"

or maybe

"Vnnn=Trim(s,e).Crop(x,y,-w,-h)"

Or other, Any preference ?

mastrboy
18th June 2013, 21:54
A lot happened in this thread when I wasn't looking. :)

Only preference I have is that it logs by ranges, and not single frames, unless of course there is a single frame which needs cropping.

Now I only have to find those sources which had these issues and test...

StainlessS
19th June 2013, 09:09
Change of mind, Ill implement user configured log, something like


"V_NNN_=Trim(_S_,_E_).Crop(_X_,_Y_,_-W_,_-H_)"

or

"V_NNN_=Trim(_S_,_E_).Crop(_X_,_Y_,_W_,_H_)"


where '_z_' replaced by numbers.

StainlessS
19th June 2013, 16:46
Update to RoboCrop v0.20 see first post.

Added args, BlankPC, LogFn, LogAppend.

Changed, range massage switch on frames to below 1500 (from 1000).

Range_massage = (FrameRange >= 1500) ? 1.0 : (FrameRange-1) * (1.0/(1500-1))


Split post as overflows 16kb limit

MakeBorderTortureClip.avs

# MakeBorderTortureClip.avs

Function MakeBorderTortureClip(clip c,String "fn") {
# TESTING ONLY
# Make a torture test clip using trims file made by SC_MakeTrimFile() {MUST USE SAME SOURCE FILE AS SC_MakeTrimFile}.
# Use resulting clip as input to DynaCrop().
# Input clip should have plenty of scene changes WITHOUT Blended Scene Transitions.
# Edges will be cropped and synthetic borders added to original size.
# Requires RT_Stats v1.18 for RT_ColorSpaceXMod/YMod.
c
myName="MakeBorderTortureClip: "
fn=Default(fn,"TrimFile.Txt") # input filename
Assert(Exist(fn),myName+"File Not Found "+fn)
c2=0 oldcx=0 oldcy=0 oldcw=0 oldch=0
XMod=RT_ColorSpaceXMod() YMod=RT_ColorSpaceYMod(Laced=false) MX=32/XMod MY=32/YMod
GSCript("""
Lines=RT_FileQueryLines(fn) # Total lines in text file
SS=RT_ReadTxtFromFile(fn) # Complete text file of trims.
For(n=0,Lines-1) {
S=RT_TxtGetLine(SS,Line=n) # Get the trim line
S=RT_StrReplace(S,Chr(9)," ") # Convert any TAB to SPACE
S=Lcase(RT_StrReplaceDeep(S," "," ")) # Convert Multiple SPACE to single SPACE
Start=RT_NumberValue(S) # trim start
S=MidStr(S,FindStr(S," ")+1)
End=RT_NumberValue(S) # trim end
t=Trim(Start,End)
b=true
while(b || (cx==oldcx && cy==oldcy && cw==oldcw && ch==oldch)) { # Make sure some change at every trim
cx=Rand(MX+1)*XMod cy=Rand(MY+1)*YMOD cw=Rand(MX+1)*XMod ch=Rand(MY+1)*YMod
b=false
}
t=t.Crop(cx,cy,-cw,-ch).AddBorders(cx,cy,cw,ch) # create fake borders
c2 = (c2.isClip) ? c2++t : t
old_cx=cx oldcy=cy oldcw=cw oldch=ch # REM for next time
}
""")
return c2
}


MakeBorderTortureClip_Client.avs

# MakeBorderTortureClip_Client.avs

Import("DynaCrop.avs")
Import("MakeBorderTortureClip.avs")

AVISource("D:\AVS\TEST.avi") # TESTING ONLY ON GOOD CLIP WITHOUT BORDERS and NO blended Scene transitions.

#ConvertToYV24() # v2.6 optional, MOD 1 Torture clip and cropping

Return SC_ShowMetrics() # Show metrics to get best Threshold 'th'.
#Return SC_MakeTrimFile() # Make Trims file for MakeBorderTortureClip/DynaCrop, Must Play all way through.

### MUST use SC_MakeTrimFile() to make trims file BEFORE below used.

CROPTHRESH = -32.0 # AUTOMATIC Thresholding, See RoboCrop.
SHOW=True

#Return MakeBorderTortureClip().DynaCrop(CropThresh=CROPTHRESH,show=SHOW).ConvertToYV12() # Show croppings

#MakeBorderTortureClip() # MAKE A SOURCE TORTURE CLIP for DynaCrop_Client test
#ConvertToYV12()

StainlessS
19th June 2013, 16:47
Also see previous post, RoboCrop Update.

DynaCrop.AVS

######################
# DynaCrop.AVS v1.01 - Script, by StainlessS.
# Crop dynamically changing borders from PROGRESSIVE clip. Requires GScript, Grunt, RT_Stats v1.18, RoboCrop v0.20.
# Will NOT Work well with blended scene transitions.
######################

Function SC_ShowMetrics(clip c,float "th",float "th2",int "x",int "y",int "w",int "h",bool "fast") {
# For Setting th (and less often th2) for SC_MakeTrimFile().
# Above th is Scene Change (Curr->Next).
# th2 governs NOT SCENE CHANGE decisions Prev->Curr and Next->(Next+1). Should be less than th. Default 0.8 * th.
# x,y,w,h sets border to ignore crud.
# Metric used sort of like:- mt_lutxy(mt_polish("((x-y)/4)^2")).AverageLuma()
c
th=Float(Default(th,80.0)) # About 80.0 seems good for fast/slow motion
th2=Float(Default(th2,0.8*th)) # Default th2 set 0.8 * th
x=default(x,16) y=default(y,16) w=default(w,-16) h=default(h,-16) # avoid crud
Fast=Default(Fast,True)
Global SCM_B=0.0 Global SCM_C=0.0 Global SCM_sc=False Global SCM_Prev=-2 # Init vars, SCM_Prev=-2 forces initalize
ScriptClip("""
# If jumped about, get values for Previous frame, else keep same.
NotNext = (current_frame!=SCM_Prev+1)
Global SCM_A=(NotNext)? RT_LumaSceneChange(Last,Last,n=current_frame-2,n2=current_frame-1,x=x,y=y,w=w,h=h) : SCM_A
Global SCM_B=(NotNext)? RT_LumaSceneChange(Last,Last,n=current_frame-1,n2=current_frame ,x=x,y=y,w=w,h=h) : SCM_B
Global SCM_C=(NotNext)? RT_LumaSceneChange(Last,Last,n=current_frame, n2=current_frame+1,x=x,y=y,w=w,h=h) : SCM_C
psc=(NotNext) ? (SCM_A<th2 && SCM_B>=th && SCM_C<th2) : SCM_SC
# Pass the parcel
Global SCM_A=SCM_B
Global SCM_B=SCM_C
Global SCM_C=RT_LumaSceneChange(Last,Last,n=current_frame+1,n2=current_frame+2,x=x,y=y,w=w,h=h) # diff(next,next+1)
# Prev->Curr NOT Scene Change AND Curr->Next IS Scene Change AND Next->(Next+1) NOT Scene Change
Global SCM_SC=((SCM_A<th2 && SCM_B>=th && SCM_C<th2) || current_frame==FrameCount()-1) # Last frame in scene ?
Subtitle(String(current_frame)+"] "+String(SCM_A,"%6.2f")+" "+String(SCM_B,"%6.2f")+" "+String(SCM_C,"%6.2f")+\
"\nTh="+String(th,"%.1f")+" Th2="+String(th2,"%.1f"),lsp=0)
(SCM_SC) ? Subtitle("END OF SCENE", align=1,size=30) : NOP
(psc||current_frame==0) ? Subtitle("START OF SCENE",align=3,size=30) : NOP # 1st frame in scene, Previous was Last frame in scene
Global SCM_Prev=current_frame
Return Last
""",args="th,th2,x,y,w,h") # Needs Grunt for args
return ((Fast)?AssumeFPS(250.0):Last).KillAudio()
}


Function SC_MakeTrimFile(clip c,float "th",float "th2",int "x",int "y",int "w",int "h",bool "fast",String "Fn") {
# Must play all way through, no jumping about. Set th using SC_ShowMetrics()
# Creates output file, list of trims for DynaCrop() {ALSO for MakeBorderTortureClip() to create a TEST clip}
# Above th is Scene Change (Curr->Next).
# th2 governs NOT SCENE CHANGE decisions Prev->Curr and Next->(Next+1). Should be less than th. Default 0.8 * th.
# x,y,w,h sets border to ignore crud.
# Metric used sort of like:- mt_lutxy(mt_polish("((x-y)/4)^2")).AverageLuma()
c
myName="SC_MakeTrimFile: "
th=Float(Default(th,80.0)) # About 80.0 seems good for fast/slow motion
th2=Float(Default(th2,0.8*th)) # Default th2 set 0.8 * th
x=default(x,16) y=default(y,16) w=default(w,-16) h=default(h,-16) # avoid crud
Fast=Default(Fast,True)
Fn=Default(Fn,"TrimFile.Txt")
(Exist(Fn)) ? RT_FileDelete(Fn) : NOP # Delete existing
Global SCM_B=0.0 Global SCM_C=0.0 Global SCM_Prev=-1 Global SCM_Start=0 Global SCM_NotNext=false # Init vars
ScriptClip("""
Global SCM_NotNext = (current_frame!=SCM_Prev+1 || SCM_NotNext) # Lock NotNext global if error
(SCM_NotNext && Exist(Fn)) ? RT_FileDelete(Fn) : NOP # Spank user for jumping about :)
Assert(SCM_NotNext==false,myName+"Cannot seek whilst making trims file "+fn) # Message on frame ONLY, no abort
# Pass the parcel
Global SCM_A=SCM_B
Global SCM_B=SCM_C
Global SCM_C=RT_LumaSceneChange(Last,Last,n=current_frame+1,n2=current_frame+2,x=x,y=y,w=w,h=h)
# Prev->Curr NOT Scene Change AND Curr->Next IS Scene Change AND Next->(Next+1) NOT Scene Change
SC=((SCM_A<th2 && SCM_B>=th && SCM_C<th2) || current_frame==FrameCount()-1)
(SC && !SCM_NotNext) ? RT_TxtWriteFile(String(SCM_Start)+" "+String(current_frame),Fn,append=True) : NOP
Global SCM_Start = (SC) ? current_frame + 1 : SCM_Start
Global SCM_Prev=current_frame
Return Last
""",args="th,th2,x,y,w,h,fn,myName") # Needs Grunt for args
return ((Fast)?AssumeFPS(250.0):Last).KillAudio()
}


Function DynaCrop(clip c,String "fn",int "W",int "H",String "Resizer",Float "CropThresh",bool "Show",String "LogFn",String "LogTMPT",bool "Debug") {
# Auto crop list of trims in filename 'fn' and resize to WxH using 'Resizer' <Default = "Spline64Resize(_W_,_H_)">
# CropThresh is RoboCrop thresh. Show is RoboCrop Show.
# LogFn default "DynaCrop.log". User configurable output log file name.
# LogTMPT Log Template, Default="V_NNNN_ = Trim(_S_,_E_).Crop(_CX_,_CY_,_-CW_,_-CH_)._RSZ_"+(9)+Chr(9)+"# Crop_W= _CW_ Crop_H= _CH_"
# Default produces eg "V0000 = Trim(0,215).Crop(2,4,-14,-6).Spline64Resize(640,400) # Crop_W= 624 Crop_H= 390"
# Requires RoboCrop v0.20 for RoboCrop output LogFile, to get crop coords.
#########################################
# Log TEMPLATE Replacements
# "_NNNN_" = trim number, 0 relative
# "_S_" = Start frame Number, "_E_" = End frame number
# "_CX_", "_CY_", "_CW_","_CH_", Crop x,y,w,h, "_-CW_" and "_-CH_" are -ve crop width and height relative
# "_IW_", "_IH_" = Input clip width and height.
# "_W_", "_H_" = Resize width and height.
# "_RSZ_" = The resizer, defaulted or otherwise.
#########################################
c
myName="DynaCrop:"
c2 = 0
fn=Default(fn,"TrimFile.Txt") # input filename
_W_=Default(W,width) _H_=Default(H,height)
Resizer=Default(Resizer,"Spline64Resize(_W_,_H_)") # Resizer to use
TResizer="t."+Resizer
LogTMPT=Default(LogTMPT,"V_NNNN_ = Trim(_S_,_E_).Crop(_CX_,_CY_,_-CW_,_-CH_)._RSZ_"+Chr(9)+Chr(9)+"# Crop_W= _CW_ Crop_H= _CH_" )
LogFn=Default(LogFn,"DynaCrop.log")
Debug=Default(Debug,false)
Assert(Exist(fn),myName+" File Not Found "+fn)
(Exist(LogFn)) ? RT_FileDelete(LogFn) : NOP # Delete existing Log
Lines=RT_FileQueryLines(fn) # Total lines in text file
SS=RT_ReadTxtFromFile(fn) # Read complete text file into string
EOL=Chr(10)
FND="_RSZ_"+EOL+"_NNNN_"+EOL+"_S_"+EOL+"_E_"+EOL+"_CX_"+EOL+"_CY_"+EOL+"_CW_"+EOL+"_CH_"+EOL+"_-CW_"+EOL+"_-CH_"+EOL+"_W_"+EOL+
\ "_H_"+EOL+"_IW_"+EOL+"_IH_"+EOL
TmpLog="DynaCropTmp~.log"
(Exist(TmpLog)) ? RT_FileDelete(TmpLog) : NOP # Delete existing TmpLog
GSCript("""
for(n=0,Lines-1) {
S=RT_TxtGetLine(SS,Line=n) # Get the trim line
S=RT_StrReplace(S,Chr(9)," ") # Convert any TAB to SPACE
S=Lcase(RT_StrReplaceDeep(S," "," ")) # Convert Multiple SPACE to single SPACE
Start=RT_NumberValue(S)
S=MidStr(S,FindStr(S," ")+1)
End=RT_NumberValue(S)
t=Trim(Start,End) # Get current trim
t=t.RoboCrop(thresh=CROPTHRESH,laced=False,show=Show,debug=Debug,LogFn=TmpLog,LogAppend=false)
if(LogFn!="" && Exist(TmpLog)) {
ts= RT_ReadTxtFromFile(TmpLog)
Crop_x=RT_NumberValue(ts)
ts=MidStr(ts,FindStr(ts," ")+1)
Crop_y=RT_NumberValue(ts)
ts=MidStr(ts,FindStr(ts," ")+1)
Crop_w=RT_NumberValue(ts)
ts=MidStr(ts,FindStr(ts," ")+1)
Crop_h=RT_NumberValue(ts)
REP =
\ Resizer + EOL +
\ RT_NumberString(n,width=4) + EOL +
\ RT_NumberString(Start) + EOL +
\ RT_NumberString(End) + EOL +
\ RT_NumberString(crop_x) + EOL +
\ RT_NumberString(crop_y) + EOL +
\ RT_NumberString(crop_w) + EOL +
\ RT_NumberString(crop_h) + EOL +
\ RT_NumberString(crop_w -(Width - crop_x)) + EOL +
\ RT_NumberString(crop_h -(Height - crop_y)) + EOL +
\ RT_NumberString(_W_) + EOL +
\ RT_NumberString(_H_) + EOL +
\ RT_NumberString(Width) + EOL +
\ RT_NumberString(Height) + EOL
LOG=RT_StrReplaceMulti(LogTMPT,FND,REP)
RT_TxtWriteFile(LOG,LogFn,append=True)
}
t=Eval(TResizer) # Resize using optional resizer
c2 = (c2.isClip) ? c2++t : t # Splice
}
(Exist(TmpLog)) ? RT_FileDelete(TmpLog) : NOP # Delete temp Log
""")
return c2
}



DynaCrop_Client.avs

# DynaCrop_Client.avs

Import("DynaCrop.avs")

#AVISource("D:\AVS\TEST.avi")
AVISource("D:\AVS\BORDERTORTURE.avi") # Pre-Prepared TORTURE test clip

#ConvertToYV24() # Optional v2.6, MOD 1 crop coords

Return SC_ShowMetrics().ConvertToYV12() # Show metrics to get best Threshold 'th', use bofore SC_MakeTrimFile().
#Return SC_MakeTrimFile().ConvertToYV12() # Make Trims file for DynaCrop(), Must Play all way through.

### MUST use SC_MakeTrimFile() to make trims file BEFORE below used.

CROPTHRESH = -32.0 # AUTOMATIC Thresholding, See RoboCrop.
SHOW=True # SHOW WHAT WHAT WILL BE CROPPED
DEBUG=False # RoboCrop Debug

#Return DynaCrop(CropThresh=CROPTHRESH,show=SHOW,debug=DEBUG).ConvertToYV12()



DynaSplice.avs

# DynaSplice.avs # Joins trims file generated as DEFAULT DynaCrop logfile.

Function SpliceTrimsString(String VideoString,int maxim,int "Wid") {
Wid=Default(Wid,4)
GSCript("""
S=""
for(i =0,maxim) {
if(S!="") {
S=RT_StrAddStr(S,"++")
}
S=RT_StrAddStr(S,VideoString,RT_NumberString(i,width=wid)) # RT_StrAddStr, Avoid v2.58 bug
}
""")
return S
}

AVISource("D:\AVS\BORDERTORTURE.avi") # Pre-Prepared TORTURE test clip

#ConvertToYV24() # v2.6 optional, Mod 1 Cropping

TRIMSFILE="Dynacrop.log" # Created by DynaCrop default logging.

TRIMS=RT_ReadTxtFromFile(TRIMSFILE) # Or Import()
Lines=RT_TxtQueryLines(TRIMS) # Total lines in text file (Or RT_FileQueryLines)
SPLICE=SpliceTrimsString("V",Lines-1) # Zero Relative
Eval(TRIMS) # Eval trims,crop,resize
Eval(SPLICE) # Splice trims

ConvertToYV12()

StainlessS
19th June 2013, 16:51
Split post due to 16kb limit. See two previous posts.


Trims file Generated by SC_MakeTrimFile()

0 215
216 233
234 334
335 442
443 520
521 637
638 711
712 798
799 816
817 843
844 1018
1019 1131
1132 1298
1299 1329
1330 1450
1451 1569
1570 1744
1745 1856
1857 1917
1918 2010
2011 2055
2056 2118
2119 2236
2237 2392
2393 2473
2474 2723
2724 3410
3411 3505
3506 3608
3609 3684
3685 3769
3770 4143
4144 4212
4213 4685
4686 5202
5203 5449
5450 5791
5792 5822


Default Logfile Generated by DynaCrop() {User configurable}

V0000 = Trim(0,215).Crop(8,20,-31,-1).Spline64Resize(640,400) # Crop_W= 601 Crop_H= 379
V0001 = Trim(216,233).Crop(29,16,-27,-21).Spline64Resize(640,400) # Crop_W= 584 Crop_H= 363
V0002 = Trim(234,334).Crop(1,11,-29,-29).Spline64Resize(640,400) # Crop_W= 610 Crop_H= 360
V0003 = Trim(335,442).Crop(16,30,-28,-29).Spline64Resize(640,400) # Crop_W= 596 Crop_H= 341
V0004 = Trim(443,520).Crop(25,29,-9,-24).Spline64Resize(640,400) # Crop_W= 606 Crop_H= 347
V0005 = Trim(521,637).Crop(18,18,-8,-21).Spline64Resize(640,400) # Crop_W= 614 Crop_H= 361
V0006 = Trim(638,711).Crop(28,7,-30,-5).Spline64Resize(640,400) # Crop_W= 582 Crop_H= 388
V0007 = Trim(712,798).Crop(17,29,-2,-12).Spline64Resize(640,400) # Crop_W= 621 Crop_H= 359
V0008 = Trim(799,816).Crop(20,21,-21,-13).Spline64Resize(640,400) # Crop_W= 599 Crop_H= 366
V0009 = Trim(817,843).Crop(26,31,-7,-27).Spline64Resize(640,400) # Crop_W= 607 Crop_H= 342
V0010 = Trim(844,1018).Crop(26,18,-5,-6).Spline64Resize(640,400) # Crop_W= 609 Crop_H= 376
V0011 = Trim(1019,1131).Crop(18,11,-27,-22).Spline64Resize(640,400) # Crop_W= 595 Crop_H= 367
V0012 = Trim(1132,1298).Crop(5,4,-5,-23).Spline64Resize(640,400) # Crop_W= 630 Crop_H= 373
V0013 = Trim(1299,1329).Crop(25,21,-6,-22).Spline64Resize(640,400) # Crop_W= 609 Crop_H= 357
V0014 = Trim(1330,1450).Crop(11,6,-7,-19).Spline64Resize(640,400) # Crop_W= 622 Crop_H= 375
V0015 = Trim(1451,1569).Crop(7,32,-14,-27).Spline64Resize(640,400) # Crop_W= 619 Crop_H= 341
V0016 = Trim(1570,1744).Crop(24,10,-31,-32).Spline64Resize(640,400) # Crop_W= 585 Crop_H= 358
V0017 = Trim(1745,1856).Crop(25,10,-23,-12).Spline64Resize(640,400) # Crop_W= 592 Crop_H= 378
V0018 = Trim(1857,1917).Crop(17,30,-16,-5).Spline64Resize(640,400) # Crop_W= 607 Crop_H= 365
V0019 = Trim(1918,2010).Crop(24,15,-6,-17).Spline64Resize(640,400) # Crop_W= 610 Crop_H= 368
V0020 = Trim(2011,2055).Crop(27,17,-27,-22).Spline64Resize(640,400) # Crop_W= 586 Crop_H= 361
V0021 = Trim(2056,2118).Crop(12,26,-16,-17).Spline64Resize(640,400) # Crop_W= 612 Crop_H= 357
V0022 = Trim(2119,2236).Crop(5,7,-15,0).Spline64Resize(640,400) # Crop_W= 620 Crop_H= 393
V0023 = Trim(2237,2392).Crop(8,4,-26,-22).Spline64Resize(640,400) # Crop_W= 606 Crop_H= 374
V0024 = Trim(2393,2473).Crop(14,3,-27,-8).Spline64Resize(640,400) # Crop_W= 599 Crop_H= 389
V0025 = Trim(2474,2723).Crop(15,29,-19,-24).Spline64Resize(640,400) # Crop_W= 606 Crop_H= 347
V0026 = Trim(2724,3410).Crop(0,30,-18,-29).Spline64Resize(640,400) # Crop_W= 622 Crop_H= 341
V0027 = Trim(3411,3505).Crop(26,12,-5,-2).Spline64Resize(640,400) # Crop_W= 609 Crop_H= 386
V0028 = Trim(3506,3608).Crop(29,31,0,-21).Spline64Resize(640,400) # Crop_W= 611 Crop_H= 348
V0029 = Trim(3609,3684).Crop(14,30,-15,-12).Spline64Resize(640,400) # Crop_W= 611 Crop_H= 358
V0030 = Trim(3685,3769).Crop(28,24,-20,-24).Spline64Resize(640,400) # Crop_W= 592 Crop_H= 352
V0031 = Trim(3770,4143).Crop(14,17,-27,-31).Spline64Resize(640,400) # Crop_W= 599 Crop_H= 352
V0032 = Trim(4144,4212).Crop(5,7,-26,-28).Spline64Resize(640,400) # Crop_W= 609 Crop_H= 365
V0033 = Trim(4213,4685).Crop(12,10,-7,-31).Spline64Resize(640,400) # Crop_W= 621 Crop_H= 359
V0034 = Trim(4686,5202).Crop(21,29,-22,-18).Spline64Resize(640,400) # Crop_W= 597 Crop_H= 353
V0035 = Trim(5203,5449).Crop(13,11,0,-21).Spline64Resize(640,400) # Crop_W= 627 Crop_H= 368
V0036 = Trim(5450,5791).Crop(29,32,-1,-23).Spline64Resize(640,400) # Crop_W= 610 Crop_H= 345
V0037 = Trim(5792,5822).Crop(32,9,-20,-31).Spline64Resize(640,400) # Crop_W= 588 Crop_H= 360


EDIT:
Only preference I have is that it logs by ranges

Trims file generated by SC_MakeTrimFile() produces 1st file above.

EDIT: Found a fairly popular DVD that SC_MakeTrimFile fails on quite badly, X-Men II.
The lady in the blue rubber naked suit (forgot her name), has different cropping whenever she is on screen,
so I thought I would try the Dynacrop thing, and SC_MakeTrimFile is way off recognizing many scene changes.
Some scene changes require a th of about 16.0 (default 80.0) so is a long way off. Going to have to add chroma
to scene change detection or figure out a better way of doing it.

StainlessS
21st June 2013, 18:34
Here, just an experiment to see if we understood how SCSelect works.

Avisource("D:\avs\test.avi")

# RemoveDirt's SCSelect(clip input, clip scene_begin, clip scene_end, clip global_motion, float dfactor, bool debug, bool planar)

Function SCSelect_Like(clip dclip,clip Start,clip End,clip Motion, float "dfactor",bool "debug") {
# Start, End, Motion MUST all be same, dclip can be other colorspace/size (unlike SCSelect).
dfactor=Float(Default(dfactor,4.0))
debug=Default(debug,false)
Global SCM_A=0.0 Global SCM_B=0.0 Global SCM_SC=0 Global SCM_Prev=-1
Motion.ScriptClip("""
NotNext = (current_frame!=SCM_Prev+1)
Global SCM_A=(NotNext)? RT_LumaDifference(dclip,dclip,n=current_frame-1,n2=current_frame) : SCM_B
Global SCM_B= RT_LumaDifference(dclip,dclip,n=current_frame,n2=current_frame+1)
# 0 = Start of scene, 1 = End of scene, 2 = Global motion
Global SCM_SC=(current_frame==FrameCount-1)?1:(SCM_A>dfactor*SCM_B || current_frame==0)?0:(SCM_B>dfactor*SCM_A)?1:2
(SCM_SC==0) ? Start : (SCM_SC==1) ? End : Last # Choose Start, End or Motion(ie Last)
(debug)?RT_Subtitle("%d ] %6.2f %6.2f SC=%d",current_frame,SCM_A,SCM_B,SCM_SC):NOP
Global SCM_Prev=current_frame
Return Last
""",args="dfactor,Start,End,Dclip,debug") # Needs Grunt for args
return Last
}

Start=Subtitle("START OF SCENE",align=3,size=30)
End=Subtitle("END OF SCENE", align=1,size=30)
Motion=Subtitle("GLOBAL MOTION",align=5,size=30)
L=SCSelect_Like(Last,Start,End,Motion,debug=true)
R=SCSelect(Last,Start,End,Motion)
StackHorizontal(L,R)

EDITED:

EDIT: It's not what I could call reliable, unmatched start/end scene, completely messes up on flash photography.
I'm quite surprised that people use SCSelect at all.

StainlessS
10th July 2013, 22:54
RoboCrop v0.21, Update, see 1st post.

Changed default samples to 32, modified Thresh Massaging, generally a bit more paranoia.

StainlessS
11th September 2013, 00:04
RoboCrop v1.00, beta status removed (Atm arg added). See 1st post.

EDIT: current RT_Stats zip contains updates to previous given scripts eg DynaCrop.avs.

FredThompson
23rd November 2013, 18:45
Mediafire link is a 404. Did you intend to have an updated script set there?

I am looking for a way to autocrop frames such as the attached screenshot. Preferred method would be a scan of an entire file with the minimal crop values returned. Seems the entire stream should be checked due to the variable cropping mentioned above. Results will be used to generate encoder scripts with video bitrate a function of post-cropped frame-size. My hope is to use RoboCrop in a pre-scan to generate crop values for each file in the queue, preserving field order and block sizes so crap and frame would be the result. Output from RoboCrop would probably go into a file with a format similar to:

filename
cropx1
cropx2
cropy1
cropy2
framewidth
frameheight

or something similar which can be easily parsed by a batch file. End result of my process will be a job queue of various frame sizes, rates and source codecs which can be loaded into Hybrid encoding GUI for a "encode all in directory to a target quality/size" process.

Another example of this type of unwanted junk is at:

http://forum.doom9.org/showthread.php?p=1651430#post1651430

Notice how close the noise is to the desired video data. Perhaps a grayscale vs. chroma determination would help.

I assume this is extra junk that DirecTV uses for the guide data or extra information for a show, maybe it's the bitmap for the recorded show.

Background to this project is at:

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

StainlessS
23rd November 2013, 19:07
Sorry Fred, MediaFire problem, hopefully just temporary but till fixed try here: LINK REMOVED

StainlessS
23rd November 2013, 19:11
Sorry, even that one seems to have a problem, except for me, try again here: LINK REMOVED

EDIT:
Arh, see what you mean, the updated scripts are in RT_Stats zip here: LINK REMOVED

StainlessS
23rd November 2013, 19:17
See Above Edit Fred.

FredThompson
23rd November 2013, 19:44
Thanks. I've edited my previous post to expand on the goals of my current project. Would appreciate any help you will offer.

StainlessS
23rd November 2013, 20:11
Mediafire link is a 404. Did you intend to have an updated script set there?

I am looking for a way to autocrop frames such as the attached screenshot. Preferred method would be a scan of an entire file with the minimal crop values returned. Seems the entire stream should be checked due to the variable cropping mentioned above. Results will be used to generate encoder scripts with video bitrate a function of post-cropped frame-size. My hope is to use RoboCrop in a pre-scan to generate crop values for each file in the queue, preserving field order and block sizes so crap and frame would be the result. Output from RoboCrop would probably go into a file with a format similar to:

filename
cropx1
cropx2
cropy1
cropy2
framewidth
frameheight

or something similar which can be easily parsed by a batch file. End result of my process will be a job queue of various frame sizes, rates and source codecs which can be loaded into Hybrid encoding GUI for a "encode all in directory to a target quality/size" process.

Another example of this type of unwanted junk is at:

http://forum.doom9.org/showthread.php?p=1651430#post1651430

Notice how close the noise is to the desired video data. Perhaps a grayscale vs. chroma determination would help.

I assume this is extra junk that DirecTV uses for the guide data or extra information for a show, maybe it's the bitmap for the recorded show.

Background to this project is at:

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

I would need to disable the auto start/end credits skipping, and give alternative method of selecting samples, eg percentage of frames to scan (maybe user calc something like 100.0 / FrameRate for 1 frame per second, scanned, or 10.0 % for 1 in ten scanned). Have to think about the morse code stuff, and waiting to see attachment.

FredThompson
24th November 2013, 03:35
Yes, I was thinking about 1 frame every 15 or 30 frames through the whole file. It's a very different use than you've envisioned but a related concept.

Letterboxed source with the "morse code" is fairly easy because there will be a number of near-black lines above and below the source. Test from the bottom then use that indicate relative upper cutoff location.

Non-letterboxed source with that crap in the top few lines is the challenge. Sometimes it's one line, The sample I made is probably the most complex I've seen, four or five lines. That's a LOT of extra data. My original idea was to overwrite those lines with black to preserve aspect ratio.

The DirecTV files I have with the crap in them are all 480x480 or 544x480 SD. If there are other formats with junk, I don't know about them.

StainlessS
24th November 2013, 16:59
Having seen you attachment, think all that really is needed is avoid start/end credits skipping. You can calc samples as FrameCount / 30
or whatever and the Baffle setting would avoid the morse code anyway (can set higher than default 4), setting Blank to true would blank
out the border area. Would work best if converted to YV24 allowing blanking of individual scanlines.
Ill add something to avoid credits skipping and let you have a try with that.

EDIT:
Non-letterboxed source with that crap in the top few lines is the challenge. Sometimes it's one line,

Not sure that single line of morse could be detected if no additional lines of black. The Baffle setting controls the minimum
number of consecutive lines that have to be above Threshold, to be detected as image rather than border.
Your attachment should be no problem but baffle might need be raised if morse thicker than Baffle default of 4.

FredThompson
25th November 2013, 19:27
thanks.

StainlessS
25th November 2013, 20:31
Fred can you up a sample somewhere, think I got an idea that might work for morse without letterboxing, about two minutes should do.

FredThompson
25th November 2013, 22:11
Fantastic news! Yes, am putting one up now. Will send you a PM with a link.

StainlessS
29th November 2013, 15:27
Link to MediaFire in sig now working OK, removed temp links.

jmac698
1st December 2013, 03:49
Feature request,
Hi, it's the season for planet cropping again, and I just came up with a really clean way to do it. What I'd like is a tracking crop. What this means is that, I supply frame1 and frame100 and it computes the cropping values for each, then draws a linear line between them, and uses that for the search zone.

In the ideal case, planets move in a perfect straight line across the camera as the earth turns. But it's not exactly because of lens distortions and other things. You can speed up cropping tremendously by tracking the search area. Sometimes I'm tracking only 20x20 pixels in a 16MP image. There's also the possibility of passing by some other bright object that can fool plain luma detection.

So the parameters would be, start/end frame to find endpoint locations, initial search window w/h/x/y, and tween search window size, and all the usual detection parameters. Also the option for simple tracking with no detection at all in the tweens.

some samples here
http://imgur.com/FnbRhes,wOBrbPf,E2y7UUy,lOBJ5oT,NQOEk3y,GIBgUhD#0

StainlessS
1st December 2013, 19:24
Jmac, surely animate could be persuaded to do that.

EDIT: Also, see no real advantage to 'tracking' estimate to were planets are, the RT_YInRangeLocate fn
in PlanetCrop is really quite fast and I dont really fancy spending quite a lot of time coding to save a second
or two every now and then.

StainlessS
17th January 2014, 05:05
RoboCrop v1.03, updated 26 Dec 2013.


v0.20, Changed, range massage switch on frames to below 1500 (from 1000).
v0.21, Autothresh Massaging changed minimum to -1.5 from -0.5.
v1.00, Added ATM arg.
v1.02, Added Start & End args, Changed default rec709 switch to width > 1100 || height > 600.
v1.03, Minor mods.

Reginald0
11th October 2014, 01:58
Hi, folks! Sorry if I miss something in the doc, but is it possible to adjust specific values like in the AutoCrop plugin?

AutoCrop(mode=0, leftadd=4, rightadd=2, topadd=8, bottomadd=6)

StainlessS
11th October 2014, 17:52
Suggest trying a greater value of auto Thresh (greater being more -ve). I wish now that I had used a more -ve default AutoThresh (is -32.0),
I sometimes find that RoboCrop() does leaves a little dark line (which is perhaps about AverageLuma ~48.0 to ~56.0, but still appears as dark edge
when adjacent to lighter image). If I have a problem clip (maybe about 1 in 30 or 40, or thereabouts), I just try a Thresh of eg -50.0 sometimes takes -64.0, and the line disappears. Might also prove better with the occasional clip to raise Baffle to eg 8 from default 4. AutoCrop() would also fail with the problem clips leaving a line,
but a lot more often and with worse results, AutoCrop gets it wrong a lot more often than RoboCrop and occasionally eats up more image than it leaves intact.
I would suggest that you try the above fix (make Thresh more -ve), and if not satisfactory, then will look at adding the suggested args, (LeftAdd etc).

EDIT: I have a 10min sample VOB from Cabaret (Liza Minnelli) that AutoCrop crops about 200 pixels both left and right sides, rather than maybe about 4 pixels either side (default settings). RoboCrop gets it bang on correct with only a single sample (Default 32, although it would depend upon which frame was chosen to sample, AutoCrop and RoboCrop do not use similar methods to select sample frames).

StainlessS
13th October 2014, 01:07
v1.13 Docs, part 1 of 2 (Post #1 only has v1.0 docs due to draconian D9 post size restrictions)

RoboCrop()

To Protect And Serve - by StainlessS @ Doom9:- http://forum.doom9.org/showthread.php?t=168053
Requires VS2008 CPP Runtimes.

VIDEO: Planar, YUY2, RGB (Must be Seekable ie best not DivX or XVid).
AUDIO: No change.

Plugin's for both Avisynth v2.58 and v2.6 (avs+ x86 & x64).

RoboCrop is an automatic cropping solution to crop black borders from video clips, loosely based on (but using no code from)
Autocrop by Glenn Bussell.

For the most part, you can just call it with RoboCrop(clip) and not bother with any other arguements, it is intended to be pretty
much autonomous in its decisions. You might however want to alter eg WMod/HMod if your encoder has special requirements, and
perhaps Laced if your source is likely to be fully progressive.

Borders are detected by sampling at Samples frames, at scanlines (h/v) using AverageLuma (RGB is converted to Luma Y at either TV or
PC levels, See Matrix). This sampling is done on all 4 sides of the frame.
If a scanline Average luma is below or equal to Thresh, then is considered possible black border, above considered possible image,
if Baffle [default=4] adjacent scanlines above Thresh, then it IS image.

Function RoboCrop(clip c,int "Samples"=40,Float "Thresh"=-40.0,bool "Laced"=true,int "WMod",int "HMod",int "RLBT"=15,bool "Debug"=false, \
float "Ignore"=0.4,int "Matrix"=(c.Width>1100||c.Height>600?3:2), int "Baffle"=4, bool "ScaleAutoThreshRGB"=true,
bool "ScaleAutoThreshYUV"=false, int "CropMode"=2,bool "Blank"=false,bool "BlankPC"=false,bool "Align"=True,bool "Show"=false, \
String "LogFn"="",bool "LogAppend"=false, Float "ATM"=4.0,int "Start"=Undefined,Int "End"=Undefined, \
Int "LeftAdd"=0,Int "TopAdd"=0,Int "RightAdd"=0,Int "BotAdd"=0, \
Int "LeftSkip"=0,Int "TopSkip"=0,Int "RightSkip"=0,Int "BotSkip"=0 \
Float "ScanPerc=49.0,String "Prefix"="ROBOCROP_" )


Args:-

Samples=40, Number of frames to sample from source clip c. v1.06 changed default from 32 to 40.
As an observation, most clips have good border recogition within the 1st 2 or 3 sampled frames using the default -40.0 AUTOTHRESH
although have noticed some dark clips that required ~8 samples (maybe more) for full recognition @ default Thresh = -40.0
We use a default Samples=40, because we are intrinsically paranoid.
If number of frames between frame at 5% of framecount and frame at 90% of framecount is greater than 250 and is also greater
than Samples, will ignore the first 5% and last 10% of frames when both auto-thresholding and crop sampling to try to negate
effects of artificial black in titles and end credits. Can override the Auto Credits skipping by setting Start and/or End frame
of the range to sample.
Samples = 0, will be converted to Samples = FrameCount, ie auto credits skipping disabled and ALL FRAMES SAMPLED,
of use for very short scenes, not for general full movie clips.
Set eg Samples = Int(FrameCount * 2.0 / 100.0 + 0.5) to sample 2.0% of frames in clip.

Thresh: Default= -40.0 (==DEFAULT AUTOTHRESH, any -ve (or 0.0) Thresh is AUTOTHRESH where Thresh adjustments are automatic).
v1.06, Changed DEFAULT AUTOTHRESH from -32.0 to -40.0.
v1.07, Changed to recognise a Thresh of either -32.0 or -40.0 as DEFAULT_AUTOTHRESH (fully automatic).

Thresh > 0: (Explicit Threshold)
A user supplied +ve Thresh should be at correct TV/PC levels for the the clip being worked on ie 16->235 for TV levels and
0->255 for PC Levels (RGB, as appropriate for matrix being used).

Thresh <= 0: (AUTOTHRESH)
When Thresh <= 0, the clip will be sampled over Samples frames to find the minimum YPlaneMin (using Matrix if RGB) which
we will call MINLUMA and an Explicit Threshold calculated by adding MINLUMA to abs(Thresh), after that it is processed
as for Thresh > 0: (Explicit Threshold) as noted above, but, before adding MINLUMA, some AUTOTHRESH massaging and scaling occurs.

Here AUTOTHRESH Thresh massaging and scaling occurs in sequence:-
1 ) if (Thresh == DEFAULT AUTOTHRESH && ATM < abs(thresh))
(DEFAULT AUTOTHRESH = exactly -40.0, defaulted OR user supplied, v1.07 also recognises -32.0 as DEFAULT_AUTOTHRESH):
Let sampstart and sampend, be starting and ending frames numbers after any Auto Credits skipping and/or user set Start or End.
Let Samples be limited to sampend-sampstart+1.
Let SampRange (Sample Range) = SampEnd-SampStart+1.
samples_massage =(Samples>=20) ? 1.0 : (Samples-1) * (1.0/(20-1)) # No massaging if Samples >= 20
range_massage =(SampRange >= (250*20)) ? 1.0 : (SampRange-1) * (1.0/((250*20)-1)) # No massaging if SampRange >= 5000
Both samples_massage and range_massage will be in range 0.0 to 1.0.
Thresh = -(((samples_massage * range_massage) * (abs(Thresh) - ATM)) + ATM)
This adjustment to Auto Thresh is to reduce the possibility of overcropping on eg a dark low 'Samples' clip, or where
source SampRange (ie temporal frame set) is too small to take a reliable sample from.
Resulting massaged Thresh will range between -ATM and DEFAULT_AUTOTHRESH.
Although massaging is intended to reduce overcropping, it could result in not cropping enough border (less disastrous),
its a bit of a balancing act really. See also ATM.
2 ) If RGB AND PC matrix(default) AND ScaleAutoThreshRGB==True(default) then
Thresh= Thresh*(255.0/(235-16))
3 ) If YUV AND ScaleAutoThreshYUV==True(default=false) then
Thresh= Thresh*(255.0/(235-16))

Steps 2) and 3) above, by default treat a -ve AUTOTHRESH as being @ TV Levels and so Scale RGB Thresh to PC levels but not YUV.
If you want to supply a PC levels AUTOTHRESH Thresh for RGB, then simply set ScaleAutoThreshRGB=false to inhibit scaling.
Note, if a TV levels Matrix is supplied for RGB, then scaling will always be inhibited.
If your clip is YUV at PC levels and you want to use eg DEFAULT AUTOTHRESH (-40.0, which is considered to be @ TV levels),
then set ScaleAutoThreshYUV=True to enable Thresh scaling.
If your clip is YUV at PC levels and you want to use a PC levels AUTOTHRESH (-ve) then leave ScaleAutoThreshYUV at default false
which does not scale Thresh.
After any scaling, MINLUMA is then added to abs(Thresh) and processed as for +ve Explicit Threshold as noted above.
NOTE, Above RoboCrop step 1) 'massages' DEFAULT_AUTOTHRESH (exactly -40.0 or v1.07 exactly -32.0) if low samples count or if short clip.
Reason being to avoid overcropping when insufficient data available for reliable cropping. It is considered better to not crop enough
or at all, than to overcrop. You can override by simply setting an explicit threshold (+ve) of eg 40.0, or setting a NON-DEFAULT auto thresh
(-ve) eg -16.0 or -40.1, where YPlaneMin is established for the sampled frames and then abs(thresh) is added to that value which
is then used as an explicit thresh.
NOTE, v1.07 recognises a Thresh of either -40.0 OR -32.0 as DEFAULT_AUTOTHRESH, so user can provide either value and
DEFAULT_AUTOTHRESH massaging will be applied for low samples count and/or low frame ranges.

Laced:, Default=true, true for Interlaced.
RoboCrop automatically deduces colorspace cropping restrictions and sets internal XMod and YMod,
eg XMod and YMod would both be set to 2 for YV12, for YUY2 Xmod=2, YMod=1, etc.
If Laced==true(default), then internal YMod is doubled so as not to destroy interlaced chroma.
Below HMod is defaulted to internal YMod after the Laced hint is applied to YMod.
You can set Laced=False if your source is known Progressive, if your dont then you may lose a few scanlines.

WMod:, Default=Max(XMOD,4), Where XMOD is the natural chroma cropping restriction of the colorspace concerned, eg 2 for YV12.
WMod MUST be a multiple of internal XMOD as described above, or it will throw an error.
v1.06, Changed default from XMOD to Max(XMOD,4), this is for several reasons, some encoders, media players and VDubMod
demand WMOD==4 ie width an exact multiple of 4 (some Mpeg encoders may demand WMOD=16 which you would have to set yourself).
In addition to above, Avisynth v2.58 kicks up a fuss if any YUV colorspace clip with Width not an exact multiple of 4 is
returned as final result clip (intermediate clips only have to comply with colorspace XMOD requirment). It is not really
the job of any plugin to guess whether it's result will be the final return clip and so is not really for RoboCrop to
enforce WMOD=4 for eg YV12, BUT, combined with the other reasons above, it was decided to change default WMOD to Max(XMOD,4),
you will have to set eg WMOD=2 manually if required for eg YV12 or YUY2, or WMOD=1 for eg RGB32 if that is what you want.
Avisynth has no problem returning eg RGB32 with an odd width, but at least one player had problems when RGB32 was XMOD=2
about 12 months prior to writing this (now fixed). WMOD set to 4 [as Max(XMOD,4) will likely be] will be least problematic
choice but you know what you require and can set WMOD to suit.
Some encoders may require an WMod/HMod of eg 8 or 16, and if set thus, would crop off more or less depending upon
which CropMode is set, if later resizing will be done, then encoder requirements can be satisfied during the resize.
NOTE, Some players and VirtualDubMod (Helix YV12 decoder) dont like WMOD less than 4 (Vdub latest, OK, internal decoder).
If eg VDMod shows blank frame, OR eg player halts saying eg "No combination of filters cound be found to render frame"
then WMod needs to be a multiple of 4.
NOTE, RT_Stats has a function RT_GetProcessName() which could be used to set WMod=4 only for specific programs eg,
RoboCrop(WMod=(RT_GetProcessName=="VirtualDubMod.exe") ? 4 : Last.RT_ColorspaceXMod) # Where VDubMod opened Avisynth
v1.08, limited WMod to max 16.

HMod:, Default=The natural chroma cropping restriction of the colorspace concerned, BUT, doubled if laced=true.
HMod MUST be a multiple of internal YMod as described under Laced above, or it will throw an error. If eg colorspace is
YV12 then YMod would be set to 2, and if Laced, then YMod would be doubled to 4, so HMod MUST be a multiple of 4.
v1.08, limited HMod to max 16.

RLBT:=15=All Borders, Bitflags of borders to detect, 15 ($0F) crops all four. Each letter in the name 'RLBT' represents an edge and bit position
starting with 'R' in bit 3 representing the value 8 (2^3=8). 'L' = bit 2=4 (2^2=4), 'B' = bit 1=2 (2^1=2), 'T' = bit 0=1 (2^0=1).
To calculate the RLBT bitflags, for 'R'(Right) add 8, for 'L'(Left) add 4, for 'B'(Bottom) add 2, and for 'T'(Top) add 1.
Add all of the bit flags together 8+4+2+1 (=15) crops all four edges, 8+4 crops only Right & Left, and 2+1 crops only Bottom & Top.
RLBT affects border detection.
User Skips eg LeftSkip are applied irrespective of what RLBT is set to.
User adjustments eg LeftAdd are applied irrespective of what RLBT is set to.

DEBUG:=False=No Debug. Set True for debugging info, need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027
The debug info output shows eg range limiting of Samples and sample info and resultant auto set Thresh. You are encouraged
to use debug to see the eg the auto Thresh massaging in action, it may help to understand usage of the plugin. MS DebugView
can also be used to view output from other plugins and programs that can also be useful.

Ignore:=0.4, Percentage of darkest pixels to ignore during AutoThresh scan to detect minimum luma pixel of all sampled frames.
(ignores a few extreme pixel values ie noise, as for Threshold arg in YPlaneMin).
v1.05, changed default from 0.2% to 0.4%.

Matrix:, RGB ONLY. For conversion of RGB to YUV-Y, 0 = Rec601, 1 = Rec709, 2 = PC601, 3 = PC709
Default for RGB is:- If clip Width > 1100 OR clip Height > 600 Then 3(PC709) , else 2(PC601) : YUV not used
The defaults are for PC601 & PC709 range 0-255.
So as to not require different AutoThresh for RGB, if clip c is RGB AND matrix is PC Levels AND Thresh < 0.0 and ScaleAutoThreshRGB=true,
then Thresh will be scaled to RGB full range ie Thresh = Thresh * (255.0/(235.0-16.0)) ONLY when AutoThresh (ie Thresh < 0.0,
YPlaneMin relative).
When +ve Thresh is explicitly supplied (Thresh > 0.0) it is not scaled and assumed to be already correct range TV or PC levels.

StainlessS
13th October 2014, 01:07
v1.13 Docs, part 2 of 2



Baffle:=4, Number of scanlines (h/v) that must break threshold to be considered image (can avoid noise around frame edges).
Does not usually need changing but might be of use to avoid some kind of eg teletext data at top of frame in broadcast video.

ScaleAutoThreshRGB: bool default True. If true and RGB and Matrix at PC levels, and Thresh -ve (autothresh) then thresh will (after any
auto Thresh massaging) be scaled to PC levels. By default, -ve Auto Thresh is considered to be at TV levels, and so will be scaled to
to PC levels to match the matrix setting. If ScaleAutoThreshRGB is False Then autothresh is considered to be at PC levels and not scaled.

ScaleAutoThreshYUV: bool default False. If true and YUV and Thresh -ve (autothresh) then Thresh will (after any auto Thresh massaging),
be scaled to PC levels. By default, -ve Auto Thresh is considered to be at TV levels, this allows you to change that assumption when
source clips are at PC levels. If supplying PC levels clip and PC levels autothresh then leave this setting at false (no scaling).
The above seemingly awkward settings are due to having to deal with YUV @ TV levels and RGB @ PC levels with the possibility of
YUV @ PC levels.

Cropmode: default=2 == CropMore. 1 = CropLess. Range 1 -> 2.
1 (CropLess) crops a little less border if the exact cropping coords do not comply with XMod/YMod/WMod/HMod as
described earlier. May leave a little border edge.
2 Default, (CropMore) crops a little extra where exact coords do not comply XMod/YMod/WMod/HMod requirements.
You may lose a little of the image edges.
CropMode is applied AFTER any user edge adjustments via LeftAdd, TopAdd, RightAdd and BotAdd.

Blank: Default False. If true, then Blanks the borders, ie sets border to RGB(0,0,0) or YUV(16,128,128) instead of cropping.
Is overridden if Show == true.

BlankPC: default false. If Blanking then blanks to YUV(0,128,128) instead of default YUV(16,128,128).

Align: Default True. If true, then aligns frames in memory when cropping, for eg SSE2 16-byte alignment required by some
filters, particularly smoothing filters (filters following RoboCrop). See Docs for Crop().
Only Applies if Cropping, ie Blank==false AND Show==false.
v1.11, changed Default to True, avoid Avs+ problems which can put up an error if False.

Show: Default false. If true, then does no cropping, just shows a little info on frame. Overrides both Blank and Align.
Final image edge positions shown as dotted lines every fifth pixel set white, always shown. Final image edge markers show edge
after any User adjustment via Add args (LeftAdd, TopAdd, RightAdd, BotAdd), and also after Modn rounding applied (CropMore/CropLess).
Exact image edges are show if not exactly coinciding with Final Image Edge markers, Exact image edge markers shown as every 3rd pixel
plotted in white.
Where the Skip args (LeftSkip, TopSkip, RighSkip, BotSkip) are non zero, will show skip positions as dotted lines with dots
every other pixel, not plotted if exact same position at final Modn (CropMore/CropLess) position or detected exact edge position.
The Skip args preset the 'already cropped area', ie auto cropping starts with edges already considered border.
Added cross hair reticule when show=True. Larger markings are 10 pixels apart, dots are 5 pixels apart.
Perhaps of use where borders not of fixed position.

LogFn: Default "" (unset). Filename of Log file.
Will output crop coords, crop coords will be output whether cropping or not (Blank/Show), format as within quotes below.

'28 92 668 392 2 4 2 4 720 576 27 89 696 484 2 27 89 696 484 '

Where in order:
CropX CropY CropW CropH : Crop coords mod XMod, YMod, WMod, HMod.
XMod YMod WMod HMod : As used for above crop coords
Width Height : Original frame width and height
ORG_X1 ORG_Y1 ORG_X2 ORG_Y2 : Exact coords of found image, not rounded according to x/y/w/h mod (Before User Adjust)
CropMode : 1 = CropLess, 2 = CropMore(default)
X1 Y1 X2 Y2 : Coords after any User adjustments eg ORG_X1+LeftAdd etc and before applying XMod etc.
All values output are single SPACE separated.


LogAppend: Default false. If true then appends log to any existing log file.

ATM: Float default 4.0 (0.5 -> 40.0). Silently limited to valid range.
ATM allows user to set the DEFAULT_AUTOTHRESH massaging minimum. When eg samples = 1, then auto thresholding is of course quite
unreliable and so auto Thresh would be 'massaged' to -ve(ATM), other values of Samples below 20 will likewise have auto thresh
massaged but to a lesser degree, linearly between -ve(ATM) for Samples == 1 and -ve(40.0) for Samples == 20.
Auto Thresh massaging also takes into account the frame range of samples (first sampled frame to last sampled frame inclusive)
and this is mixed together with any samples massaging then applied to auto Thresh.
Previous (Fixed) default for ATM was 0.5, for maximum safety so that a single Samples scan would NOT overcrop. The new ATM arg default
of 4.0 is a less paranoid safety setting which should in most cases work well but with a very short clip or eg single image then
user might be better off giving the minimum ATM of 0.5. An ATM of 40.0 will switch OFF default auto thresh massaging.
So long as sample range is about 5000+ frames and Samples at least 20(default 40), then there will be no auto thresh massaging and
current default is unlikely to need changing, with very short clips or reduced Samples count, then you might want to reduce ATM, for
maximum paranoia, set ATM=0.5 -> 1.0, especially in an app that processes single images. See Thresh.

Start: Default Undefined. Start frame of scan area. Overrides Auto Intro credits skipping.
For Auto Intro and End Credits Skipping to be set to 5% (of FrameCount for Intro Skipping) and 90% (for End Skipping), the number of
frames between them must be greater or equal to 250 frames, and MUST also be greater than Samples, otherwise Auto skipping ignored and
the Start and End frame numbers are set to 0 and Framecount - 1. If a user supplies eg a Start frame number ONLY, then End Skipping
has to comply with the same conditions, range between End Skip frame and user supplied Start has to be at least 250 frames and greater
than Samples, otherwise End frame set to FrameCount - 1.
After either via Auto Credits skipping, or user supplied Start/End, or defaulted to 0 & FrameCount -1, we have a sample scan range.

End: Default Undefined. End frame for scan area. Overrides Auto End credits skipping. 0 will be converted to Framecount - 1.
See previous Start setting.

Int LeftAdd, TopAdd, RightAdd, BotAdd, All default 0. Valid range depends upon clip dimensions, Skip and Baffle settings.
User adjustments to Skip + Autocrop exact found coords. CropMode applied after user Add adjustments.

Int LeftSkip, TopSkip, RightSkip, BotSkip, All default 0. TopSkip/BotSkip range 0 -> Height/4. LeftSkip/RightSkip range 0 -> Width/4.
Minimum edge croppings, detection starts with these edges cropped already, and are applied whether RLBT flags (ie edge crop scanning)
are applied or not. Avoid noise eg teletext at top of frame of VHS gunk at bottom.
NOTE, The Skip and Add args eg LeftSkip and LeftAdd are processed irrespective of the relevant RLBT flags so if you just wanted to
autocrop top and botton then set RLBT=$03 and can set either LeftSkip = 16 OR LeftAdd=16 to manually crop 16 pixels from Left hand
Side, DO NOT SET BOTH are this would crop off 32 pixels. LeftSkip is applied before autocrop, and LeftAdd after autocrop, and then
results are rounded to WMOD:HMOD, dependent upon cropmode (Default CROPMORE).

Float ScanPerc, Default 49.0, Range 1.0->99.0. Percentage of clip dimensions to scan for border edges.
Default 49.0%, Starts scan from nearly the middle of frame to outer edge of frame looking for borders.
Specialist use, might use eg 99.0% when image wholly to one of other side of the middle of frame.
eg, when 99.0, starts scan for TOP edge at nearly bottom of frame, scanning upwards.
starts scan for BOT edge at nearly top of frame, scanning downwards.
starts scan for LFT edge at nearly RHS of frame, scanning leftwards.
starts scan for RGT edge at nearly LHS of frame, scanning rightwards.

String Prefix, Default "ROBOCROP_". Prefix for Local vars set by the filter, crop coordinates. Setting to "" disables Local vars.
With Prefix="ROBOCROP_" (Default)
ROBOCROP_X = X coord
ROBOCROP_Y = Y coord
ROBOCROP_W = +ve Width
ROBOCROP_H = +ve Height
ROBOCROP_W2 = -ve Width relative crop coord
ROBOCROP_H2 = -ve Height relative crop coord

Example use:
<<<<<<<<< CODE START <<<<<<<
BlankClip(Length=1,width=1024,height=768,Pixel_type="YV12")
Wid=Width
Hit=Height
BLK=Last.BlankClip(width=320,height=240,color=$FF00FF)
OverLay(BLK,x=680,y=416)
RoboCrop(ScanPerc=99,show=true,debug=true,Prefix="ROBOCROP_")
X=ROBOCROP_X # Get Local Vars as set by RoboCrop (Using Prefix, above using Prefix same as Default Prefix)
Y=ROBOCROP_Y
W=ROBOCROP_W
H=ROBOCROP_H
W2=ROBOCROP_W2
H2=ROBOCROP_H2
Subtitle("Source: Width="+String(Wid)+",Height="+String(Hit),Y=4)
Subtitle("Crop("+String(X)+","+String(Y)+","+String(W)+","+String(H)+")",Y=24)
Subtitle("Crop("+String(X)+","+String(Y)+","+String(W2)+","+String(H2)+")",Y=44)
Return Last
>>>>>>>>>> CODE END >>>>>>>





Cropping will likely fail on END CREDITS ONLY clips, where on black background, and will probably crop off the sides that are no
different in average luma to any letterbox borders, if you cannot see the borders, then neither can RoboCrop(), even setting the
auto Thresh to eg -1.0 or 0.0 is quite likely to fail. (See RLBT edge bitflags).

If cropping too much border, then increase Samples or reduce Thresh or lower ATM if short clip.
If not cropping enough border then border is being seen as image, increase Thresh (for -ve Thresh , make more -ve).

To speed up, you may want to leave Auto-Thresh alone and reduce samples, but there is danger that it will not detect all borders (overcrop).
Suggest you do not go below Samples=20, although early default for samples was 12, we use a paranoid setting of 40 by default.
However, RoboCrop is quite sprightly and you will probably not need to reduce Samples, but if you are interested in how long it takes to
do it's auto thresh scanning in the filter constructor, the time taken is output via the debug arg to DebugView. Clips that have no letter
boxing are quickest dealt with and those with largest borders take most time as it has to scan the borders of all Samples frames, looking for
bigger image. Doing a short test as I write this on a 10 mins 12 secs PAL DVD vob of Cabaret, it took 0.875secs where
borders = Crop(30,90,-24,-92) with default args except for Debug=true (RoboCrop v1.03, YV12, Core Duo, Duel Core 2.14Ghz, Sata 2).
NOTE, scans over entire range of clip and so clip must be seekable, ie not eg DIVX with only a single keyframe, would take nearly forever.

NOTE, The plugin AutoCrop() uses a Thresh of 40.0 and samples == 5 by default (No AutoThresh), but the base logic is not too dissimilar.

Final NOTE, use arg Laced=False if you always process progressive or deinterlaced, And ATM set between 0.5 and 4.0 if very short
clips/single-image.

StainlessS

StainlessS
25th February 2015, 15:37
RoboCrop new version v1.12. See 1st post. 1st post has old version of docs
(too big for 16KB post limit, see post #37 [2 posts ahead] for current docs over two posts).


v0.20, Changed, range massage switch on frames to below 1500 (from 1000).
v0.21, Autothresh Massaging changed minimum to -1.5 from -0.5.
v1.00, Added ATM arg.
v1.02, Added Start & End args, Changed default rec709 switch to width > 1100 || height > 600.
v1.03, Minor mods.
v1.04, Added User adjustments to detected border edges.
v1.05, Addef LeftSkip, RightSkip, TopSkip, BotSkip (also shown when Show). Changed default Ignore from 0.2 to 0.4.
v1.06, Changed Default WMod to 4, avoid possible problems in Avisynth v2.58, some media players and VDubMod.
Changed Default AutoThresh to -40.0, been wanting to do this for some time.
Changed default Samples to 40, paranoia.
v1.07, Changed to recognise AutoThresh of both -32.0 and -40.0 as DEFAULT AUTOTHRESH (both old and new version args).
v1.08, wmod,hmod limited max 16. Fixed crop centering.
v1.09, Added reticule when Show=true..
v1.10, Added Exact line marker when show.
v1.11, 07 Jan 2019. Added Version Resource, Move to VS2008, Added x64, Changed default Align=True.
v1.12, 06 Feb 2020. Added ScanPerc arg.


@ FredThompson, TopSkip, should assist with your morse code gunk.


Int LeftSkip, TopSkip, RightSkip, BotSkip, All default 0. Minimum edge croppings, detection starts with these edges cropped already,
avoid noise eg teletext at top of frame or VHS gunk at bottom.

StainlessS
22nd April 2015, 03:30
RoboCrop new version v1.06. See 1st post. 1st post has old version of docs
(too big for 16KB post limit, see post #37 for current docs over two posts).


v1.05, Added LeftSkip, RightSkip, TopSkip, BotSkip (also shown when Show). Changed default Ignore from 0.2 to 0.4.
v1.06, Changed Default WMod to 4, avoid possible problems in Avisynth v2.58, some media players and VDubMod.
Changed Default AutoThresh to -40.0, been wanting to do this for some time.
Changed default Samples to 40, paranoia.


Main changes


Samples=40, Number of frames to sample from source clip c. v1.06 changed default from 32 to 40.
As an observation, most clips have good border recogition within the 1st 2 or 3 sampled frames using the default -40.0 AUTOTHRESH
although have noticed some dark clips that required ~8 samples (maybe more) for full recognition @ default Thresh = -40.0
We use a default Samples=40, because we are intrinsically paranoid.
If number of frames between frame at 5% of framecount and frame at 90% of framecount is greater than 250 and is also greater
than Samples, will ignore the first 5% and last 10% of frames when both auto-thresholding and crop sampling to try to negate
effects of artificial black in titles and end credits. Can override the Auto Credits skipping by setting Start and/or End frame
of the range to sample.
Samples = 0, will be converted to Samples = FrameCount - 1, ie auto credits skipping disabled and ALL FRAMES SAMPLED,
of use for very short scenes, not for general full movie clips.
Set eg Samples = Int(FrameCount * 2.0 / 100.0 + 0.5) to sample 2.0% of frames in clip.

Thresh: Default= -40.0 (==DEFAULT AUTOTHRESH, any -ve (or 0) Thresh is AUTOTHRESH where Thresh adjustments are automatic).
v1.06, Changed DEFAULT AUTOTHRESH from -32.0 to -40.0.

Thresh > 0: (Explicit Threshold)
A user supplied +ve Thresh should be at correct TV/PC levels for the the clip being worked on ie 16->235 for TV levels and
0->255 for PC Levels (RGB, as appropriate for matrix being used).

Thresh <= 0: (AUTOTHRESH)
When Thresh <= 0, the clip will be sampled over Samples frames to find the minimum YPlaneMin (using Matrix if RGB) which
we will call MINLUMA and an Explicit Threshold calculated by adding MINLUMA to abs(Thresh), after that it is processed
as for Thresh > 0: (Explicit Threshold) as noted above, but, before adding MINLUMA, some AUTOTHRESH massaging and scaling occurs.

Here AUTOTHRESH Thresh massaging and scaling occurs in sequence:-
1 ) if (Thresh == DEFAULT AUTOTHRESH && ATM < 40.0) (DEFAULT AUTOTHRESH = exactly -40.0, defaulted OR user supplied):
Let sampstart and sampend, be starting and ending frames numbers after any Auto Credits skipping and/or user set Start or End.
Let Samples be limited to sampend-sampstart+1.
Let SampRange (Sample Range) = SampEnd-SampStart+1.
samples_massage =(Samples>=20) ? 1.0 : (Samples-1) * (1.0/(20-1)) # No massaging if Samples >= 20
range_massage =(SampRange >= (250*20)) ? 1.0 : (SampRange-1) * (1.0/((250*20)-1)) # No massaging if SampRange >= 5000
Both samples_massage and range_massage will be in range 0.0 to 1.0.
Thresh = -(((samples_massage * range_massage) * (40.0 - ATM)) + ATM)
This adjustment to Auto Thresh is to reduce the possibility of overcropping on eg a dark low 'Samples' clip, or where
source SampRange (ie temporal frame set) is too small to take a reliable sample from.
Resulting massaged Thresh will range between -ATM and -40.0.
Although massaging is intended to reduce overcropping, it could result in not cropping enough border (less disastrous),
its a bit of a balancing act really. See also ATM.
2 ) If RGB AND PC matrix(default) AND ScaleAutoThreshRGB==True(default) then
Thresh= Thresh*(255.0/(235-16))
3 ) If YUV AND ScaleAutoThreshYUV==True(default=false) then
Thresh= Thresh*(255.0/(235-16))

Steps 2) and 3) above, by default treat a -ve AUTOTHRESH as being @ TV Levels and so Scale RGB Thresh to PC levels but not YUV.
If you want to supply a PC levels AUTOTHRESH Thresh for RGB, then simply set ScaleAutoThreshRGB=false to inhibit scaling.
Note, if a TV levels Matrix is supplied for RGB, then scaling will always be inhibited.
If your clip is YUV at PC levels and you want to use eg DEFAULT AUTOTHRESH (-40.0, which is considered to be @ TV levels),
then set ScaleAutoThreshYUV=True to enable Thresh scaling.
If your clip is YUV at PC levels and you want to use a PC levels AUTOTHRESH (-ve) then leave ScaleAutoThreshYUV at default false
which does not scale Thresh.
After any scaling, MINLUMA is then added to abs(Thresh) and processed as for +ve Explicit Threshold as noted above.
NOTE, Above RoboCrop step 1) 'massages' DEFAULT AUTOTHRESH (exactly -40.0) if low samples count or if short clip. Reason being to
avoid overcropping when insufficient data available for reliable cropping. It is considered better to not crop enough or at all,
than to overcrop. You can override by simply setting an explicit threshold (+ve) of eg 40.0, or setting a NON-DEFAULT auto thresh
(-ve) eg -16.0 or -40.1, where YPlaneMin is established for the sampled frames and then abs(thresh) is added to that value which
is then used as an explicit thresh.



WMod:, Default=Max(XMOD,4), Where XMOD is the natural chroma cropping restriction of the colorspace concerned, eg 2 for YV12.
WMod MUST be a multiple of internal XMOD as described above, or it will throw an error.
v1.06, Changed default from XMOD to Max(XMOD,4), this is for several reasons, some encoders, media players and VDubMod
demand WMOD==4 ie width an exact multiple of 4 (some Mpeg encoders may demand WMOD=16 which you would have to set yourself).
In addition to above, Avisynth v2.58 kicks up a fuss if any YUV colorspace clip with Width not an exact multiple of 4 is
returned as final result clip (intermediate clips only have to comply with colorspace XMOD requirment). It is not really
the job of any plugin to guess whether it's result will be the final return clip and so is not really for RoboCrop to
enforce WMOD=4 for eg YV12, BUT, combined with the other reasons above, it was decided to change default WMOD to Max(XMOD,4),
you will have to set eg WMOD=2 manually if required for eg YV12 or YUY2, or WMOD=1 for eg RGB32 if that is what you want.
Avisynth has no problem returning eg RGB32 with an odd width, but at least one player had problems when RGB32 was WMOD=2
about 12 months prior to writing this (now fixed). WMOD set to 4 [as Max(XMOD,4) will likely be] will be least problematic
choice but you know what you require and can set WMOD to suit.

EDIT:
The Max() bit above in Magenta is just in case some future supported Planar format has requirement greater than 4.


Function RoboCrop(clip c,int "Samples"=40,Float "Thresh"=-40.0,bool "Laced"=true,int "WMod",int "HMod",int "RLBT"=15,bool "Debug"=false, \
float "Ignore"=0.4,int "Matrix"=(c.Width>1100||c.Height>600?3:2), int "Baffle"=4, bool "ScaleAutoThreshRGB"=true,
bool "ScaleAutoThreshYUV"=false, int "CropMode"=2,bool "Blank"=false,bool "BlankPC"=false,bool "Align"=false,bool "Show"=false, \
String "LogFn"="",bool "LogAppend"=false, Float "ATM"=4.0,int "Start"=Undefined,Int "End"=Undefined, \
Int "LeftAdd"=0,Int "TopAdd"=0,Int "RightAdd"=0,Int "BotAdd"=0, \
Int "LeftSkip"=0,Int "TopSkip"=0,Int "RightSkip"=0,Int "BotSkip"=0)


Laced=True,Show = true
https://s20.postimg.org/vk7jwv799/robo0_zpsfzfpfakr.jpg (https://postimg.org/image/sq4ejf52x/)

MysteryX
4th December 2015, 01:09
I'm using RoboCrop like this to get the auto-crop dimensions
RoboCrop(LogFn="Preview_Temp.txt")

then I run it with avs2yuv.exe

It takes a long time to get the result because it is processing the whole file. Is there a way to just get the coordinates to the file and then stop any further processing?

Groucho2004
4th December 2015, 01:16
I'm using RoboCrop like this to get the auto-crop dimensions
RoboCrop(LogFn="Preview_Temp.txt")

then I run it with avs2yuv.exe

It takes a long time to get the result because it is processing the whole file. Is there a way to just get the coordinates to the file and then stop any further processing?
AVSMeter script.avs -i

StainlessS
4th December 2015, 01:53
Or something like,


AviSource("Cabaret.avi")
WMOD=4
LACED=False
SHOW=True # Whatever
DEBUG=True # DebugView
RoboCrop(WMod=WMOD,Laced=LACED,Show=SHOW,LogFn="Coord.Txt",Debug=DEBUG)
Trim(0,-1) # Curtail Avs2YUV scan


EDIT:
Produces This coords.txt:

28 90 668 394 2 2 4 2 720 576 28 89 696 484 2 28 89 696 484



LogFn: Default "" (unset). Filename of Log file.
Will output crop coords, crop coords will be output whether cropping or not (Blank/Show), format as within quotes below.

'28 92 668 392 2 4 2 4 720 576 27 89 696 484 2 27 89 696 484 '

Where in order:
CropX CropY CropW CropH : Crop coords mod XMod, YMod, WMod, HMod.
XMod YMod WMod HMod : As used for above crop coords
Width Height : Original frame width and height
ORG_X1 ORG_Y1 ORG_X2 ORG_Y2 : Exact coords of found image, not rounded according to x/y/w/h mod (Before User Adjust)
CropMode : 1 = CropLess, 2 = CropMore(default)
X1 Y1 X2 Y2 : Coords after any User adjustments eg ORG_X1+LeftAdd etc and before applying XMod etc.
All values output are single SPACE separated.


https://s20.postimg.cc/9mb332s8t/Cabaret_zpsl1admor0.png (https://postimg.cc/image/7hqq1zqm1/)

Debugview

00000174 262.95639038 [2148] RoboCrop: RoboCrop: v1.06 - 22 Apr 2015 - By StainlessS
00000175 262.95642090 [2148] RoboCrop: Input: Width=720 Height=576 FrameCount=15285
00000176 262.95642090 [2148] RoboCrop:
00000177 262.95648193 [2148] RoboCrop: Thresh defaulting to DEFAULT AUTOTHRESH -40.00
00000178 262.95651245 [2148] RoboCrop: Potential Auto Credits Skip Start@5%=764 End @90%=13756 : Range=12993
00000179 262.95654297 [2148] RoboCrop: Skip Start(764) and End(13756) : Range=12993
00000180 262.95657349 [2148] RoboCrop:
00000181 262.95660400 [2148] RoboCrop: Samples=40 Thresh=-40.000 Laced=False Matrix=2
00000182 262.95663452 [2148] RoboCrop: WMod=4 HMod=2 {Colorspace/Laced Restricted XMod=2 YMod=2}
00000183 262.95666504 [2148] RoboCrop: RLBT=15 Ignore=0.400 Baffle=4
00000184 262.95669556 [2148] RoboCrop: ScaleAutoThreshRGB=Yes ScaleAutoThreshYUV=No
00000185 262.95669556 [2148] RoboCrop: CropMode=2(CropMore) Blank=No Align=No Show=Yes Log=Yes
00000186 262.95672607 [2148] RoboCrop: Atm=4.000 SampStart=764 SampEnd=13756 SampRange=12993
00000187 262.95672607 [2148] RoboCrop: LeftAdd=0 TopAdd=0 RightAdd=0 BotAdd=0
00000188 262.95675659 [2148] RoboCrop: LeftSkip=0 TopSkip=0 RightSkip=0 BotSkip=0
00000189 262.95678711 [2148] RoboCrop:
00000190 262.98403931 [2148] RoboCrop: AutoThresh 1) [ 764] YPlaneMin = 14 (14)
00000191 263.04266357 [2148] RoboCrop: AutoThresh 2) [ 1097] YPlaneMin = 14 (14)
00000192 263.07455444 [2148] RoboCrop: AutoThresh 3) [ 1430] YPlaneMin = 14 (14)
00000193 263.09149170 [2148] RoboCrop: AutoThresh 4) [ 1763] YPlaneMin = 14 (14)
00000194 263.10733032 [2148] RoboCrop: AutoThresh 5) [ 2097] YPlaneMin = 14 (14)
00000195 263.12109375 [2148] RoboCrop: AutoThresh 6) [ 2430] YPlaneMin = 15 (14)
00000196 263.13745117 [2148] RoboCrop: AutoThresh 7) [ 2763] YPlaneMin = 14 (14)
00000197 263.15515137 [2148] RoboCrop: AutoThresh 8) [ 3096] YPlaneMin = 14 (14)
00000198 263.17474365 [2148] RoboCrop: AutoThresh 9) [ 3429] YPlaneMin = 13 (13)
00000199 263.21542358 [2148] RoboCrop: AutoThresh 10) [ 3762] YPlaneMin = 14 (13)
00000200 263.24392700 [2148] RoboCrop: AutoThresh 11) [ 4095] YPlaneMin = 14 (13)
00000201 263.25967407 [2148] RoboCrop: AutoThresh 12) [ 4428] YPlaneMin = 14 (13)
00000202 263.32559204 [2148] RoboCrop: AutoThresh 13) [ 4762] YPlaneMin = 14 (13)
00000203 263.35232544 [2148] RoboCrop: AutoThresh 14) [ 5095] YPlaneMin = 14 (13)
00000204 263.38153076 [2148] RoboCrop: AutoThresh 15) [ 5428] YPlaneMin = 14 (13)
00000205 263.42202759 [2148] RoboCrop: AutoThresh 16) [ 5761] YPlaneMin = 14 (13)
00000206 263.48983765 [2148] RoboCrop: AutoThresh 17) [ 6094] YPlaneMin = 14 (13)
00000207 263.55682373 [2148] RoboCrop: AutoThresh 18) [ 6427] YPlaneMin = 14 (13)
00000208 263.59436035 [2148] RoboCrop: AutoThresh 19) [ 6760] YPlaneMin = 14 (13)
00000209 263.62008667 [2148] RoboCrop: AutoThresh 20) [ 7093] YPlaneMin = 14 (13)
00000210 263.64840698 [2148] RoboCrop: AutoThresh 21) [ 7427] YPlaneMin = 15 (13)
00000211 263.66235352 [2148] RoboCrop: AutoThresh 22) [ 7760] YPlaneMin = 14 (13)
00000212 263.67373657 [2148] RoboCrop: AutoThresh 23) [ 8093] YPlaneMin = 14 (13)
00000213 263.70022583 [2148] RoboCrop: AutoThresh 24) [ 8426] YPlaneMin = 14 (13)
00000214 263.73031616 [2148] RoboCrop: AutoThresh 25) [ 8759] YPlaneMin = 14 (13)
00000215 263.74728394 [2148] RoboCrop: AutoThresh 26) [ 9092] YPlaneMin = 14 (13)
00000216 263.75781250 [2148] RoboCrop: AutoThresh 27) [ 9425] YPlaneMin = 14 (13)
00000217 263.77706909 [2148] RoboCrop: AutoThresh 28) [ 9758] YPlaneMin = 14 (13)
00000218 263.79431152 [2148] RoboCrop: AutoThresh 29) [ 10092] YPlaneMin = 14 (13)
00000219 263.81048584 [2148] RoboCrop: AutoThresh 30) [ 10425] YPlaneMin = 14 (13)
00000220 263.83358765 [2148] RoboCrop: AutoThresh 31) [ 10758] YPlaneMin = 14 (13)
00000221 263.85678101 [2148] RoboCrop: AutoThresh 32) [ 11091] YPlaneMin = 14 (13)
00000222 263.86941528 [2148] RoboCrop: AutoThresh 33) [ 11424] YPlaneMin = 14 (13)
00000223 263.89089966 [2148] RoboCrop: AutoThresh 34) [ 11757] YPlaneMin = 14 (13)
00000224 263.90399170 [2148] RoboCrop: AutoThresh 35) [ 12090] YPlaneMin = 14 (13)
00000225 263.92401123 [2148] RoboCrop: AutoThresh 36) [ 12423] YPlaneMin = 14 (13)
00000226 263.94082642 [2148] RoboCrop: AutoThresh 37) [ 12757] YPlaneMin = 14 (13)
00000227 263.96194458 [2148] RoboCrop: AutoThresh 38) [ 13090] YPlaneMin = 14 (13)
00000228 263.98049927 [2148] RoboCrop: AutoThresh 39) [ 13423] YPlaneMin = 14 (13)
00000229 264.00881958 [2148] RoboCrop: AutoThresh 40) [ 13756] YPlaneMin = 14 (13)
00000230 264.00885010 [2148] RoboCrop:
00000231 264.00888062 [2148] RoboCrop: YPlaneMin=13 : Automatic set Thresh=53.000
00000232 264.00891113 [2148] RoboCrop:
00000233 264.01147461 [2148] RoboCrop: Top 1) [ 764] AveY= 53.14 Y1=177
00000234 264.01153564 [2148] RoboCrop: Bot 1) [ 764] AveY= 57.44 Y2=484
00000235 264.01156616 [2148] RoboCrop: Lft 1) [ 764] AveY= 54.72 X1=154
00000236 264.01162720 [2148] RoboCrop: Rgt 1) [ 764] AveY= 54.73 X2=695
00000237 264.01531982 [2148] RoboCrop: Lft 3) [ 1430] AveY= 54.32 X1= 28
00000238 264.01910400 [2148] RoboCrop: Top 5) [ 2097] AveY= 53.28 Y1=110
00000239 264.02890015 [2148] RoboCrop: Rgt 10) [ 3762] AveY= 63.56 X2=696
00000240 264.03656006 [2148] RoboCrop: Top 14) [ 5095] AveY= 54.04 Y1= 89
00000241 264.09036255 [2148] RoboCrop:
00000242 264.09039307 [2148] RoboCrop: Active Frames (where image coords first found) = 5
00000243 264.09042358 [2148] RoboCrop: Sampled ImageEdge: X1=28 Y1=89 X2=696(W=669,-23) Y2=484(H=396,-91)
00000244 264.09069824 [2148] RoboCrop:
00000245 264.09078979 [2148] RoboCrop: Crop(ModW/H): X = 28 Y = 90 W =668(-24) H =394(-92)
00000246 264.09085083 [2148] RoboCrop: Constructor Scan Total Time=1.140 secs

MysteryX
4th December 2015, 02:21
Trim(0,-1)

yeah that works.

Oddly enough, I already was using that for another script; somehow I missed that I was already doing it.

StainlessS
14th June 2016, 14:39
RoboCrop v1.07, new version.

V1.07 Docs overflow 16kb limit, so left first post docs at v1.0.
See post #37 for v1.07 Docs over two posts. Here: http://forum.doom9.org/showthread.php?p=1696703#post1696703


v0.20, Changed, range massage switch on frames to below 1500 (from 1000).
v0.21, Autothresh Massaging changed minimum to -1.5 from -0.5.
v1.00, Added ATM arg.
v1.02, Added Start & End args, Changed default rec709 switch to width > 1100 || height > 600.
v1.03, Minor mods.
v1.04, Added User adjustments to detected border edges.
v1.05, Addef LeftSkip, RightSkip, TopSkip, BotSkip (also shown when Show). Changed default Ignore from 0.2 to 0.4.
v1.06, Changed Default WMod to 4, avoid possible problems in Avisynth v2.58, some media players and VDubMod.
Changed Default AutoThresh to -40.0, been wanting to do this for some time.
Changed default Samples to 40, paranoia.
v1.07, Changed to recognise AutoThresh of both -32.0 and -40.0 as DEFAULT AUTOTHRESH (both old and new version args).


See Mediafire in sig for zip (~148.0 KB)

Katie Boundary
14th June 2016, 15:56
This reminds me of an idea that I recently had for a plugin that would auto-kill the slight pillarboxing that exists in some fullscreen sources because of overscan. Basically, you'd just give it a number (default = 16), and it would automatically select and crop the "darkest" column of pixels from either the left or right side of the screen, iterated that many times per frame. It could easily be modified to kill letterboxing as well. The easiest way to implement this might be to just give it a target resolution instead of target numbers of rows/columns to kill.

I shall call it... PillKill.

FranceBB
14th June 2016, 16:30
I tried it and it works.
I tested it with a "dodgy" source, which is HD - 2.35 LB but has a few captions appearing and disappearing sometimes at the bottom and it worked (it didn't crop them).
Well done! ;)

StainlessS
14th June 2016, 16:56
FranceBB,
With such a source, I would not recommend auto cropping of bottom, you were perhaps lucky that it just happened to sample a frame
with caption appearing just by chance (only samples 40 frames from entire clip, by default).
Perhaps best to set RLBT flags (which sides to autocrop) for eg top only, and set eg BotAdd to 64 or whatever to manually crop bottom area.
(EDIT: Above I'm assuming you mean that captions appear in bottom border)

EDIT:
@Katie, RoboCrop should deal with your problem clips no bother at all (see image a few posts ahead for all 4 sides cropped).

EDIT: The image is done with Show=True, ie did not do the actual cropping.
EDIT: To crop mod16 width, just set WMod=16 (where will center L+R cropping). Same for height, set HMod (see Laced).
CropLess mode may leave a little border to comply with W/HMod, CropMore[default] may crop a little extra to comply.
EDIT: Or mod8 as filler56789 said is OK for TmpGenc in your thread, set WMod=8.

StainlessS
14th June 2016, 17:52
Below a bit of code to show cropped DAR (Display Aspect Ratio) and also signal to MeGUI.
Req, RT_Stats.


AvisourcE("CabaretUncropped.avi")

FULLFRAME_DAR = 4.0/3.0 # Display Aspect Ratio of FULL FRAME

SAR = Last.RT_GetSAR(FULLFRAME_DAR) # Gets Sample (pixel) Aspect Ratio from full frame DAR Display Aspect Ratio.
RoboCrop(WMod=4, Laced=false, debug=true)
DAR = Last.RT_GetDAR(SAR) # Gets cropped DAR Display Aspect Ratio from SAR, Sample (pixel) Aspect Ratio.

RT_SignalDAR(DAR) # Signal DAR to MEGUI.
# Sets Global vars MeGUI_darX and MeGUI_darY which are read during MEGUI loading of AVS file.

RT_DebugF("Cropped DAR = %.3f",DAR,name="ShowDAR: ") # To DebugView

RT_Subtitle("Cropped DAR = %.3f",DAR,align=5)


NOTE, Dont miss post #45, RoboCrop is updated today.

EDIT: For Cabaret shows "Cropped DAR = 1.808".

EDIT Added explicit Last in places, might not be obvious that it is using clip to calc DAR and SAR.

EDIT: Above RT_ Aspect ratio functions converted from script, below original script

Function GetCropDAR(clip c,float DAR,float "X",float "Y",float "W",float "H") {
# Call prior to Crop/Resize with (possibly fractional) cropping to calc resultant DAR, X,Y,W,H are cropping coords
# DAR = FAR * SAR ::: FAR = DAR / SAR ::: SAR = DAR / FAR
#
X=Float(Default(X,0.0)) Y=Float(Default(Y,0.0)) W=Float(Default(W,0.0)) H=Float(Default(H,0.0))
W=W<=0.0?c.width+W-X:W H=H<=0.0?c.height+H-Y:H
# Irrespective of what various resizers in various Avisynth versions silently correct, we dont allow eg -ve X
Assert(X>=0.0&&X < c.width, "GetCropDAR: Invalid X("+String(X)+")")
Assert(Y>=0.0&&Y < c.height,"GetCropDAR: Invalid Y("+String(Y)+")")
Assert(W> 0.0&&X+W<=c.width, "GetCropDAR: Invalid W("+String(W)+")")
Assert(H> 0.0&&Y+H<=c.height,"GetCropDAR: Invalid H("+String(H)+")")
Return c.GetSAR(DAR) * W / H
}

#--------------

# From MeGUI Wiki:
Function GetDAR(clip c, float SAR) { return Float(c.width) * SAR / Float(c.height)} # Gets the DAR from the SAR
Function GetSAR(clip c, float DAR) { return DAR * Float(c.height) / Float(c.width) } # Gets the SAR from the DAR
Function SignalDAR(float DAR){ # Signal DAR for MEGUI (Name change from SetDar)
Assert(DAR>0.0, "SignalDAR: Error, DAR must be greater than zero")
Global MeGUI_darx=Round(1000*DAR) Global MeGUI_dary=1000
}
Function SignalDAR2(int DARX,int DARY){
Assert(DARX>0 && DARY>0, "SignalDAR2: Error, DARX and DARY must be greater than zero")
Global MeGUI_darx=DARX Global MeGUI_dary=DARY
}


Cropping keeps original SAR. Resizing (without crop) keeps original DAR.

Katie Boundary
14th June 2016, 18:37
@Katie, RoboCrop should deal with your problem clips no bother at all (see image a few posts ahead for all 4 sides cropped).

EDIT: The image is done with Show=True, ie did not do the actual cropping.
EDIT: To crop mod16 width, just set WMod=16 (where will center L+R cropping). Same for height, set HMod (see Laced).

If I'm interpreting the documentation correctly, that won't work. I'm talking about cropping in increments of one pixel until a target resolution is achieved. WMod and HMod seem to set the increments by which the cropping is done, with the final resolution being entirely decided by the filter...

On a side note, the hypothetical filter that I described has some serious flaws that become apparent when the pillarboxing is a few pixels wider or thinner than expected. A better version of the filter would attempt to include equal amounts of black on the edges if the borders are wider than expected, or crop equal amounts of color off the edges if the borders are thinner than expected. I've seen plenty of episodes in which the actual black area was - for example - only 7 pixels on one edge and 3 on the other, and I had to pad the crop values to 10 and 6 respectively. This crap drives me nuts.