martin53
7th April 2017, 21:18
From time to time, you may come across interlaced footage that was vertically scaled without having been deinterlaced before - ouch!
Such footage will show alternating interlaced and blended horizontal streaks, with continuous transitions. Traditional deinterlacing did not give me good results and I always wondered if this could be fixed with AviSynth.
I like brute force blending best as a starting point, since the original fields vary between odd and even lines over the frame. Instead of e.g. taking half of the pixel's original value and half of the pixel below, object position is best retained by taking half of the center pixel, and a quarter each of the upper and lower neighbors.
This seems to produce evenly blended frames but of course it deteriorates vertical sharpness.
It would be desirable to only blend pixels in combed regions. Fortunately, we have mt_lutxyz: prepare two helper videos, one with the content shifted up by one line, the other shifted downward by one line, and feed them together with the original clip to mt_lutxyz: Voilą, we can design an expression with the center pixel and its vertical neighbors.
The expression in the example checks if both neighbors are either both darker or both brighter than the center pixel by at least a threshold, and if so, the center pixel is blended, otherwise it is used unchanged.
(Note: Cnv2() and StrResolve() were published in the forum before. Script was developed and checked with AviSynth+ and up to date pinterf masktools version)
# add your source filter here
Cnv2("YUV") #you can use this ensure YUV pixel type for masktools, omit it for already planar YUV input, or convert with core filters
v = last
v8 = v.ConvertToY8()
vUp = v8.Overlay(v8,y=1).Overlay(v8,y=-1) # using two overlay commands, top line is 2nd line of original, 3rd line too: top line of original can be blended properly
vDn = v8.Overlay(v8,y=-1).Overlay(v8,y=1)
thr = 3
expr = """
(y < (x - $thr) & z < (x - $thr)) # if both pixel above and pixel below center pixel are darker than center pixel by thr increments
| (y > (x + $thr) & z > (x + $thr)) # or if both of them are brighter than center pixel ...
? 0.25 * (x + x + y + z) # then blend: 0.5 * center pixel + 0.25 * upper neighor + 0.25 * bottom neighbor
: x # otherwise return center pixel as is
""".StrResolve.mt_polish
mt_lutxyz(v, vUp, vDn, expr=expr, chroma="copy")
EDIT after reading the thread johnmeyer pointed out in the following post
The damage done by operations such as vertical resize on interlaced clips can be very different. The above, quite simple operation does just blend the lines that are not yet blended. If some interpolating vertical resize (in contrast to pointresize) had been done before, the result will hopefully, yes, look blended but smooth. very rapid brightness change like flashes will probably not be recovered well. And if the vertical resizer was of a pointresize nature, with distinct borders between the streaks, the above approach is useless.
As for frames with flash issues, I typically use and suggest a runtime filter that compares average brightness of e.g. three frames and replaces a center frame with significantly higher brightness than the other two by one ore a blend of them. This kinda censors out flashes but the clip afterwards looks neat.
Such footage will show alternating interlaced and blended horizontal streaks, with continuous transitions. Traditional deinterlacing did not give me good results and I always wondered if this could be fixed with AviSynth.
I like brute force blending best as a starting point, since the original fields vary between odd and even lines over the frame. Instead of e.g. taking half of the pixel's original value and half of the pixel below, object position is best retained by taking half of the center pixel, and a quarter each of the upper and lower neighbors.
This seems to produce evenly blended frames but of course it deteriorates vertical sharpness.
It would be desirable to only blend pixels in combed regions. Fortunately, we have mt_lutxyz: prepare two helper videos, one with the content shifted up by one line, the other shifted downward by one line, and feed them together with the original clip to mt_lutxyz: Voilą, we can design an expression with the center pixel and its vertical neighbors.
The expression in the example checks if both neighbors are either both darker or both brighter than the center pixel by at least a threshold, and if so, the center pixel is blended, otherwise it is used unchanged.
(Note: Cnv2() and StrResolve() were published in the forum before. Script was developed and checked with AviSynth+ and up to date pinterf masktools version)
# add your source filter here
Cnv2("YUV") #you can use this ensure YUV pixel type for masktools, omit it for already planar YUV input, or convert with core filters
v = last
v8 = v.ConvertToY8()
vUp = v8.Overlay(v8,y=1).Overlay(v8,y=-1) # using two overlay commands, top line is 2nd line of original, 3rd line too: top line of original can be blended properly
vDn = v8.Overlay(v8,y=-1).Overlay(v8,y=1)
thr = 3
expr = """
(y < (x - $thr) & z < (x - $thr)) # if both pixel above and pixel below center pixel are darker than center pixel by thr increments
| (y > (x + $thr) & z > (x + $thr)) # or if both of them are brighter than center pixel ...
? 0.25 * (x + x + y + z) # then blend: 0.5 * center pixel + 0.25 * upper neighor + 0.25 * bottom neighbor
: x # otherwise return center pixel as is
""".StrResolve.mt_polish
mt_lutxyz(v, vUp, vDn, expr=expr, chroma="copy")
EDIT after reading the thread johnmeyer pointed out in the following post
The damage done by operations such as vertical resize on interlaced clips can be very different. The above, quite simple operation does just blend the lines that are not yet blended. If some interpolating vertical resize (in contrast to pointresize) had been done before, the result will hopefully, yes, look blended but smooth. very rapid brightness change like flashes will probably not be recovered well. And if the vertical resizer was of a pointresize nature, with distinct borders between the streaks, the above approach is useless.
As for frames with flash issues, I typically use and suggest a runtime filter that compares average brightness of e.g. three frames and replaces a center frame with significantly higher brightness than the other two by one ore a blend of them. This kinda censors out flashes but the clip afterwards looks neat.