Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 28th July 2021, 12:53   #141  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,153
This link deprived SSTV and SSTV+
kedautinh12 is offline   Reply With Quote
Old 28th July 2021, 22:58   #142  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
Database can be build for InpaintDelogo too, here are the logo deblending masks for Arsenal VODs:


Arsenal (not perfect analysis, but it's pretty good)

Example how filename corresponds to settings:
Filename - "arsenal_4-3.bmp_InpaintDelogo_1500-56-334-936_A3_1-2-3.ebmp".
Notice naming rule - "Basemask_InpaintDelogo_Loc coordinates_Analyze_FrB-FrW-FrS".
If InpaintDelogo finds ebmp file corresponding to the settings then it won't do analyze/generate the masks, it would just use the masks from that file.

This command would find the logo deblending masks named as the example above:
InpaintDelogo( mask="D:\arsenal_4-3.bmp", Loc="1500,56,-334,-936", Mode="Deblend", Analyze=3, FrB=1, FrW=2, FrS=3, Deep=0)
VoodooFX is offline   Reply With Quote
Old 14th August 2021, 02:52   #143  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
New v1.30, tuned to remove subtitles.
Relevant thread: https://forum.doom9.org/showthread.php?p=1949702

To remove subtitles in this case used:
InpaintDelogo(Loc="50,600,-50,-14", DynMask=3, DynTune=-4, DynInflate=4, Dyn3Seq=13, ClpBlend=11, Show=5)

Before:


After:
VoodooFX is offline   Reply With Quote
Old 14th August 2021, 16:18   #144  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Thats quite amazing VX,
is it necessary for InPaintDeLogo call for each and every text sub, yes ?

Or can you just supply a mask same len as whole clip with detected logo in 'fine red' [255,0,0],
or can you also supply in planar Y channel, and as same size as input frame, or as entire subs
target locate area, where all subs live over entire clip.
[cant remember how InpaintDelogo works]
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 14th August 2021, 19:56   #145  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,691
That is a pretty amazing result.
johnmeyer is offline   Reply With Quote
Old 15th August 2021, 03:30   #146  |  Link
GMJCZP
Registered User
 
GMJCZP's Avatar
 
Join Date: Apr 2010
Location: I have a statue in Hakodate, Japan
Posts: 744
It is simply amazing!

VoodooFX has lived up to its name to "killing" subtitles, awesome! If I had this tool at my fingertips a few years ago I wouldn't have had to place a solid box on hardsubs of some series that I translated.

Is there a tutorial to apply this?

Edit: The jewel in the crown would be to extract these subtitles to an SRT file.
__________________
By law and justice!

GMJCZP's Arsenal

Last edited by GMJCZP; 15th August 2021 at 03:39.
GMJCZP is offline   Reply With Quote
Old 15th August 2021, 08:48   #147  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
Quote:
Originally Posted by GMJCZP View Post
It is simply amazing!

VoodooFX has lived up to its name to "killing" subtitles, awesome! If I had this tool at my fingertips a few years ago I wouldn't have had to place a solid box on hardsubs of some series that I translated.
Actually it's not good on sources like this anime, because video is too static, levels are above TV range, fansubs don't follow standards like minimum 1 second duration nor minimum 1 frame between subs... and I don't see point in bothering with them, better to join fansubs community and get unsubbed source there.

StainlessS' "DetectSub_MI" method should be much better for this case (but script is not finished for the end use).

You could use ssa subtitles, there is option to add soft black box.

Quote:
Originally Posted by GMJCZP View Post
Is there a tutorial to apply this?
There is help about parameters in the script.

Quote:
Originally Posted by GMJCZP View Post
The jewel in the crown would be to extract these subtitles to an SRT file.
This is what I'm mostly interested in, and it greatly helped in the process to convert hardsubs to softsubs, maybe one day I'll write tutorial how to do it.

Last edited by VoodooFX; 15th August 2021 at 14:35.
VoodooFX is offline   Reply With Quote
Old 15th August 2021, 09:19   #148  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
Quote:
Originally Posted by StainlessS View Post
Thats quite amazing VX,
is it necessary for InPaintDeLogo call for each and every text sub, yes ?

Or can you just supply a mask same len as whole clip with detected logo in 'fine red' [255,0,0],
or can you also supply in planar Y channel, and as same size as input frame, or as entire subs
target locate area, where all subs live over entire clip.
[cant remember how InpaintDelogo works]
No, you can supply whole mask clip (B/W), full range YV12 is expected, I think "mask=maskClip" should do it, resolution must be same as "Loc" area/setting (it can be full frame).
What you want to do?

Btw, I'm interested in detection method you done in "DetectSub_MI", would it be possible to detect subs in a mask and extract them to images? One image per sub with time range in the filename, for example like "0_00_56_958__0_00_57_957.tiff".
VoodooFX is offline   Reply With Quote
Old 15th August 2021, 15:03   #149  |  Link
GMJCZP
Registered User
 
GMJCZP's Avatar
 
Join Date: Apr 2010
Location: I have a statue in Hakodate, Japan
Posts: 744
Quote:
Originally Posted by VoodooFX View Post
Actually it's not good on sources like this anime, because video is too static, levels are above TV range, fansubs don't follow standards like minimum 1 second duration nor minimum 1 frame between subs... and I don't see point in bothering with them, better to join fansubs community and get unsubbed source there.

StainlessS' "DetectSub_MI" method should be much better for this case (but script is not finished for the end use).

You could use ssa subtitles, there is option to add soft black box.


There is help about parameters in the script.


This is what I'm mostly interested in, and it greatly helped in the process to convert hardsubs to softsubs, maybe one day I'll write tutorial how to do it.
Thanks for your answers.

In regards to extracting hardsubs here are some links:

https://www.videoconverterfactory.co...subtitles.html

http://redonesubs.blogspot.com/p/ext...dsubs.html?m=1

Long ago I used Subrip but the time to teach the program is somewhat high.
__________________
By law and justice!

GMJCZP's Arsenal
GMJCZP is offline   Reply With Quote
Old 15th August 2021, 16:06   #150  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
No, you can supply whole mask clip (B/W), full range YV12 is expected, I think "mask=maskClip" should do it, resolution must be same as "Loc" area/setting (it can be full frame).
Thanks.
Quote:
What you want to do?
Dont know, just wantin' to know what is required at the moment.

Quote:
I'm interested in detection method you done in "DetectSub_MI",
From here [about an earlier version of the script, but mostly same] :- https://forum.doom9.org/showthread.p...25#post1780125
Quote:
Originally Posted by StainlessS View Post
The script basically extracts from RGB color value eg $FEFEFE, the individual R,G,B components of both Text and Halo, then calculates the range limits for
each channel using CHANVAR (just saves user from specifying min and max for each color channel individually for both text and halo).
The ShowRed, etc lines isolate pixels that fall within the acceptable ranges for all 3 channels for text, and then AND's them together so result is pixels where all 3 channels are in acceptable range. Same is then done for HALO.

The for next loop, Expands (swells) the text [edit: by halo HALO_W,HALO_H] so as to swell into the halo region (both horizontally and vertically), and then expands the halo to swell into the text region [edit: by TEXT_W,TEXT_H]. (These are two swelled frames shown in diagnostic as TEXT and HALO frames).
Finally, the expanded/swelled frames are AND'ed together for the diagnostic shown DETECT frame.
This detect frame therefore contains white pixels where text/halo were valid colors, and because of the AND'ed swellings, it also shows where both
text and halo swelled 'into' each other ie where they were adjacent to each other (allows to ignore randomly positioned pixels which just happen to be the
sort after colors).

The FindSub routine just checks the scan area using RT_YInRangeLocate() to see if there is a suspect area of white(good) pixels of sufficient 'bulk'.
Quote:
would it be possible to detect subs in a mask and extract them to images? One image per sub with time range in the filename, for example like "0_00_56_958__0_00_57_957.tiff".
thinkin' bout it.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 17th August 2021, 05:58   #151  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
Quote:
Originally Posted by StainlessS View Post
...Finally, the expanded/swelled frames are AND'ed together for the diagnostic shown DETECT frame.
This detect frame therefore contains white pixels where text/halo were valid colors, and because of the AND'ed swellings, it also shows where both
text and halo swelled 'into' each other ie where they were adjacent to each other (allows to ignore randomly positioned pixels which just happen to be the
sort after colors).

The FindSub routine just checks the scan area using RT_YInRangeLocate() to see if there is a suspect area of white(good) pixels of sufficient 'bulk'.
Are you going to finish it? I think DETECT frames expanded ~3-5 times should be good as a final mask to remove subs in this case (where there is a clear outline around subs), probably such mask wouldn't look good if outline is only at right/bottom or outline is thin.
There could be potential of somehow merging DynMask=3 method from InpaintDelogo with DetectSub_MI's DETECT'ed area cords/range.


Quote:
Originally Posted by StainlessS View Post
thinkin' bout it.
That would be great, I could provide samples for tests if needed.
VoodooFX is offline   Reply With Quote
Old 17th August 2021, 14:58   #152  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Are you going to finish it?
Hope so, however bit pushed for time.

Here what I've done so far, [this is really for testing purposes], not sure I've dont it correctly.

Code:
###
# DSub_MI, Based on DetectSub.MI.avsi":- https://forum.doom9.org/showthread.php?p=1782036#post1782036
###
# req RT_Stats v2.00 Beta 02, GScript, Grunt, CallCmd, MaskTools v2.0.
# RT_Stats v2.00 Beta2 first posted here:- http://forum.doom9.org/showthread.php?p=1782028#post1782028
#
###

Function Hit_Marker(int W, Int H, Bool "Hit", Int "BW", Int "BH",Int "PW",Int "PH",Bool "YV12",Bool "Mod2") {
    Hit=Default(hit,False)                    BW=Max(Default(BW,W/8),1)   BH=Max(Default(BH,H/8),1)
    BW2=(W>4)?BW*2:BW                         BH2=(H>4)?BH*2:BH
    PW=Max(Default(PW,BW/8),1)                PH=Max(Default(PH,BH/8),1)  is26 = VersionNumber>=2.6
    YV12=(!is26) ? True : Default(YV12,False) Mod2=Default(Mod2,True)     Mod = (YV12||Mod2) ? 2 : 1
    CanvasW=(W+Mod-1)/Mod*Mod                 CanvasH=(H+Mod-1)/Mod*Mod
    Rpn= RT_String("x %d < x %d >= | y %d < | y %d >= | x %d < x %d >= | & y %d < y %d >= | & ",BW,W-BW,BH,H-BH,BW2,W-BW2,BH2,H-BH2)
    Rpn= (Hit) ? Rpn + RT_String("x %d < x %d >= | y %d < | y %d >= | | ",PW,W-PW,PH,H-PH) : Rpn
    Rpn= Rpn + RT_String("x %d < y %d < & & 255 0 ?",W,H)
    Blankclip(width=CanvasW,height=CanvasH,Length=1,pixel_type=YV12?"YV12":"Y8").Killaudio
    return mt_lutspa(relative = false,yExpr=Rpn, chroma = "-128")
}


Function ChrIsStar(String S)     {return RT_Ord(S)==42}
Function ChrIsNul(String S)      {return RT_Ord(S)== 0}                             # End of String
Function ChrIsHash(String S)     {return RT_Ord(S)==35}                             # #
Function ChrIsDigit(String S)    {C=RT_Ord(S) return C>=48&&C<=57}
Function ChrEatWhite(String S)   {i=1 C=RT_Ord(S,i) While(C==32||C>=8&&C<=13)       {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}
Function ChrEatDigits(String S)  {i=1 C=RT_Ord(S,i) While(C>=48&&C<=57)             {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}

Function CnvStr(clip c) {
    Return c.IsRGB24?"ConvertToRGB24":c.IsRGB32?"ConvertToRGB32":c.IsYUY2?"ConvertToYUY2":c.IsYV12?"ConvertToYV12"
     \ :c.IsYV16?"c.ConvertToYV16":c.IsYV24?"c.ConvertToYV24":c.IsY8?"c.ConvertToY8":""
}

Function DetSub_Override(string Override,string DB) {
    if(ChrIsStar(Override))  {OverRide=MidStr(OverRide,2)
    } else {
        Assert(Exist(OverRide),RT_String("%sOverRide File does not exist",myName))
        OverRide=RT_ReadTxtFromFile(Override)
    }
    LINES=RT_TxtQueryLines(OverRide)
    for(i=0,LINES-1) {
        SS=ChrEatWhite(RT_TxtGetLine(Override,i))
        S=SS
        if(!ChrIsNul(S) && !ChrIsHash(S)) {
            if(ChrIsDigit(S)) {
                StartF = RT_NumberValue(S)
                EndF=StartF
                S=ChrEatWhite(ChrEatDigits(S))
                if(ChrIsComma(S)){S=MidStr(S,2) S=ChrEatWhite(S)}
                if(ChrIsDigit(S)) {
                    EndF=RT_NumberValue(S)
                    S=ChrEatDigits(S)
                    if(EndF==0) { EndF=FrameCount-1}
                    Assert(StartF<=EndF,RT_String("%sError StartFrame(%d) > EndFrame(%d)",myName,StartF,EndF))
                }
                for(n=StartF,EndF) {RT_DBaseSetField(DB,n,0,3)}
            }
            S=ChrEatWhite(S)
            if(ChrIsHash(S)) {S=""}
            Assert(ChrIsNul(S),RT_String("%s *** NON-PARSE *** Error in Override Line %d\n'%s'",myName,i+1,SS))
        }
    }
    return 0
}


Function DetSub(clip c,string "Override",
        \ Int "X",Int "Y",Int "W",Int "H",
        \ Int "Text_w",Int "Text_h",Int "TextCol",Int "TextTol",
        \ Int "Halo_L",Int "Halo_T",Int "Halo_R",Int "Halo_B",Int "HaloCol",Int "HaloTol",
        \ Int "THysCNT",Int "HHysCNT",Int "DHysCNT",
        \ Int "Baffle_w",Int "Baffle_h",Float "Thresh_w",Float "Thresh_h",Bool "ReScan",
        \ String "DB") {
    myName="DetSub: "
    c
    IsPlus=FindStr(VersionString,"AviSynth+")!=0
    Assert(RT_FunctionExist("GScriptClip"),myName+"Essential GRunT plugin installed, http://forum.doom9.org/showthread.php?t=139337")
    Assert(IsPlus||RT_FunctionExist("GScript"),myName+"Essential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846")
    Assert(RT_FunctionExist("CallCmd"),myName+"Essential CallCmd plugin installed, http://forum.doom9.org/showthread.php?t=166063")
    Assert(RT_FunctionExist("mt_expand"),myName+"Essential MaskTools v2 plugin installed, http://forum.doom9.org/showthread.php?t=98985")
    Override=Default(OverRide,"")
    X=Default(X,10)                     Y=Default(Y,Height-120)         W=Default(W,-10)                    H=Default(H,-8)
    W=(W<=0)?Width-X+W:W                H=(H<=0)?Height-Y+H:H
    Text_w=Default(Text_w,3)            Text_h=Default(Text_h,3)
    TextCol=Default(TextCol,$FCFCFC)    TextTol=Default(TextTol,$030303)
    Halo_L=Default(Halo_L,3)            Halo_T=Default(Halo_T,4)        Halo_R=Default(Halo_R,5)            Halo_B=Default(Halo_B,6)
    HaloCol=Default(HaloCol,$030303)    HaloTol=Default(HaloTol,$030303)
    Text_Tol_B=BitAnd(TextTol,$FF)  TextTol=BitRShiftU(TextTol,8) Text_Tol_G=BitAnd(TextTol,$FF)  TextTol=BitRShiftU(TextTol,8)  Text_Tol_R=BitAnd(TextTol,$FF)
    Halo_Tol_B=BitAnd(HaloTol,$FF)  HaloTol=BitRShiftU(HaloTol,8) Halo_Tol_G=BitAnd(HaloTol,$FF)  TextTol=BitRShiftU(HaloTol,8)  Halo_Tol_R=BitAnd(HaloTol,$FF)
    THysCNT=Default(THysCNT,0)          HHysCNT=Default(HHysCNT,0)      DHysCNT=Default(DHysCNT,0)
    Baffle_w=Default(Baffle_w,0)        Baffle_h=Default(Baffle_h,0)
    Thresh_w=Default(Thresh_w,0.0)      Thresh_h=Default(Thresh_h,0.0)  ReScan=Default(ReScan,False)
    DB=Default(DB,"")    UserDB=(DB!="")
    DB=(!UserDB) ? "~"+RT_LocalTimeString+".DB" : DB
    DB=RT_GetFullPathName(DB)
    VW=Width VH=Height
    CNVS=CnvStr(c)
    Assert(CNVS!="",RT_String("%sRGB24, RGB32, YUY2, YV12, YV16, YV24,and Y8 Only",myName))
    /*  Fields
            0) Status,  0=Unknown (unvisited), 1=Sub, 2 Not sub, 3 User OverRide
            1) X
            2) Y
            3) W
            4) H
    */
    RT_DBaseAlloc(DB,FrameCount,"iiiii")
    RT_DBaseSetID(DB,0,c.FrameCount,c.FrameRate,VW,VH,X,Y,W,H)
    if(OverRide!="") {DetSet_Override(Override,DB)}

    LogoC=crop(0,Y,0,H)   # Full width logo area

    rgb=LogoC.ConvertToRGB32.Crop(X,0,W,0).ResetMask    # Valid Logo Area only, Reset Alpha to White
    TxtInRng=rgb.ColorKeyMask(TextCol,Text_Tol_R,Text_Tol_G,Text_Tol_B).ShowAlpha(Pixel_Type="Y8")   # Set TextCol in range pixels to black
    HalInRng=rgb.ColorKeyMask(HaloCol,Halo_Tol_R,Halo_Tol_G,Halo_Tol_B).ShowAlpha(Pixel_Type="Y8")   # Set HaloCol in range pixels to black
    TxtInRng=TxtInRng.Invert  # Text In-range pixels white, else black
    HalInRng=HalInRng.Invert  # Halo In-range pixels white, else black

    Text2 = TxtInRng
    # Swell Text by Halo thickness [Including Halo Drop Shadow]
    HALO_MAX=Max(HALO_L,HALO_T,HALO_R,HALO_B)
    for(i=1,HALO_MAX) {
        HorFlg=(i<=HALO_L?1:0)+(i<=HALO_R?2:0)    VerFlg=(i<=HALO_T?1:0)+(i<=HALO_B?2:0)
        if(HorFlg+VerFlg==6)     {Text2=Text2.Mt_Expand(mode="square")
        } else {
            if(HorFlg==3)        {Text2=Text2.Mt_Expand(mode="horizontal") HorFlg=0}
            if(VerFlg==3)        {Text2=Text2.Mt_Expand(mode="vertical") VerFlg=0}
            if(HorFlg!=0)        {Text2=Text2.Mt_Expand(mode=HorFlg==1? " 1  0  0  0" : " -1  0  0  0")}
            if(VerFlg!=0)        {Text2=Text2.Mt_Expand(mode=VerFlg==1? " 0  1  0  0" : "  0 -1  0  0")}
        }
    }

    Text3=Text2
    Text4=Text3
    # reduce Text strays a little
    if(THysCNT>0) {
        For(i=1,THysCNT) {Text3=Text3.MT_Inpand(mode="both")}
        Text4=Text3.MT_Hysteresis(Text2)
    }

    Halo2 = HalInRng
    # Swell Halo by Text thickness
    TEXT_MAX=Max(TEXT_W,TEXT_H)
    for(i=1,TEXT_MAX) {
        HorFlg=(i<=TEXT_W?1:0) VerFlg=(i<=TEXT_H?1:0)
        if(HorFlg+VerFlg==2)    {Halo2=Halo2.Mt_Expand(mode="square")
        } else {
            if(HorFlg!=0)       {Halo2=Halo2.Mt_Expand(mode="horizontal") }
            if(VerFlg!=0)       {Halo2=Halo2.Mt_Expand(mode="vertical") }
        }
    }

    Halo3=Halo2
    Halo4=Halo3
    # reduce Halo strays a little
    if(HHysCNT>0) {
        For(i=1,HHysCNT) {Halo3=Halo3.MT_Inpand(mode="both")}
        Halo4=Halo3.MT_Hysteresis(Halo2)
    }

    Det1=Mt_Logic(Text4,Halo4,"and")
    Det2=Det1
    Det3=Det2
    if(DHysCNT>0) {
        For(i=1,DHysCNT) {Det2=Det2.MT_Inpand(mode="both")}
        Det3=Det2.MT_Hysteresis(Det1)
    }
    SSS="""
        n = current_frame
        Status = RT_DBaseGetField(DB,n,0)
        if(Status==0) {                                                       # Unknown Status
            Status = (Det3.RT_YInRangeLocate(Baffle_w=Baffle_w,Baffle_h=Baffle_h,lo=255,hi=255,Thresh_w=Thresh_w,Thresh_h=Thresh_h,ReScan=ReScan)) ? 1 : 2
            if(Status==1)   { RT_DBaseSet(DB,n,Status,X+YIRL_X,Y+YIRL_Y,YIRL_W,YIRL_H) }
            else            { RT_DBaseSetField(DB,n,0,Status) }
        }
        if(Status==1) {
            SUB_X = RT_DBaseGetField(DB,n,1)    SUB_Y = RT_DBaseGetField(DB,n,2)
            SUB_W = RT_DBaseGetField(DB,n,3)    SUB_H = RT_DBaseGetField(DB,n,4)
            SUB_W=(SUB_W+1)/2*2 SUB_H=(SUB_H+1)/2*2
            OverLay(Last.BlankClip(color=$FF00FF,width=SUB_W,height=SUB_H),x=SUB_X,y=SUB_Y-Y,opacity=0.25)
        }
        Return Last
    """
    LogoC=LogoC.GScriptClip(SSS, local=true, args="Det3,DB,X,Y,W,H,Baffle_w,Baffle_h,Thresh_w,Thresh_h,ReScan")
    Mrk=LogoC.BlankClip(Length=1,Width=W,Height=H,Color=$FF00FF)
    Msk=Hit_Marker(W,H,True,8,8,1,1)
    LogoC=LogoC.Overlay(Mrk,Mask=Msk,x=X,y=0,Opacity=0.5)
    LogoC=LogoC.AddBorders(0,22,0,0,$F0F080).Subtitle("LogoArea (Full width)",y=2)
    Det3=Det3.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Detect3 : DETECT FINAL, [Detect2.MT_Hysteresis(Detect1)]",y=2)
    Det2=Det2.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Detect2 : [Detect1 Inpand by DHysCNT, reduce stray pixels]",y=2)
    Det1=Det1.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Detect1 : Text4 AND Halo4",y=2)
    Text4=Text4.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Text4 : [Text3.MT_Hysteresis(Text2)]",y=2)
    Text3=Text3.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Text3 : [Text2 Inpand by THysCNT, reduce stray pixels]",y=2)
    Text2=Text2.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Text2 : [Swell Text1 by Halo thickness]",y=2)
    TxtInRng=TxtInRng.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Text1 : [TextInRange via TEXTCOL & TEXTTOL]",y=2)
    Halo4=Halo4.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Halo4 : [Halo3.MT_Hysteresis(Halo2)]",y=2)
    Halo3=Halo3.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Halo3 : [Halo2 Inpand by HHysCNT, reduce stray pixels]",y=2)
    Halo2=Halo2.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Halo2 : [Swell Halo1 by Text thickness]",y=2)
    HalInRng=HalInRng.Eval(CnvS).AddBorders(X,0,Width-X-W,0).AddBorders(0,22,0,0,$F0F080).Subtitle("Halo1 : [HaloInRange via HALOCOL & HALOTOL]",y=2)
    StackVertical(LogoC,Det3,Det2,Det1,Text4,Halo4,Text3,Halo3,Text2,Halo2,TxtInRng,HalInRng)
    Return Last
}

############################

HARDFN="hard sub - 01 WEBdlRip 720p, 23.976.mkv.AVI"  # converted to AVI via ffmpeg
HARDFN=HARDFN.RT_GetFullPathName

AVISource(HARDFN)
killaudio


# Subtitle coords
X        = 40
Y        = Height-140
W        = -X
H        = -8
# Text, Halo color
TEXTCOL   = $EDEEF4  # R 230->245[$ED:$8] :::  G 230->247 [$EE:$9]::: B 233->255 [$F4:$B]
TEXTTOL   = $08090B                       # Text RGB channels can vary by as much as TEXTTOL, eg TEXTTOL $010203 is Red Tolerance $01, Grn Tolerance $02, Blue Tolerance $03.
HALOCOL   = $10313D  # R 7->26[$10:$A] ::: G 37->62[$31:$D] ::: B 55->68[$3D:7]
HALOTOL   = $0A0D07                       # Halo RGB channels can vary by as much as HALOTOL, eg HALOTOL $010203 is Red Tolerance $01, Grn Tolerance $02, Blue Tolerance $03.
# Text pixel width,height
TEXT_W    = 4                             # minimum text pixel 'thickness' Horizontal (horizontal thickness of vertical strokes)
TEXT_H    = 4                             # minimum text pixel 'thickness' Vertical (vertical thickness of horizontal strokes)
# Halo pixel width,height
HALO_L    = 2                             # Left Halo width in pixels
HALO_R    = 2                             # Right Halo width in pixels
HALO_T    = 2                             # Top Halo height in pixels
HALO_B    = 2                             # Bot Halo height in pixels
# Mt_Hysteresis (reduce stray pixels):- http://forum.doom9.org/showthread.php?p=1780589#post1780589
THYSCNT   = 2                             # Text Mask Mt_Hysteresis inpand count (prior to mt_hysteresis), Dont Mt_Hysteresis if 0
HHYSCNT   = 2                             # Halo Mask Mt_Hysteresis inpand count (prior to mt_hysteresis), Dont Mt_Hysteresis if 0
DHYSCNT   = 2                             # Detect clip Mt_Hysteresis inpand count (prior to mt_hysteresis), Dont Mt_Hysteresis if 0

######

THRESH_W  = -(Text_w+(Halo_L+Halo_R)/2)   # -ve, specifies Abs(Pixel width)  {Else +ve = Percent width 0.0->100.0%) {0.0=any pixel in range)
THRESH_H  = -(Text_h+(Halo_T+Halo_B)/2)   # -ve, specifies Abs(Pixel Height) {Else +ve = Percent width 0.0->100.0%) {0.0=any pixel in range)
#
BAFFLE_W  = Text_w+Halo_L+Halo_R          # Width of outermost Vertical edges.
BAFFLE_H  = Text_h+Halo_T+Halo_B          # Height of outermost Horizontal edges.
#
RESCAN    = true                          # Switching on might get rid of the odd stray pixel (most likely not).
#
DB        = "MyDB.DB"                     # If Named, then DB not deleted on exit. (Maybe DBase used by other scripts later)
OverRide  = ""                            # ""=Not used, "*..." multiline string of ranges, "OverRide.txt"=Text file of ranges.

#OverRide="OverRide.txt"

/*
    OverRide="""*   # <<=== NOTE Asterisk (STAR). Example String OverRide (1st char is '*'). Ranges OverRidden to NO SUBTITLE
        10 100      # A comment, SPACE or COMMA Separator
        200,300     # 200 to 300. NOTE -ve frame count NOT supported.
        3000,0      # 3000 till last frame.
    """
*/

DetSub(Last,Override=Override,
    \ x=X,y=Y,w=W,h=H,
    \ Text_w=TEXT_W,Text_h=TEXT_H,TextCol=TEXTCOL,TextTol=TEXTTOL,
    \ Halo_L=HALO_L,Halo_T=HALO_T,Halo_R=HALO_R,Halo_B=HALO_B,HaloCol=HALOCOL,HaloTol=HALOTOL,
    \ THysCnt=THYSCNT,HHysCnt=HHYSCNT,DHysCnt=DHYSCNT,
    \ Baffle_w=BAFFLE_W,Baffle_h=BAFFLE_H,Thresh_w=THRESH_W,Thresh_h=THRESH_H,ReScan=RESCAN,
    \ db=DB)
In VDub2, can set to 100% and using mouse scroll image in window. [EDIT: If eg monitor Full HD or less]



Something to play with. [EDIT: Avs+ only]

EDIT: TEXTTOL and HALOTOL instead of TEXTVAR and HALOVAR, separate tolerance per channel.
Script & image updated.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 17th August 2021 at 17:39.
StainlessS is offline   Reply With Quote
Old 18th August 2021, 14:50   #153  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
Quote:
Originally Posted by StainlessS View Post
Here what I've done so far
Thanks, the script looks more readable now, maybe I'll be able to steal some ideas now.

Is there real advantage of TOL over VAR (I kinda liked a simple setting)?

Last edited by VoodooFX; 20th August 2021 at 10:17.
VoodooFX is offline   Reply With Quote
Old 18th August 2021, 22:12   #154  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
EDIT: Here are the supplementary script functions.

Code:
###
# DSub_MI, Based on DetectSub.MI.avsi":- https://forum.doom9.org/showthread.php?p=1782036#post1782036
###
# Req Avs+, RT_Stats v2.00 Beta 02, GScript, Grunt, CallCmd, MaskTools v2.0. RemoveGain or RGTools.
# RT_Stats v2.00 Beta2 first posted here:- http://forum.doom9.org/showthread.php?p=1782028#post1782028
#
###

Function Hit_Marker(int W, Int H, Bool "Hit", Int "BW", Int "BH",Int "PW",Int "PH",Bool "YV12",Bool "Mod2") {
/*
    Req RT_Stats & mt_tools v2.     http://forum.doom9.org/showthread.php?t=174527
    Creates a marker mask WxH, for use with Overlay as Mask arg.
    Intended for use via some kind of detector to show detection Hit, or Miss.
    Returns Single frame clip with null audio, the marker top left hand side is aligned to 0,0.
            Default return clip colorspace is Y8 for Avisynth v2.6 and above, or YV12 if defunct version.
    Args:-
        W,H,    Size of marker mask (can be odd), return clip dimensions are rounded up to next multiple of 2 if YV12 return clip.
                  Bare minimum usable size is 4x4 with defaulted BW, BH, PW, PH.
        HIT,    Default False, returns marker as angled corners (Thickness set by BW and BH).
                        True,  returns marker as angled corners + outer perimeter where perimeter thickness set by PW and PH.
        BW,     Default Max(W/8,1). Horizontal thickness of the marker corners.
        BH,     Default Max(H/8,1). Vertical   thickness of the marker corners.
        PW,     Default Max(BW/8,1). Horizontal thickness of the vertical perimeter.
        PH,     Default Max(BH/8,1). Vertical thickness of the horizontal perimeter.
        YV12,   Default False if Avisynth version 2.6 or greater(Y8), else true(YV12). Selects return clip colorspace.
        Mod2,   Default True. If Y8 then round odd dimensions up modulo 2 (the mask is still WxH).

    Example:-
        Import("Hit_Marker.avs")
        WW=128  HH=WW   HIT=True
        BlankClip
        Yell=Last.BlankClip(Width=WW,Height=HH,Length=1,Color=$FFFF00)
        Return OverLay(Yell,x=(Width-WW)/2,y=(Height-HH)/2,mask=Hit_Marker(WW,HH,HIT))
*/
    Hit=Default(hit,False)                    BW=Max(Default(BW,W/8),1)   BH=Max(Default(BH,H/8),1)
    BW2=(W>4)?BW*2:BW                         BH2=(H>4)?BH*2:BH
    PW=Max(Default(PW,BW/8),1)                PH=Max(Default(PH,BH/8),1)  is26 = VersionNumber>=2.6
    YV12=(!is26) ? True : Default(YV12,False) Mod2=Default(Mod2,True)     Mod = (YV12||Mod2) ? 2 : 1
    CanvasW=(W+Mod-1)/Mod*Mod                 CanvasH=(H+Mod-1)/Mod*Mod
    Rpn= RT_String("x %d < x %d >= | y %d < | y %d >= | x %d < x %d >= | & y %d < y %d >= | & ",BW,W-BW,BH,H-BH,BW2,W-BW2,BH2,H-BH2)
    Rpn= (Hit) ? Rpn + RT_String("x %d < x %d >= | y %d < | y %d >= | | ",PW,W-PW,PH,H-PH) : Rpn
    Rpn= Rpn + RT_String("x %d < y %d < & & 255 0 ?",W,H)
    Blankclip(width=CanvasW,height=CanvasH,Length=1,pixel_type=YV12?"YV12":"Y8").Killaudio
    return mt_lutspa(relative = false,yExpr=Rpn, chroma = "-128")
}


Function ChrIsStar(String S)     {return RT_Ord(S)==42}
Function ChrIsNul(String S)      {return RT_Ord(S)== 0}                             # End of String
Function ChrIsHash(String S)     {return RT_Ord(S)==35}                             # #
Function ChrIsDigit(String S)    {C=RT_Ord(S) return C>=48&&C<=57}
Function ChrEatWhite(String S)   {i=1 C=RT_Ord(S,i) While(C==32||C>=8&&C<=13)       {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}
Function ChrEatDigits(String S)  {i=1 C=RT_Ord(S,i) While(C>=48&&C<=57)             {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}

Function DetSub_Override(string Override,string DB) {
    if(ChrIsStar(Override))  {OverRide=MidStr(OverRide,2)
    } else {
        Assert(Exist(OverRide),RT_String("%sOverRide File does not exist",myName))
        OverRide=RT_ReadTxtFromFile(Override)
    }
    LINES=RT_TxtQueryLines(OverRide)
    for(i=0,LINES-1) {
        SS=ChrEatWhite(RT_TxtGetLine(Override,i))
        S=SS
        if(!ChrIsNul(S) && !ChrIsHash(S)) {
            if(ChrIsDigit(S)) {
                StartF = RT_NumberValue(S)
                EndF=StartF
                S=ChrEatWhite(ChrEatDigits(S))
                if(ChrIsComma(S)){S=MidStr(S,2) S=ChrEatWhite(S)}
                if(ChrIsDigit(S)) {
                    EndF=RT_NumberValue(S)
                    S=ChrEatDigits(S)
                    if(EndF==0) { EndF=FrameCount-1}
                    Assert(StartF<=EndF,RT_String("%sError StartFrame(%d) > EndFrame(%d)",myName,StartF,EndF))
                }
                for(n=StartF,EndF) {RT_DBaseSetField(DB,n,0,3)}
            }
            S=ChrEatWhite(S)
            if(ChrIsHash(S)) {S=""}
            Assert(ChrIsNul(S),RT_String("%s *** NON-PARSE *** Error in Override Line %d\n'%s'",myName,i+1,SS))
        }
    }
    return 0
}
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 20th August 2021 at 00:38.
StainlessS is offline   Reply With Quote
Old 19th August 2021, 14:37   #155  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Code:
/*

   function Prototype:
    DetSub(clip c,Int "X"=-10,Int "Y"=Height-120,Int "W"=-10,Int "H"=-8,
        \ Int "Text_w"=3,Int "Text_h"=3,Int "TextCol"=$FCFCFC,Int "TextTol"=$030303,
        \ Int "Halo_L"=3,Int "Halo_T"=3,Int "Halo_R"=3,Int "Halo_B"=3,Int "HaloCol"=$030303,Int "HaloTol"=$030303,
        \ int "BackColor"=$00FF00,Int "ClipIx"=0,string "Matrix"="rec601",String "DB"="",string "Override"="")

    Matrix, for src conversion to RGB32.

    ClipIx select which sub clip to return, [DetSub, output always RGB32 with Alpha = known state $FF (opaque)]
      0)     = Full detect Info clip, same width as input clip.
      1->15) = Other sub clip, dimensions X,Y,W,H.

*/
Function DetSub(clip c,Int "X",Int "Y",Int "W",Int "H",
        \ Int "Text_w",Int "Text_h",Int "TextCol",Int "TextTol",
        \ Int "Halo_L",Int "Halo_T",Int "Halo_R",Int "Halo_B",Int "HaloCol",Int "HaloTol",
        \ int "BackColor",Int "ClipIx",string "Matrix",String "DB",string "Override") {
    myName="DetSub: "
    c
    IsPlus=FindStr(VersionString,"AviSynth+")!=0
    Assert(RT_FunctionExist("GScriptClip"),myName+"Essential GRunT plugin installed, http://forum.doom9.org/showthread.php?t=139337")
    Assert(IsPlus||RT_FunctionExist("GScript"),myName+"Essential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846")
    Assert(RT_FunctionExist("CallCmd"),myName+"Essential CallCmd plugin installed, http://forum.doom9.org/showthread.php?t=166063")
    Assert(RT_FunctionExist("mt_expand"),myName+"Essential MaskTools v2 plugin installed, http://forum.doom9.org/showthread.php?t=98985")
    Assert(RT_FunctionExist("RemoveGrain"),myName+"Essential RemoveGrain installed.")
    X=Default(X,10)                     Y=Default(Y,Height-120)         W=Default(W,-10)                    H=Default(H,-8)
    W=(W<=0)?Width-X+W:W                H=(H<=0)?Height-Y+H:H
    Text_w=Default(Text_w,3)            Text_h=Default(Text_h,3)
    TextCol=Default(TextCol,$FCFCFC)    TextTol=Default(TextTol,$030303)
    Halo_L=Default(Halo_L,3)            Halo_T=Default(Halo_T,3)        Halo_R=Default(Halo_R,3)            Halo_B=Default(Halo_B,3)
    HaloCol=Default(HaloCol,$030303)    HaloTol=Default(HaloTol,$030303)
    Text_Tol_B=BitAnd(TextTol,$FF)      TextTol=BitRShiftU(TextTol,8) Text_Tol_G=BitAnd(TextTol,$FF)  TextTol=BitRShiftU(TextTol,8)  Text_Tol_R=BitAnd(TextTol,$FF)
    Halo_Tol_B=BitAnd(HaloTol,$FF)      HaloTol=BitRShiftU(HaloTol,8) Halo_Tol_G=BitAnd(HaloTol,$FF)  HaloTol=BitRShiftU(HaloTol,8)  Halo_Tol_R=BitAnd(HaloTol,$FF)
    BackColor=Default(BackColor,$00FF00)  # Background for Det4, DETECT FINAL
    Matrix = Default(Matrix,"Rec601")
    Ix = Default(ClipIx,0)
    Assert(0 <= Ix <=15,MyName+"0 <= ClipIx <=15")
    DB=Default(DB,"")    UserDB=(DB!="")
    DB=(!UserDB) ? "~"+RT_LocalTimeString+".DB" : DB
    DB=RT_GetFullPathName(DB)
    Override=Default(OverRide,"")
    ###
    # Mt_Hysteresis (reduce stray pixels):- http://forum.doom9.org/showthread.php?p=1780589#post1780589
    # Text Mask Mt_Hysteresis inpand count (prior to mt_hysteresis), Dont Mt_Hysteresis if 0
    THYSCNT   = Min(TEXT_W,TEXT_H)/2 - 1
    # Halo Mask Mt_Hysteresis inpand count (prior to mt_hysteresis), Dont Mt_Hysteresis if 0
    HHYSCNT   = Min(HALO_L,HALO_R,HALO_T,HALO_B)/2 - 1
    # Detect clip Mt_Hysteresis inpand count (prior to mt_hysteresis), Dont Mt_Hysteresis if 0
    DHYSCNT   = Min(TEXT_W+HALO_L+HALO_R,TEXT_H+HALO_T+HALO_B)/2 - 1
    ###### Subs detect position
    THRESH_W  = -(Text_w+(Halo_L+Halo_R)/2)   # -ve, specifies Abs(Pixel width)  {Else +ve = Percent width 0.0->100.0%) {0.0=any pixel in range)
    THRESH_H  = -(Text_h+(Halo_T+Halo_B)/2)   # -ve, specifies Abs(Pixel Height) {Else +ve = Percent width 0.0->100.0%) {0.0=any pixel in range)
    BAFFLE_W  = Text_w+Halo_L+Halo_R          # Width of outermost Vertical edges.
    BAFFLE_H  = Text_h+Halo_T+Halo_B          # Height of outermost Horizontal edges.
    RESCAN    = true                          # Switching on might get rid of the odd stray pixel (most likely not).
    ###
    VW=Width VH=Height
    /*  Fields
            0) Status,  0=Unknown (unvisited), 1=Sub, 2 Not sub, 3 User OverRide
            1) X # Coords relative the Subtitles X,Y,W,H Detect Area
            2) Y
            3) W
            4) H
    */
    RT_DBaseAlloc(DB,FrameCount,"iiiii")
    RT_DBaseSetID(DB,0,c.FrameCount,c.FrameRate,VW,VH,X,Y,W,H)
    if(OverRide!="") {DetSet_Override(Override,DB)}

    FullWidSubC=ConvertToRGB32(matrix=Matrix).crop(0,Y,0,H)   # Full width Subs area

    Area=FullWidSubC.Crop(X,0,W,0).ResetMask    # Valid Subs Area only, Reset Alpha to White
    Text1=Area.ColorKeyMask(TextCol,Text_Tol_R,Text_Tol_G,Text_Tol_B).ShowAlpha(Pixel_Type="Y8")   # Set TextCol in range pixels to black
    Halo1=Area.ColorKeyMask(HaloCol,Halo_Tol_R,Halo_Tol_G,Halo_Tol_B).ShowAlpha(Pixel_Type="Y8")   # Set HaloCol in range pixels to black
    Text1=Text1.Invert  # Text In-range pixels white, else black
    Halo1=Halo1.Invert  # Halo In-range pixels white, else black

    Text2 = Text1.RemoveGrain(2)
    Halo2 = Halo1.RemoveGrain(2)


    Text3 = Text2
    # Swell Text by Halo thickness [Including Halo Drop Shadow]
    HALO_MAX=Max(HALO_L,HALO_T,HALO_R,HALO_B)
    for(i=1,HALO_MAX) {
        HorFlg=(i<=HALO_L?1:0)+(i<=HALO_R?2:0)    VerFlg=(i<=HALO_T?1:0)+(i<=HALO_B?2:0)
        if(HorFlg+VerFlg==6)     {Text3=Text3.Mt_Expand(mode="square")
        } else {
            if(HorFlg==3)        {Text3=Text3.Mt_Expand(mode="horizontal") HorFlg=0}
            if(VerFlg==3)        {Text3=Text3.Mt_Expand(mode="vertical") VerFlg=0}
            if(HorFlg!=0)        {Text3=Text3.Mt_Expand(mode=HorFlg==1? " 1  0  0  0" : " -1  0  0  0")} # ? Expand_Left : Expand_Right
            if(VerFlg!=0)        {Text3=Text3.Mt_Expand(mode=VerFlg==1? " 0  1  0  0" : "  0 -1  0  0")} # ? Expand_Up   : Expand_Down
        }
    }

    Text4=Text2
    Text5=Text3
    # reduce Text strays a little
    if(THysCNT>0) {
        For(i=1,THysCNT) {Text4=Text4.MT_Inpand(mode="both")}
        Text5=Text4.MT_Hysteresis(Text3)
    }

    Halo3 = Halo2
    # Swell Halo by Text thickness
    TEXT_MAX=Max(TEXT_W,TEXT_H)
    for(i=1,TEXT_MAX) {
        HorFlg=(i<=TEXT_W?1:0) VerFlg=(i<=TEXT_H?1:0)
        if(HorFlg+VerFlg==2)    {Halo3=Halo3.Mt_Expand(mode="square")
        } else {
            if(HorFlg!=0)       {Halo3=Halo3.Mt_Expand(mode="horizontal") }
            if(VerFlg!=0)       {Halo3=Halo3.Mt_Expand(mode="vertical") }
        }
    }

    Halo4=Halo2
    Halo5=Halo3
    # reduce Halo strays a little
    if(HHysCNT>0) {
        For(i=1,HHysCNT) {Halo4=Halo4.MT_Inpand(mode="both")}
        Halo5=Halo4.MT_Hysteresis(Halo3)
    }

    Detect1=Mt_Logic(Text5,Halo5,"and")
    Detect2=Detect1
    Detect3=Detect2
    Ocr1=Text2
    if(DHysCNT>0) {
        For(i=1,DHysCNT) {Detect2=Detect2.MT_Inpand(mode="both")}
        Detect3=Detect2.MT_Hysteresis(Detect1)
        Ocr1=Detect2.MT_Hysteresis(Mt_Logic(Text2,Detect3,"and"))
    }


    SSS1="""
        n = current_frame
        Status = RT_DBaseGetField(DB,n,0)
        if(Status==0) {                                                       # Unknown Status
            Status = (Detect3.RT_YInRangeLocate(Baffle_w=Baffle_w,Baffle_h=Baffle_h,lo=255,hi=255,Thresh_w=Thresh_w,Thresh_h=Thresh_h,ReScan=ReScan)) ? 1 : 2
            if(Status==1)   {
                RT_DBaseSet(DB,n,Status,YIRL_X,YIRL_Y,YIRL_W,YIRL_H)
            }
            RT_DBaseSetField(DB,n,0,Status)
        }
        Return Last
    """
    FullWidSubC=FullWidSubC.GScriptClip(SSS1, local=true, args="Detect3,DB,Baffle_w,Baffle_h,Thresh_w,Thresh_h,ReScan",after_frame=true)
    Grn=Detect3.BlankClip(Pixel_Type="RGB32",color=BackColor)
    Ocr2=Grn.Overlay(Grn.BlankClip(color=$000000),Mask=Detect3.RemoveGrain(2)).Overlay(Ocr1,Mask=Ocr1)

    SSS2="""
        n = current_frame
        Status = RT_DBaseGetField(DB,n,0)
        if(Status==1) {
            SUB_X = RT_DBaseGetField(DB,n,1)    SUB_Y = RT_DBaseGetField(DB,n,2)
            SUB_W = RT_DBaseGetField(DB,n,3)    SUB_H = RT_DBaseGetField(DB,n,4)
            OverLay(Last.BlankClip(color=$FF00FF,width=SUB_W,height=SUB_H),x=X+SUB_X,y=SUB_Y,opacity=0.25)
        }
        Return Last
    """
    FullWidSubC=FullWidSubC.GScriptClip(SSS2, local=true, args="Detect3,DB,X",after_frame=true)
    Mrk=FullWidSubC.BlankClip(Length=1,Width=W,Height=H,Color=$FFFF0000)
    Msk=Hit_Marker(W,H,True,8,8,1,1)
    FullWidSubC=FullWidSubC.Overlay(Mrk,Mask=Msk,x=X,y=0,Opacity=0.5)
    FullWidSubC=FullWidSubC.AddBorders(0,22,0,0,$F0F080).Subtitle("0] SubsArea (Search area in Red, detected subs in purple)",y=2)
    Ocr2_T=Ocr2.AddBorders(X,0,Width-X-W,0,BackColor).AddBorders(0,22,0,0,$F0F080).Subtitle("1] OCR2 : [GreenC.Overlay(Blackness.Mask=Detect3.RemoveGrain(2)).Overlay(Ocr1,Mask=Ocr1)]",y=2)
    Ocr1_T=Ocr1.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("2] OCR1 : [Detect2.MT_Hysteresis(Mt_Logic(Text2,Detect3,'and'))]",y=2)
    Detect3_T=Detect3.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("3] Detect3 : [Detect2.MT_Hysteresis(Detect1), reduce stray pixels]",y=2)
    Detect2_T=Detect2.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle(String(DHysCNT,"4] Detect2 : [Detect1 Inpand by DHysCNT(%.0f))]"),y=2)
    Detect1_T=Detect1.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("5] Detect1 : Text5 AND Halo5",y=2)
    Text5_T=Text5.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("6] Text5 : [Text4.MT_Hysteresis(Text3), reduce stray pixels]",y=2)
    Text4_T=Text4.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle(String(THysCNT,"7] Text4 : [Text2 Inpand by THysCNT(%.0f)]"),y=2)
    Text3_T=Text3.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("8] Text3 : [Swell Text2 by Halo thickness]",y=2)
    Text2_T=Text2.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("9] Text2 : [UnDot, Text1.RemoveGrain(2)]",y=2)
    Text1_T=Text1.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("10] Text1 : [TextInRange via TEXTCOL & TEXTTOL]",y=2)
    Halo5_T=Halo5.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("11] Halo5 : [Halo4.MT_Hysteresis(Halo3), reduce stray pixels]",y=2)
    Halo4_T=Halo4.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle(String(HHysCNT,"12] Halo4 : [Halo2 Inpand by HHysCNT(%.0f)]"),y=2)
    Halo3_T=Halo3.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("13] Halo3 : [Swell Halo2 by Text thickness]",y=2)
    Halo2_T=Halo2.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("14] Halo2 : [UnDot, Halo1.RemoveGrain(2)]",y=2)
    Halo1_T=Halo1.ConvertToRGB32.AddBorders(X,0,Width-X-W,0,$000000).AddBorders(0,22,0,0,$F0F080).Subtitle("15] Halo1 : [HaloInRange via HALOCOL & HALOTOL]",y=2)
    C0=StackVertical(FullWidSubC,Ocr2_T,Ocr1_T,Detect3_T,Detect2_T,Detect1_T,Text5_T,Text4_T,Text3_T,Text2_T,Text1_T,Halo5_T,Halo4_T,Halo3_T,Halo2_T,Halo1_T)
    Ix==0?C0:Ix==1?Ocr2:Ix==2?Ocr1:Ix==3?Detect3:Ix==4?Detect2:Ix==5?Detect1:Ix==6?Text5:Ix==7?Text4:Ix==8?Text3:Ix==9?Text2:Ix==10?Text1:Ix==11?Halo5:Ix==12?Halo4:Ix==13?Halo3:Ix==14?Halo2:Halo1
    Return ConvertToRGB32(Matrix="PC601").ResetMask # Alpha = $FF
}

############################

HARDFN="hard sub - 01 WEBdlRip 720p, 23.976.mkv.AVI"  # converted to AVI via ffmpeg
HARDFN=HARDFN.RT_GetFullPathName

AVISource(HARDFN)
killaudio

# Subtitle coords
X        = 58
Y        = Height-118
W        = -X
H        = -16
# Text, Halo color

TEXTCOL   = $F3F3F3
TEXTTOL   = $0E0E0E

HALOCOL   = $102A37
HALOTOL   = $121212

# Setting all below too narrow[eg all 2 on test sample], produces odd effect where subs shown are actually mid way between text and halo, looks pretty good result but wrong.
# Also has peculiar property where seems to ignore random garbage in result adjacent to subs.
# Text pixel width,height
TEXT_W    = 4                             # minimum text pixel 'thickness' Horizontal (horizontal thickness of vertical strokes)
TEXT_H    = 4                             # minimum text pixel 'thickness' Vertical (vertical thickness of horizontal strokes)
# Halo pixel width,height
HALO_L    = 3                             # Left Halo width in pixels
HALO_R    = 3                             # Right Halo width in pixels
HALO_T    = 3                             # Top Halo height in pixels
HALO_B    = 3                             # Bot Halo height in pixels

BACKCOLOR = $00FF00                       # Background for OCR2 bar

MATRIX    = "Rec601"
ClipIx    =  0                            # 0=full metric clip[Full width, H height].
                                          # 1 -> 15, other clip[Size X,Y,W,H]. always RGB32 result.
##################
DB        = "MyDB.DB"                     # If Named, then DB not deleted on exit. (Maybe DBase used by other scripts later)
OverRide  = ""                            # ""=Not used, "*..." multiline string of ranges, "OverRide.txt"=Text file of ranges.
#OverRide="OverRide.txt"

/*
    OverRide="""*   # <<=== NOTE Asterisk (STAR). Example String OverRide (1st char is '*'). Ranges OverRidden to NO SUBTITLE
        10 100      # A comment, SPACE or COMMA Separator
        200,300     # 200 to 300. NOTE -ve frame count NOT supported.
        3000,0      # 3000 till last frame.
    """
*/

DetSub(x=X,y=Y,w=W,h=H,
    \ Text_w=TEXT_W,Text_h=TEXT_H,TextCol=TEXTCOL,TextTol=TEXTTOL,
    \ Halo_L=HALO_L,Halo_T=HALO_T,Halo_R=HALO_R,Halo_B=HALO_B,HaloCol=HALOCOL,HaloTol=HALOTOL,
    \ backColor=BACKCOLOR,clipIx=ClipIx,Matrix=MATRIX,db=DB,Override=Override)
[Below, click twice]


EDIT: function Prototype in code block fixed.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 22nd August 2021 at 19:55. Reason: Updated
StainlessS is offline   Reply With Quote
Old 20th August 2021, 10:44   #156  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
Quote:
Originally Posted by StainlessS View Post
EDIT: significant re-write.
That is 7th version I've saved...
This last one doesn't come with the user part.
So, "Detect3" is a final removal mask and "Detect4" is just to show what it covers? Could you add output for a final text mask without halo (that could be used for OCR purpose)?

Today I'll try to play with this sample too.

Last edited by VoodooFX; 20th August 2021 at 10:52.
VoodooFX is offline   Reply With Quote
Old 20th August 2021, 12:37   #157  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Not sure that I understand, outputs whole image set [ClipIx=0] or ClipIx= 1->14, 14 different masks, see either post #157 or #158 images, ClipIx in subclip title text,
eg for green bar [ClipIx=1]
Code:
1] Detect4 : DETECT FINAL, [FullWidSubC.BlankClip.Overlay(FullWidSubC.Mask=Detect3.RemoveGrain(2))]
Code:
    DetSub(clip c,x="10",y="Height-120",w="-10",h="-8",
    \ Text_w="3",Text_h="3",TextCol="$FCFCFC",TextTol=$030303",
    \ Halo_L="3",Halo_T="3",Halo_R="3",Halo_B="3",HaloCol=HALOCOL,HaloTol=HALOTOL,
    \ backColor="$00FF00",ClipIx="0",Matrix="rec601",db="",Override="")
Quote:
This last one doesn't come with the user part.
What user part are we talkin' bout ?

EDIT:
Damn, I forgot that Green bar, non-green parts, text/halo is original pixels, I need to 'sorta' binarize before making green bar.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 20th August 2021 at 12:51.
StainlessS is offline   Reply With Quote
Old 20th August 2021, 13:49   #158  |  Link
VoodooFX
Banana User
 
VoodooFX's Avatar
 
Join Date: Sep 2008
Posts: 985
I did few experiments with InpaintDelogo's DynMask=3, probably I can make it from 'not good' to 'usable' for this sample.

Quote:
Originally Posted by StainlessS View Post
Not sure that I understand, outputs whole image set [ClipIx=0] or ClipIx= 1->14, 14 different masks, see either post #157 or #158 images...
First(FINAL) mask doesn't look like a mask...
Text2 looks like best to OCR, but it's not cleaned from all the dots, maybe another "UnDot" pass would help.

Quote:
Originally Posted by StainlessS View Post
What user part are we talkin' bout?
About settings used. I found them at the top, before they were at the bottom.
VoodooFX is offline   Reply With Quote
Old 20th August 2021, 15:57   #159  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
About settings used. I found them at the top, before they were at the bottom.
OK, sorry.

Quote:
First(FINAL) mask doesn't look like a mask...
Well the idea is to be able to extract from it both Text and Halo separately, with Green being the 'other guys'.

Posts #157 updated.


EDIT: So long as there is only ever 2 lines of subs, then would be better to reduce search area height to avoid encroaching noise above and below.


EDIT: Changed to [Images not updated]
Code:
# Subtitle coords
X        = 58
Y        = Height-118
W        = -X
H        = -16
EDIT: Images updated.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 20th August 2021 at 16:37.
StainlessS is offline   Reply With Quote
Old 21st August 2021, 14:10   #160  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
VX,
I have a rough idea how to select best Sub image from each detected Sub range.
Roughly, scan for each image in range, detecting image with least white text, excess white being crud round the edges, choose that image. (there can only be excess crud halo if excess crud text. <sort of>)
Well thats the idea, maybe work, maybe not.
I think we've polluted your important thread a bit with this, so I suggest you delete posts back to about #151, and I'll delete mine back to wherever you choose too.
The only other person posting back to #151, was kedautinh12 with a "thanks Stain" remark, perhaps he/she/they/them/it would be good enough to delete too.
I'll post new thread with current script and continue there if I have any success, will of course require multiple passes scripts.
[Which could possibly be automated into single script. <to export subs images for OCR, or InpaintDelogo>]
EDIT: Maybe also output frames file with Subs range and frameno of best subs in range.

EDIT:
Quote:
(there can only be excess crud halo if excess crud text. <sort of>)
That aint quite right, but we'll try figure that out when we need to. [at least we know where we are tryin' to get to next]

EDIT: Logical AND of all white over the range [for text] and logical AND of all the black over range [for halo] - should maybe do it.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 21st August 2021 at 15:28.
StainlessS is offline   Reply With Quote
Reply

Tags
delogo, hardsubs, ocr, remove, watermark

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 08:39.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.