Hello guest, if you like this forum, why don't you register? https://fanrestore.com/member.php?action=register (December 14, 2021) x


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
AviSynth DeSub - automatic hardcoded subtitles removal
#1
DeSub - automatic hardcoded subtitles removal (Avisynth script)

Is it too good to be true? Well, it needs two clips, one with subtitles (or logo), and the other without; will create a mask "on the fly", and the subtitles (logo) will be replaced with the corresponding part of the image of the clip without logo.

For best result, it's better to limit usage only to frames with subtitles; clips must be aligned perfectly, both temporally and spatially; must have the same (or very similar) colors; it's always possible to merge the result and the existing not subbed clip to improve quality.

Include it into your avisynth script or save it as DeSub.avsi and put into your AviSynth plugins folder.

EDIT: WARNING! IT WORKS ONLY WITH WHITE SUBTITLES!!!

Code:
###########################################################################################
### DeSub 1.0: removes the subtitles with no need to prepare a mask for every line!     ###
###                                                                                     ###
### Two spatially and aligned clips are needed, one with hardcoded subtitles, or logo,  ###
### and the other without; the script creates a mask "on the fly" that will be used to  ###
### cover the subtitles with the corresponding parts of the clip without them.          ###
###                                                                                     ###
### Usage:   DeSub(clipwithoutsubs,clipwithsubs,subcolor)                               ###
###                                                                                     ###
### Example: goodclip.avi has subtitles, badclip.avi has no subtitles, subs color white ###
###                                                                                     ###
###          DeSub(goodclip,badclip,$ffffff)                                            ###
###                                                                                     ###
### It is highly reccomended to use it only on frames with subtitles                    ###
### Possible update: limit the use to a certain area of the frame, perfect for logo!    ###
###                                                                                     ###
### AviSynth script made by spoRv (http://blog.sporv.com) - Created: 2016-11-29         ###
###                                                                                     ###
### Creative Commons 4,0 - Attribution-NonCommercial-ShareAlike 4.0 (CC BY-NC-SA 4.0)   ###
### Link to the licence page: https://creativecommons.org/licenses/by-nc-sa/4.0         ###
###########################################################################################

function DeSub (clip nosubs, clip withsubs, val "color") {

withsubs=withsubs.converttoyv24
nosubs=nosubs.converttoyv24
color=default(color,$ffffff)

subs = withsubs.converttorgb

mask = ColorKeyMask(subs, color, 20)
blk = blankclip(length=withsubs.FrameCount,width=withsubs.width,height=withsubs.height)

over=Overlay(withsubs, blk, mask=mask.ShowAlpha, mode="blend", opacity=1)

mk=over.levels(235,1,255,1,255)

w=2

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=3

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=4

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add").levels(235,1,255,1,255)

numask = ColorKeyMask(nu.ConvertToRGB32, color, 30)

Overlay(nosubs, withsubs, mask=numask.ShowAlpha, mode="blend", opacity=1)

converttoyv12

}

I tested it, and seems to work well; of course, could still be improved. Waiting for your test results and impressions!

Examples - top DeSub result, bottom original:

[Image: desub2.jpg]

[Image: desub4.jpg]

[Image: desub3.jpg]

[Image: desub1.jpg]
Reply
Thanks given by:
#2
Hi spoRv,

With my current project I have two sources. The HD version with embedded subs (because I am not able to buy the version without subs), and a DVD of the same version with no subs.

Assuming I can get the sources to align I'd like to use the DVD version to mask the subs of the HD version. I'm curious if there is a preferred upscaler that you'd recommend? The DVD is NTSC so I believe it should be 720x480 (I can confirm this tomorrow).

Keep in mind I'm still struggling to get to grips with Avisynth, but I'm more than happy to try.
Reply
Thanks given by:
#3
Using Avisynth, best upscalers are (in order of MY preference): AIupscale, NNEDI3, spline36resize or spline64resize.

The biggest problem is to properly align DVD when upscaled to HD (using whichever technique); I mean, it should not be only pixel-perfect, but also subpixel-perfect! Eek

When you have solved that problem, the following passages would be like a walk in the park! Wink
Reply
Thanks given by:
#4
Thanks, spoRv!

I'll test AIupscale. I did have a go at using NNEDI3 but something must have gone wrong in the settings.
Reply
Thanks given by:
#5
Hi again spoRv,

How should the script look when I have everything lined up? I tried to run a test through virtualdub and it suggested that there was no video stream. I've got a HD source and I'd ideally like to use the SD source to mask over the subs.

Happy to provide as much information as necessary.

Thanks!
Reply
Thanks given by:
#6
Post your avisynth script inside |CODE|
Reply
Thanks given by:
#7
Code:
function DeSub (clip withsubs, clip nosubs, val "color") {

withsubs="F:\Desktop\Projects\new\ivtc.mkv".converttoyv24
nosubs="F:\Desktop\Projects\new\ivtc.mkv"".converttoyv24
color=default(color,$ffffff)

subs = withsubs.converttorgb

mask = ColorKeyMask(subs, color, 20)
blk = blankclip(length=withsubs.FrameCount,width=withsubs.width,height=withsubs.height)

over=Overlay(withsubs, blk, mask=mask.ShowAlpha, mode="blend", opacity=1)

mk=over.levels(235,1,255,1,255)

w=2

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=3

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=4

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add").levels(235,1,255,1,255)

numask = ColorKeyMask(nu.ConvertToRGB32, color, 30)

Overlay(nosubs, withsubs, mask=numask.ShowAlpha, mode="blend", opacity=1)

converttoyv12

}

Thanks for taking a look at it!
Reply
Thanks given by:
#8
Let's pretend my own script is working... you need two different clips, one with subs, one without (you posted the same!)

Code:
# filenames should reflect the actual ones! ;)

withosubs=ffvideosource("F:\Desktop\Projects\old\sd.mkv")
nosubs   =ffvideosource("F:\Desktop\Projects\old\hd.mkv")

desub(withsubs,nosubs)

function DeSub (clip withsubs, clip nosubs, val "color") {

withsubs=withsubs.converttoyv24
nosubs=nosubs.converttoyv24
color=default(color,$ffffff)

subs = withsubs.converttorgb

mask = ColorKeyMask(subs, color, 20)
blk = blankclip(length=withsubs.FrameCount,width=withsubs.width,height=withsubs.height)

over=Overlay(withsubs, blk, mask=mask.ShowAlpha, mode="blend", opacity=1)

mk=over.levels(235,1,255,1,255)

w=2

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=3

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=4

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add").levels(235,1,255,1,255)

numask = ColorKeyMask(nu.ConvertToRGB32, color, 30)

Overlay(nosubs, withsubs, mask=numask.ShowAlpha, mode="blend", opacity=1)

converttoyv12

}
Reply
Thanks given by:
#9
Oops. The filenames were quite close, but they were different clips when I tried to run it  Smile

Still getting the 'does not have a video stream' error. Might it be an error in the filenames/folders?

Thanks!

Code:
withsubs=ffvideosource("F:\Desktop\Projects\old\ivtc.mkv")
nosubs=ffvideosource("F:\Desktop\Projects\old\towanew.mkv")

desub(withsubs,nosubs)

function DeSub (clip withsubs, clip nosubs, val "color") {

withsubs=withsubs.converttoyv24
nosubs=nosubs.converttoyv24
color=default(color,$ffffff)

subs = withsubs.converttorgb

mask = ColorKeyMask(subs, color, 20)
blk = blankclip(length=withsubs.FrameCount,width=withsubs.width,height=withsubs.height)

over=Overlay(withsubs, blk, mask=mask.ShowAlpha, mode="blend", opacity=1)

mk=over.levels(235,1,255,1,255)

w=2

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=3

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add")

mk=nu.levels(235,1,255,1,255)

w=4

a=mk.addborders(0,0,w,w).crop(w,w,0,0)
b=mk.addborders(0,0,0,w).crop(0,w,0,0)
c=mk.addborders(w,0,0,w).crop(0,w,-w,0)
d=mk.addborders(w,0,0,0).crop(0,0,-w,0)
e=mk.addborders(w,w,0,0).crop(0,0,-w,-w)
f=mk.addborders(0,w,0,0).crop(0,0,0,-w)
g=mk.addborders(0,w,w,0).crop(w,0,0,-w)
h=mk.crop(w,0,0,0).addborders(0,0,w,0)

x= overlay(b, f, mode="add")
y= overlay(d, h, mode="add")
xx=overlay(a, e, mode="add")
yy=overlay(c, g, mode="add")
z= overlay(x, y, mode="add")
zz=overlay(xx,yy,mode="add")

nu=overlay(z,zz,mode="add").levels(235,1,255,1,255)

numask = ColorKeyMask(nu.ConvertToRGB32, color, 30)

Overlay(nosubs, withsubs, mask=numask.ShowAlpha, mode="blend", opacity=1)

converttoyv12

}
Reply
Thanks given by:
#10
Try to load each clip on its own; make a new .avs file with

Code:
ffvideosource("F:\Desktop\Projects\old\ivtc.mkv")

and then another with

Code:
ffvideosource("F:\Desktop\Projects\old\towanew.mkv")
Reply
Thanks given by:


Forum Jump:


Users browsing this thread: 6 Guest(s)