View Full Version : Cropping interlaced video = shimmering bars
Ingram
11th January 2005, 13:50
I have recorded a tv show via SD tv. I have converted it to MPG and all that. I am currently trying to encode it with CCE and dvd2svcd, however I need to crop the image by 2 pixels all around the image, and because the file is interlaced (and I wish to keep it that way) I end up getting these flickering bars when I play it back in powerdvd with deinterlacing on.
I am using the Crop(x,x,x,x) command in the avisynth tab. I need help to know how to do this properly!. Video is pal 25fps interlaced.
thankyou.
Ps. I know this is a double post but im going insane tryint to get this work and I know its most likely something very simple.!
Ingram
11th January 2005, 14:41
Still no go. The way it plays is, its like half the video is playing, and another half is kinda lagging behind, so you get these lines of screen which are not aligned correctly with the rest of the image. I hope that better explains things.
Wilbert
11th January 2005, 14:54
If you crop interlaced video you should crop a multiple of 4 pixels from below, 4 pixels from above, since chroma is shared between 4 pixels (well between line 1, 3, and between line 2, 4, etc.). 2 pixels from the left and the right is ok.
Ingram
11th January 2005, 14:58
so it should be like this?
0=Crop(2,4,-2,-4)
Tried that, didnt work. I only seem to get this wave effect in Windvd when I set it to progressive playback, if its weave or bob its fine. Automaticially powerdvd gives me the wave effect unless I manually select a different de-interlace method.
Ingram
11th January 2005, 16:17
can anyone help me at all?
if I encode hte video without any cropping settings it works perfectly. With the cropping settings I get the wave effect.
I really need to fix this, ive been at it for 5 or so hours now.
Ingram
11th January 2005, 17:38
I just used TMPGEnc Plus 2.5 to do it and it worked flawlessly. So unless someone can tell me how I am to do it properly I think I will be sticking with TMPGEnc Plus 2.5.
Boulder
11th January 2005, 18:09
You probably had the field order wrong in CCE.
Ingram
11th January 2005, 18:19
No, I tried with it set to automatic, top field and bottom field. There was actually no change at all.
I tried to take pictures but it wouldnt come out in the pictures. Oh well.
Im sure someone here has successfully cropped an interlaced video?
Boulder
11th January 2005, 18:25
I do it all the time.
Is 'Offset line' set to zero in CCE? What is the field order of your original video?
Ingram
11th January 2005, 18:32
Originally posted by Boulder
I do it all the time.
Is 'Offset line' set to zero in CCE? What is the field order of your original video?
Where is this offset line setting? and its top field.
I just managed to encode it and it worked, but now it wont at all, keeps crashing.
With this
0=crop(0,4,720,572)
1=AddBorders(0,4,0,0)
It encodes and works, it cuts off the jibberish I was getting on the top. And it doesnt cause any silly wave effects. Its still the correct aspect isnt it? even if it isnt, 4 pixels :rolleyes:
Boulder
11th January 2005, 18:37
If your video really is TFF (how did you check this?), then the offset value should absolutely be zero. The setting can be found at the same place where you set the DVD compliance etc.
Have you tried Crop(0,4,-0,-4) ?
Ingram
11th January 2005, 18:40
Originally posted by Boulder
If your video really is TFF (how did you check this?), then the offset value should absolutely be zero. The setting can be found at the same place where you set the DVD compliance etc.
Have you tried Crop(0,4,-0,-4) ?
While I was demuxing it said the first field. Also I think its a PAL standard that its the first field.
I dont want to attempt any more settings since this is the first ever to properly work.
Oh and I know what your talking about with the offset, that happens after encoding, I always set it to 0 because I hate it cutting 5 seconds off the start of the file.
OK I tried your Crop(0,4,-0,-4) and that also worked. But! Powerdvd said its res was 720x560, where as the code I used resulted in power saying 720x576. which is what we want. Any idea's?
Boulder
11th January 2005, 19:08
Originally posted by Ingram
While I was demuxing it said the first field. Also I think its a PAL standard that its the first field.
Standard or not, if you process a captured clip, you should check it manually. This script will do it:
MPEG2Source("path\clip.d2v")
AssumeTFF()
SeparateFields()
Open in VDub and check if the motion is jerky or smooth. If it's smooth, it's top field first. If it's jerky, it's bottom field first.
Oh and I know what your talking about with the offset, that happens after encoding, I always set it to 0 because I hate it cutting 5 seconds off the start of the file.
The offset thing has nothing to do with cutting the video, it's how the video is arranged on the screen.
OK I tried your Crop(0,4,-0,-4) and that also worked. But! Powerdvd said its res was 720x560, where as the code I used resulted in power saying 720x576. which is what we want. Any idea's?
You have something wrong there. 576-4-4=568. But you see now that the 'wavy lines' were actually caused by cropping horizontally. If you crop 4 pixels off each side there should be no problems I think.
Ingram
11th January 2005, 19:12
Originally posted by Boulder
[B]Standard or not, if you process a captured clip, you should check it manually. This script will do it:
MPEG2Source("path\clip.d2v")
AssumeTFF()
SeparateFields()
Open in VDub and check if the motion is jerky or smooth. If it's smooth, it's top field first. If it's jerky, it's bottom field first.
Smooth.
The offset thing has nothing to do with cutting the video, it's how the video is arranged on the screen.
We must be talking about different ones then, im refering to the multiplexer which snips the first 5 seconds of the start of a clip to fix any sync issues. I have this set on 0.
You have something wrong there. 576-4-4=568. But you see now that the 'wavy lines' were actually caused by cropping horizontally. If you crop 4 pixels off each side there should be no problems I think.
I think it was being caused by having a resize line written, because I added it back and it caused the waves, removed and its gone. Im now trying to set it so it snips from the top and bottom, and maybe both sides so it keeps the right aspect.
Edit:
Ok, using
0=Crop(4,4,-4,-4)
1=AddBorders(4,4,4,4)
i have it playing perfectly in power with the correct DVD res being reported and no waves, also all the crap around the edge is now removed :) Only problem however is there are still some traces of interlacing even after power dvds de-interlacing. Wont matter on the tv. So meh :)
Thanks for your help. Amazing how 2 lines of code can take 6 hours to figure out for a Noob to Avisynth.
Mug Funky
12th January 2005, 09:58
you were resizing after cropping interlaced?
that'll give you waves on playback - when you vertically resize something that's interlaced it will mash the fields together, causing them to blur, and also causing the field order to effectively swap within the frame (causing smooth motion in the top half and jerky in the bottom, or several bars of alternating jerk and smooth).
cropping then adding borders will not cause this (but you have to use even numbers to maintain field-order).
if you wish to resize vertically (best not to though), you must bob-deinterlace, resize, then re-interlace. this will blur the video a fair bit unless you have a really good bob-deinterlacer.
one more note about field-order: mini-DV and it's variants are bottom-first, but DVD is top-first (but can be both!).
to complicate matters more, some DV decoders will shift the image up by 1-pixel, swapping the field order (and usually b0rking chroma too). the only way to know for sure is with the trick boulder said.
IanB
12th January 2005, 10:48
Try this.SeparateFields()
LanczosResize(new_width, new_height/2) # or whatever floats your boat
Weave()
IanB
scharfis_brain
12th January 2005, 12:20
@IanB:
this method of resizing should NOT be used.
it destroys static detail and introduces a vertical misalignment between both fields.
the better way to resize interlaced stuff is this:
(the one, Mug Funky described)
avisource("blah.avi")
assume?ff() #set the video's fieldorder correctly
bob() #better use an adaptive bobber like tdeint(mode=1) here
crop(blah)
lanczos(blah)
addborders(blah)
otherfiltersyoulike()
assume?ff() #set the fieldorder again
separatefields().selectevery(4,0,3).weave() #reinterlaced
kingmob
12th January 2005, 13:47
Originally posted by Ingram
I just used TMPGEnc Plus 2.5 to do it and it worked flawlessly. So unless someone can tell me how I am to do it properly I think I will be sticking with TMPGEnc Plus 2.5.
Well, i could be wrong, but i think TMPGEnc defaults to deinterlacing, so that would figure...
Ingram
12th January 2005, 14:43
Originally posted by kingmob
Well, i could be wrong, but i think TMPGEnc defaults to deinterlacing, so that would figure...
Defauts yet, my settings were to keep it interlaced.
For now im sticking with simply having
0=Crop(4,4,-4,-4)
1=AddBorders(4,4,4,4)
for my widescreen stuff. I may run into trouble when I wish to do HD stuff. At the moment its only SD, DVD resolution.
When I do go to do a 1080i capture, it will require resizing. Do I just put back the
0=WhateverResize(^TargetWidth,^TargetHeight) and it will resize or will dvd2svcd simply resize it for me without needing to add any code.
IanB
12th January 2005, 17:35
Originally posted by scharfis_brain
@IanB:
This method of resizing should NOT be used. It destroys static detail and introduces a vertical misalignment between both fields.
Granted, it does vertically misalign the fields by an amount proportional the change in height. The change in height here is very small 572/576, which gives a misalignment of 0.0034965 pixels (or if 568/576, 0.007 pixels), so I offered the cheap solution. My Bad. :o
The output misalignment is given by (OldHeight/NewHeight-1)*0.5*(NewHeight/OldHeight). Which for the common interlaced resizes 576/480, misalinment is 0.08333 pixels and for 480/576 is -0.1 pixels. With a carefully crafted static test pattern these are discernable (just).
The exact way to resize interlaced stuff is this:-
Global NewHeight=1234 # Whatever
Global NewWidth=1234 # Whatever else
avisource("blah.avi")
AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25 # Field shift correction
Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()
(This is how Bob() does it's magic, so if you use dumb Bob(), the code above is exactly what you are geting)
However if you use a good smart bob with Mug Funky's method improvements in image quality can be quite substantial.
IanB
scharfis_brain
12th January 2005, 17:58
Wow.
Thanks for point that out.
offtopic example: When doing interlaced HDTV<->SDTV down- or upsizes the vertical misalignement is clearly visible.
But with resizing ranges within 20% it won't be visible too much.
Do the resizers really accept float values for their cropping paramters?
Is it possible to abuse a resizer as a subpixel image shifter using float cropping?
(I see new possibilities :) )
btw. I also mentioned in the comment after bob(), that a motionadaptive deinterlacer will work much better with my method, than the dumb bob().
I used it here only to show the method in general.
I am always using this method, cause it seems to be fool-proof to me. no more thoughts about fields.
just progressive filtering (resize, noise etc)
the viking
12th January 2005, 21:47
scharfis_brain posted this script:
avisource("blah.avi")
assume?ff() #set the video's fieldorder correctly
bob() #better use an adaptive bobber like tdeint(mode=1) here
crop(blah)
lanczos(blah)
addborders(blah)
otherfiltersyoulike()
assume?ff() #set the fieldorder again
separatefields().selectevery(4,0,3).weave() #reinterlaced
Almost the same as I use,only one thing that dont work
well here(at least for me):
If I use the last Assume?ff line here,I change the fieldorder
for my video.
So is it nessesary to include it?(stupid question maybe)
This script reports TFF: ( Correct)
AVISource("D:\onemovie\one.avi",pixel_type="YUY2")
AssumeTFF()
bob(0,0.5)
#Cnr2()
#RemoveGrain(mode=2)
#TemporalSoften(2,4,5,15,2)
LanczosResize(688,544,6,4,756,560)
AddBorders(8,16,8,16)
SeparateFields()
SelectEvery(4,1,2)
Weave()
Info()
This one reports BFF: ( Wrong)
AVISource("D:\onemovie\one.avi",pixel_type="YUY2")
AssumeTFF()
bob(0,0.5)
#Cnr2()
#RemoveGrain(mode=2)
#TemporalSoften(2,4,5,15,2)
LanczosResize(688,544,6,4,756,560)
AddBorders(8,16,8,16)
AssumeTFF()
SeparateFields()
SelectEvery(4,1,2)
Weave()
Info()
scharfis_brain
12th January 2005, 21:55
1) assume?ff(): ? is meant to be replaced with either T or B
2) selectevery(4,0,3) leaves the fieldorder untouched, IF the correct fieldorder had been set up correctly before.
selectevery(4,1,2) reverses the fieldorder.
so, in your script there is no assumetff() and then selectevery(4,1,2).
this is going on:
bob gets TFF-flagged video and bob-deinterlaces it.
but bob() is stupid. it internally always resets the fieldorder to BFF no matter what it was before.
that's why I recommend using assume?ff() twice.
one before bob-deinterlacing
and the 2nd one before re-interlacing.
the viking
12th January 2005, 22:21
1)Yes,I know
2)I was mixing two methods to do the same thing:
a)
AVISource("D:\CAPTURED\Video 1.avi",pixel_type="YUY2")
AssumeTFF()
bob(0,0.5)
#Cnr2()
#RemoveGrain(mode=2)
#TemporalSoften(2,4,5,15,2)
LanczosResize(688,544,6,4,756,560)
AddBorders(8,16,8,16)
#ConvertToRGB24() # For TMPGEnc or VFAPI
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()
Info()
.....give the same fieldorder as...
b)
AVISource("D:\CAPTURED\Video 1.avi",pixel_type="YUY2")
AssumeTFF()
bob(0,0.5)
#Cnr2()
#RemoveGrain(mode=2)
#TemporalSoften(2,4,5,15,2)
LanczosResize(688,544,6,4,756,560)
AddBorders(8,16,8,16)
#ConvertToRGB24() # For TMPGEnc or VFAPI
SeparateFields()
SelectEvery(4,1,2)
Weave()
Info()
scharfis_brain
12th January 2005, 22:49
a) is more fool proof.
- just setup the initial fieldorder twice
- be happy
b) needs modifications on the selectevery-line
- setup the correct fieldorder once
- crack your brain about either 4,0,3 or 4,1,2
the viking
12th January 2005, 23:00
a)I agree
b)
scharfis_brain wrote:
- crack your brain about either 4,0,3 or 4,1,2
4,1,2 =TFF
4,0,3 =BFF...
:)
scharfis_brain
12th January 2005, 23:07
b) is only right, if previously BFF has been signalled!
(bob() always does this!)
but what about, if you rapidly decide to switch over to another deinterlacer, that handles the fieldorder signalling correctly? you'll get a reversed fieldorder!
if TFF had been signalled:
4,0,3 -> TFF
4,1,2 -> BFF
if BFF had been signalled:
4,0,3 -> BFF
4,1,2 -> TFF
as you can see: 4,0,3 changes nothing while 4,1,2 reverses the fieldorder.
btw.: some time ago, I trapped into this, too.
Its cost had been several lost and greyed hairs....
the viking
12th January 2005, 23:41
yep,your right,
its easier to keep things under control that way.
As far as I remember, Kernelbob() swap the fieldorder
different than Bob().I forgot how.(long time since ive used it)
:)
IanB
13th January 2005, 06:41
Originally posted by scharfis_brain
offtopic example: When doing interlaced HDTV<->SDTV down- or upsizes the vertical misalignement is clearly visible.Oh yeah, 576->1080, -0.4375 pixels and 1080->576, 0.233 pixels. Both well into the very noticable range. :eek: But with resizing ranges within 20% it won't be visible too much.Yes 20% is around the 0.1 pixels offset which is where jaggies become annoying. Field offsets of about 0.07 pixels is about my limit, a lot depends on the image size and amount of motion. ;)
Do the resizers really accept float values for their cropping paramters?
Is it possible to abuse a resizer as a subpixel image shifter using float cropping?
(I see new possibilities :) )Very much so. It is no abuse, it is exactly what the float offset paramaters of the resizers are for. You may have notice the "-shift" offset would run off the edge of the picture, this is acceptable upto 1 pixel on all edges. :D
btw. I also mentioned in the comment after bob(), that a motionadaptive deinterlacer will work much better with my method, than the dumb bob().
I used it here only to show the method in general.
I am always using this method, cause it seems to be fool-proof to me. no more thoughts about fields. just progressive filtering (resize, noise etc)
Always the KISS approach. No arguments here. Yes dumb Bob() is really, really awful.
However if speed is a necessity it pays to know how to play interlaced correctly (and where to cheat :p ), good smart bobbing is always going to take a little time. Verbs like SeparateFields(), Select(Every, Even, Odd), Interleave() have no processing cost, and Weave() costs only a blit. :cool:
IanB
Didée
11th December 2006, 14:10
Old thread, but still:
IanB, to me it seems that something is wrong there:
The output misalignment is given by (OldHeight/NewHeight-1)*0.5*(NewHeight/OldHeight).
[...]
The exact way to resize interlaced stuff is this:-
Global NewHeight=1234 # Whatever
Global NewWidth=1234 # Whatever else
avisource("blah.avi")
AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25 # Field shift correction
Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()
(This is how Bob() does it's magic, so if you use dumb Bob(), the code above is exactly what you are geting)
The formula is correct, but the script is *wrong*. The formula calculates the field offsets based on the height of the full frames. The script uses height as height(last), where (last) is the field separated source, not the full-height one ...
E.g. for the most simple case of no resizing at all, the script produces a field offset of zero. Which is not the expected result.
IanB
11th December 2006, 16:02
Opps, Yes, I beleive you are right, the shift= line should be before the SeparateFields()
I now do not believe this was wrong originally, see the post 2 down, dated 2nd January 2008, 10:46 ADST(+11)
Wilbert
1st January 2008, 17:42
I'm reading some old threads :)
I don't get it. I do understand that you get a vertical misalignment when resizing the fields separately. But i would expect that you should move the bottom field 0.5 pixel down (or crop -0.5 pixel), independently of the old and new height (leaving top field untouched).
But apparently my expectation is very wrong :confused:
IanB
2nd January 2008, 00:46
E.g. for the most simple case of no resizing at all, the script produces a field offset of zero. Which is not the expected result.Hmm, I think I may have missed the "not" in Didée post of a year ago.
I would at first thought expect exactly Shift=0 for no resizing.
Misalignment=(OldHeight/NewHeight-1)*0.5*(NewHeight/OldHeight)
gives 0 when OldHeight==NewHeight and
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
as expected also gives 0.
The other easy case is NewHeight = 2*OldHeight which gives
Shift = (0.5/(2/2)-1)*0.25 = -0.125
But i would expect that you should move the bottom field 0.5 pixel down (or crop -0.5 pixel), independently of the old and new height (leaving top field untouched).This would align the top and bottom fields as would be needed for a Bob() operation (which uses -0.25 and +0.25 into BicubicResize).
The overall operation must produce 2 new fields in correct relation to each other, effectively you need to do the "move the bottom field 0.5 pixel down (or crop -0.5 pixel)" on input then "move the bottom field 0.5 new pixel back up (uncrop -0.5 pixel)" on output.
As the resizers are "maintain the centre of the image" style and only provide input cropping, you need to back convert the output uncrop and include it with the input crop and then adjust both fields to compensate for the relative centres offset.
Wilbert
3rd January 2008, 21:43
This would align the top and bottom fields as would be needed for a Bob() operation (which uses -0.25 and +0.25 into BicubicResize).
The overall operation must produce 2 new fields in correct relation to each other, effectively you need to do the "move the bottom field 0.5 pixel down (or crop -0.5 pixel)" on input then "move the bottom field 0.5 new pixel back up (uncrop -0.5 pixel)" on output.
As the resizers are "maintain the centre of the image" style and only provide input cropping, you need to back convert the output uncrop and include it with the input crop and then adjust both fields to compensate for the relative centres offset.
Sorry, i still don't get the formulas.
Suppose you start with an interlaced 640x480 clip. You separate the fields (original offset of those fields are +/-0.25). You 2xdownscale the fields ending up with 640x120. Now you want to weave them again. For doing this correctly you also need an offset of +/-0.25 (the output uncrop). However the original offset changed because of the downscaling. Correct so far?
So the output uncrop always needs to be 0.25 (for the bottom field), and you need the include this into the input crop. It seems to me that the new input crop should be 0.25*240/120 = 0.5, which consists of the old input crop (0.25) and a correction (0.25*[240/120 - 1] = 0.25).
But if i use your formula i get:
shift = (Height()/Float(NewHeight/2) - 1.0)*0.25 = (480/(240/2) - 1)*0.25 = 0.75
Shouldn't it be (Height()/2 / Float(NewHeight/2) - 1.0)*0.25 ?
IanB
4th January 2008, 06:16
@Wilbert, Note:-...
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
shift = (240/(240/2) - 1)*0.25 = 0.25
Shouldn't it be (Height()/2 / Float(NewHeight/2) - 1.0)*0.25 ?Yes if you mean OriginalHeight for Height() it will be (OriginalHeight/2 / Float(NewHeight/2) - 1.0)*0.25
florinandrei
1st July 2008, 04:44
As the resizers are "maintain the centre of the image" style and only provide input cropping, you need to back convert the output uncrop and include it with the input crop and then adjust both fields to compensate for the relative centres offset.
I understand why this needs to be done, I just can't apply the knowledge to my script. I'm a newbie.
I'm converting 1080i TFF (AVCHD) to 480i (DVD). The final step is conversion to MPEG2, for which I use HC Encoder directly from AviSynth.
With the script below, the result looks good, but I think there might be some more tweaking required: oblique objects moving vertically seem to "vibrate" a tiny little bit, which might indicate field misalignment.
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\LeakKernelDeint.dll")
DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
LeakKernelBob(order=1)
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()
ConvertToYV12()
So how do I modify the script above to re-align the fields?
I am trying to do the conversion while preserving the best image quality: fluid motion, crisp images, no artifacts due to processing.
@florinandrei,
As you have observed Bobbing is never exact, it always involves some tradeoffs. Take a read thru this thread "exist any filter specially done for (deinterlace) flicker" for some ideas to reduce any residual flicker.
Also strictly speaking you probably wanted ConvertToYV12(Interlaced=True) at the end of your script.
Arguable the Convertion to YV12 might be better done after the Resize while things are still progressive. Interlaced YV12 is a real can of worms. The other approach might be to output YUY2 and let your encode worry about the interlaced chroma positioning. Also you might want to check what your DirectShow environment is doing with the data, it may be doing some form of 4:2:0 to YUY2 conversion that is suboptimal.
And you probably would have been better to keep this discussion in your original thread rather than dividing the focus.
jeffy
1st July 2008, 12:59
@IabB: Could you please tell us, is this code right?
Global NewHeight=1234 # Whatever
Global NewWidth=1234 # Whatever else
avisource("blah.avi")
AssumeTFF()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25 # Field shift correction
SeparateFields()
Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()
Based on this correction: http://forum.doom9.org/showthread.php?p=915260#post915260
Thank you.
@jeffy,
No it fails the trivial case test. Shift should be 0 for Height==NewHeight. This implementation give 0.25=(480/(480/2)-1)*0.25
Both of these are correctShift=(Height()/Float(NewHeight)-1.0)*0.25 # Field shift correction
SeparateFields()Note the required /2 to compensate for Height() being half after a SeparateFIelds()SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25 # Field shift correctionThis 2nd implementation is what I endeavour to use in all post.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.