Log in

View Full Version : Fancier RoboCrop or ???


MrPete
30th December 2014, 19:26
As I understand it, the RoboCrop filter assumes black borders (with optional ignored rows/columns on the edgets), and seeks "inward" to find the edge of the crop.

I'm dealing with captured film that's quite a bit more complicated. AFAIK this is totally normal... On a per-edge basis it could be any of:

1) Normal black border: black from edge to scene
2) Already no border: the good material goes right to the edge
3) Black border containing several variable lines of white (think right side of film where the lamp spills out along the edge of the film)
4) Misc-then-border-then-scene (think top or bottom of a film capture, where the previous/next frame is visible, then there's a black separator bar between frames)
5) Clear edge up to a narrow black frame around the scene
6) The hardest (?) to robo-find: left side of film which has both border and sprocket holes that are always clear/white
6a) #6 with black border
6b) #6 with clear edge to narrow black frame
7) Manual setting: top/bottom where there's actually no border at all... just two overlapping scenes.

An example (already somewhat cropped -- normally there would be more to the left/right):
http://www.ds.org/files/avisynth/blown%20highlights%20blue.jpg
This is case #2 on top, #3 on right, #4 on bottom, #6 on left.

My first puzzle: could a different and simple method find the crop edges more simply by starting in the middle of the frame and working OUTwards?

If not, how many of these scenarios could be automated? For now, I assume the user would predetermine which case applies to each edge... (maybe a negative number is the manual crop value for case #7?)

Seems like a potentially interesting but more difficult challenge to identify which is which. I'm not sure I want to try to get my head around that :)

StainlessS
30th December 2014, 21:20
I have no idea how to make RoboCrop know when image is not supposed to be there, as at the bottom of supplied pic,
and as for the spocket holes, no idea again, you need some magic dust or something.
The only thing that could possible help (but probably not for your sprocket problem) is increase Baffle significantly (to try to 'step over'
image to ignore) and also the sample count to avoid not detecting image due to the increase of baffle.

From QueryBorderCrop.avs (Supplied in RT_Stats.zip, converted to plugin RT_QueryBorderCrop).
Includes script detection here for top edge only.
(very few comments there as is real difficult to explain what it is doing, so I did not bother).

# Border detect
# Scan samples for image from frame outer to frame inner, as subsequent samples are processed, image grows outwards,
# whats left (if any) is border.
# At beginning, the image area is FULL SCREEN, so if no image at all is found, it is NOT all border, it is all image.
# The first image detections (all edges) establish an image area and so is no longer full screen, this area grows as further
# image detections are found, and if it grows to the screen edge again, there is no border (on that edge).
# At first, image grows vertically (top/bot scan), then grows horizontally (lft/rgt scan) where the horizontal
# scanning only scans the area established so far (by vertical scan) to be image. Next sample, the vertical scan similarly
# scans only the area established (by previous sample horizontal scan) to be image, ... etc, Less area to search and
# real border areas less likely to affect average luma.

GotF=-1 GotN=0 # Track Number of frames where coords 1st found
for(Samp = 1,Samples) {
Frm = int((Samp - 1) * SampMul + 0.5) + SampStart
thRem=0.0 th=0.0

if(RT_BitTST(RLBT,0) && Top>=(Baffle-1)) { # Top Edge
SCur=0 MCur=SCur Ecur=SCur+Baffle-1 OBreak=False
While(OBreak==False && ECur<=Top) {
i=ECur IBreak=False
while(i>=MCur && IBreak==False) {
th=RT_AverageLuma(n=Frm,x=CX,y=i,w=CW,h=1,matrix=Matrix)
if(th>Thresh) {
if(SCur==MCur){thRem=th}
i=i-1
} else {
IBreak=True
}
}
if(i<MCur) {
CY=SCur
Top=(CY==0)?0:ECur-1
if(Frm<>GotF) {
if(GotN==0 && Bot<i) {
Bot = i
}
GotF=Frm
GotN=GotN+1
}
(debug) ? RT_DebugF("Top %3d) [%6d] AveY=%6.2f Y1=%3d",samp,Frm,thRem,CY,name=myName) : NOP
OBreak=True
}else {SCur=i+1 MCur=ECur+1 ECur=i+Baffle}
}
}

MrPete
31st December 2014, 07:19
I'm thinking the inside-to-outside method would be much much easier...

In the meantime, I'll work on the magic dust as I sleep :)

Thanks for the thoughtful reply and code sample!

Hmmmm.....

StainlessS
31st December 2014, 15:38
I'm thinking the inside-to-outside method would be much much easier...

Dont think so. You have to detect 'Lack Of Image' rather than border. You cannot just scan inside to out and declare border at the first
raster line that is dark, image can be dark too. You have to basically 'grow' the detected image edges over a number of samples
finding the greatest area of image across all samples. Your method would end up overcropping on many clips, just dont think
it can work, although I would be delighted to be proved wrong.
As for your sprocket thing, presumably they dont stay in static position either, so could not tell difference from image.
If they did stay static, only way I could think of to detect (and this would be really best detection overall) would be to create a single
frame where each pixel was standard deviation of that pixel over the entire clip. That would I think require two entire scans of clip
(to not have to use an outrageous amount of memory), the first to find average (mean) of that pixel for the clip, and second pass
to calc standard deviation. Would be a lot simpler and faster to just do it manually. That method would also have to cope with static
opaque station logos, but that could be overcome.

If you can code something that does it your way in script, I would happily code it as plug, I will not hold my breath waiting. :)