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 10th October 2021, 21:37   #181  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Some interesting observations, thank you.

EDIT: this dont do anything [output overwritten later]
Code:
output=SpotLess(src)              # stack side by side, Source top left, Spotless TM true top right, Spotless TM false bottom left, ? bottom right.
EDIT: Your sample PAL DVD ?
My B5 has Progressive, Interlaced and even Perverse Telecine sections.
__________________
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; 10th October 2021 at 21:41.
StainlessS is offline   Reply With Quote
Old 10th October 2021, 22:15   #182  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Quote:
Originally Posted by StainlessS View Post
Some interesting observations, thank you.

EDIT: this dont do anything [output overwritten later]
Code:
output=SpotLess(src)              # stack side by side, Source top left, Spotless TM true top right, Spotless TM false bottom left, ? bottom right.
EDIT: Your sample PAL DVD ?
My B5 has Progressive, Interlaced and even Perverse Telecine sections.
PAL yes. Same problems with yours.
However my dad just bought the new B5, yucky 4:3 live but brilliant cgi. I have now changed tack and now using original 16/9 live with new 4/3 cgi with black v bars. Brilliant, no need to worry about deinterlacing old cgi which is a mess.
coolgit is offline   Reply With Quote
Old 10th October 2021, 22:35   #183  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
OK thanks, gotcha.
Had no idea they had done that.
https://www.google.com/search?client...lon+5+live+cgi

Some difference :- https://www.youtube.com/watch?v=p_oFTEAU9O8
__________________
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; 10th October 2021 at 22:37.
StainlessS is offline   Reply With Quote
Old 10th October 2021, 23:34   #184  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Amazingly got spotless and scene change to work.

Just need to output the frame numbers of detected scene frames to a text file for cross checking accuracy of detection. Your current output is of no use to me and I don't understand it either.

Code:
source=FFVideoSource("F:\BABYLON5\Season 2\9 The Coming Of Shadows\The Coming Of Shadows SA.avi").convertTOYV12(interlaced=false).killaudio()
#filename="F:\BABYLON5\Season 2\8 Soul Mates\Spotless and sc_hbd.txt"

# VARIABLES--------------------------------------------------------------------

txt_sz = 24          # Test size if infos displayed
src = source


# Spotless variables, to remove dirt and spots.-------------------------------
RadT = 1             # Temporal radius. (MCompensate arg)
Pel = 2              # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
BlkSzT = 16           # Default 8. MAnalyse BlkSize. 16 is better for eliminating all spots. Maybe also better where BIG noise.
BlkSzF = 8            # Default 8. MAnalyse BlkSize. Stay on 8 for greater accuracy in motion analysis and keeping details same as source file.
OLapT = (BlkSzT/2)     #important not too low (eg 4 for blksz 12, because creates stairs). Can use 4 if blksz 16 in some cases.
OLapF = (BlkSzF/2)     #important not too low (eg 4 for blksz 12, because creates stairs)
BblurT = 0.3          # Default 0.6. Suggest about 0.3 for denoised temporal clean clip.
BblurF = 0.6          # Default 0.6. Rare times about 0.9 helps with hands movement close to camera for better motion analysis, but a bit slower.

# Remove spots-----------------------------------------------------------------
SpotLessT=SpotLess(src,BlkSz=BlkSzT,OLap=OLapT,pel=pel,Tm=True,Bblur=BblurT,ThSAD=6000,RadT=RadT)    # Truemotion=True for fixing almost all spots but will have missing details where there is too much motion.
SpotLessF=SpotLess(src,BlkSz=BlkSzF,OLap=OLapF,pel=1,Tm=False,Bblur=BblurF,ThSAD=1000,RadT=RadT)   # Truemotion=False for retaining almost all details when there is too much motion but less and smaller spots fixed.
                                                                                              # Use these frames to overwrite above frames whenever necessary.


# FUNCTIONS
#------------------------------------------------------------------------------------------------------------------
function sub(c, label, txt_sz) {
	return subtitle(c, label, size = txt_sz, align=8)
}

Function SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion, float "dfactor",Float "MinDif",bool "show",String "S_Frames",String "E_Frames") {
    dfactor = Float(Default(dfactor,4.5))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif,1.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
    Show    = Default(show,true)
    S_Frames= Default(S_Frames,"")
    E_Frames= Default(E_Frames,"")
    Assert(!DClip.IsRGB,"SCSelect_HBD: DClip YUV Only")
    Assert(1.0 <= dFactor,"SCSelect_HBD: 1.0 <= dFactor")
    Assert(0.0 <= Mindif ,"SCSelect_HBD: 0.0 <= MinDif")
    try { bpc = DClip.BitsPerComponent } catch(err_msg) { bpc = 8 }
    DClip = (bpc!=8) ? DClip.ConvertBits(8) : DClip
    Sz  = Max(Round(Motion.Height*0.05),12)
    S_Frames = (S_Frames!="") ? S_Frames.RT_GetFullPathName : ""
    E_Frames = (E_Frames!="") ? E_Frames.RT_GetFullPathName : ""
    (S_Frames !="") ? RT_FileDelete(S_Frames) : NOP
    (E_Frames !="") ? RT_FileDelete(E_Frames) : NOP
    Motion.GScriptClip("""
        n   = current_frame
        pDf = Dclip.YDifferenceFromPrevious
        nDf = Dclip.YDifferenceToNext
        pTh = nDf*dfactor+MinDif
        nTh = pDf*dfactor+MinDif
        SC  = 2                 # Default To SC = MOTION (Last is MOTION clip)
        if     (n==0)           { SC = 0 Start S_Frames!=""?RT_WriteFile(S_Frames,"%d",n,Append=true):NOP} # SOS
        else if(n==FrameCount-1){ SC = 1 End   E_Frames!=""?RT_WriteFile(E_Frames,"%d",n,Append=true):NOP} # EOS, Fixes ScSelect SOS detect on Last frame
        else if(pDf>pTh)        { SC = 0 Start S_Frames!=""?RT_WriteFile(S_Frames,"%d",n,Append=true):NOP} # SOS
        else if(nDf>nTh)        { SC = 1 End   E_Frames!=""?RT_WriteFile(E_Frames,"%d",n,Append=true):NOP} # EOS
        if(show) {
            mx = Max(pDf,nDf)
            mn = Min(pDf,nDf)
            Can_dF = (mx > mn + Mindif)    # Can any values of dfactor(1.0 and aove) cause scene detect ?
            Can_Md = (mx > dFactor * mn)   # Can any values of MinDif(0.0 and above) cause scene detect ?
            if(Can_dF || Can_Md) {
                E_dF = (Can_dF) ? String(Min((mx - Mindif) / max(mn,0.00001),99.9999),"dFact=%7.4f") : ""
                E_Md = (Can_Md) ? String(mx - dFactor * mn,"MinD=%7.4f") : ""
                EdfS = E_dF + ((Can_dF && Can_Md) ? ":" : "") + E_Md + ""
                EdfS = ((pDf==mx) ? "SOS:" :"EOS:") + EdfS
            } else { EdfS = "" }
            Subtitle(
            \ String() + EdfS + "\n" +
            \ String(pDf,"SOS") + (SC==0 ? " <":"") + "\n" +
            \ String(nDf,"EOS") + (SC==1 ? " <":"")
            \ ,Font="Courier New",Size=Sz,lsp=0)
        }
        Return Last
    """,Args="dfactor,Start,End,Dclip,MinDif,show,S_Frames,E_Frames,Sz",Local=true)  # Needs Grunt for args
    return Last
}

Function SpotLess(clip c,int "RadT",int "ThSAD",int "ThSAD2",int "pel",bool "chroma", int "BlkSz",Int "Olap",bool "tm",Bool "glob", Float "bBlur", clip "dc" ) {
    myName   = "SpotLess: "
    RadT     = Default(RadT,1)        # Temporal radius. (MCompensate arg)
    ThSAD    = Default(ThSAD,6000)    # SAD threshold at radius 1 (Default Nearly OFF).
    ThSAD2   = Default(ThSAD2,ThSAD)   # SAD threshold at radius RadT.
    Pel      = Default(pel,2)         # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
    Chroma   = Default(chroma,True)   # MAnalyse chroma arg. If set to true, use chroma in block matching.
    BlkSz    = Default(BlkSz,16)       # Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps  better, esp for HD clips. Maybe also better where BIG noise.
    OLap     = Default(OLap,BlkSz/2)   # Default half of BlkSz.
    Tm       = Default(tm,True)       # TrueMotion, Some folk swear MAnalyse(truemotion=false) is better.
    Glob     = Default(glob,True)     # Default True, Allow set MAnalyse(global) independently of TrueMotion.
    bBlur    = Default(bblur,0.6)     # Default 0.6. Suggest about 0.6 for better motion analysis, but a bit slower.
    HasDC    = dc.Defined             # bblur ignored if HasDC, ie user already provided prefiltered clip.
    Assert(1 <= RadT,myName + " 1 <= RadT")
    Assert(0.0 <= bblur <= 1.58, myName + "0.0 <= bblur <= 1.58")
    Assert(pel==1 || pel==2 || pel==4, myName + "pel==1 || pel==2 || pel==4")
    pad = max(BlkSz,8)
    sup = (HasDC ? dc : bBlur>0.0  ? c.blur(bBlur) : c ).MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2)
    # Only 1 Level required where not MAnalyse-ing.
    sup_rend = (HasDC||bBlur>0.0) ? c.MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2,Levels=1) : sup
    MultiVec = sup.MAnalyse(multi=true,delta=RadT,blksize=BlkSz,overlap=OLap,chroma=Chroma,truemotion=Tm,global=Glob)
    c.MCompensate(sup_rend,MultiVec,tr=RadT,thSad=ThSAD,thSad2=ThSAD2)
    MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT)  # Temporal median blur only [not spatial]
    SelectEvery(RadT*2+1,RadT)                                       # Return middle frame
}

prev = SpotLessT.selectevery(1,-1)
next = SpotLessT.selectevery(1,1)
SpotLessSCT=src.SCSelect_HBD(next,prev,SpotLessT,show=false)

S1 = StackHorizontal(\
sub(src, "Source", txt_sz),\
sub(SpotLessT, "Spotless TM true", txt_sz)\
)
S2 = StackHorizontal(\
sub(SpotLessF, "Spotless TM false", txt_sz),\
sub(SpotLessSCT, "Spotless and scene change", txt_sz)\
)
output = StackVertical(S1,S2)

#Return output                           # Comparison

return SpotLessSCT                      # Conversion
#return SpotLessT
#return SpotLessF

# Debugging to check scene change detection------------------------------------
prev = SpotLessT.selectevery(1,-1)
next = SpotLessT.selectevery(1,1)
SpotLessSCTD=src.SCSelect_HBD(next,prev,SpotLessT,show=true)

SSCTD = StackHorizontal(\
sub(src, "Source", txt_sz),\
sub(SpotLessSCTD, "Spotless and scene change", txt_sz)\
)

#Return SSCTD                           # Comparison

#WriteFileIf(SpotLessSCT, filename,
#\ "SC==0", "current_frame", """ ": Start" """,
#\ "SC==1", "current_frame", """ ": End" """, flush=true)

#WriteFileIf(src, filename, "(SC==0) || (SC==1)", "current_frame", """ "(: Start)"  """ || """ "(: End)" """, flush=true)
See post 190 for updated script.

Last edited by coolgit; 14th October 2021 at 14:01. Reason: Updated the script
coolgit is offline   Reply With Quote
Old 10th October 2021, 23:44   #185  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Quote:
Originally Posted by StainlessS View Post
OK thanks, gotcha.
Had no idea they had done that.
https://www.google.com/search?client...lon+5+live+cgi

Some difference :- https://www.youtube.com/watch?v=p_oFTEAU9O8
Saw them years ago. There was one showing orangey tint making white people look like Donald Trump and i thought, cricky i ain't buying that 4/3 orangutan Trump 5.
coolgit is offline   Reply With Quote
Old 13th October 2021, 12:52   #186  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Stainlesss

How do I move your scselect_hbd text output higher to the added black bar?

I used addborder(0,100,0,0) in the debug section for debugging purpose only so the text can go in there. I got the spotless text in there but not the rest.

Checking that spot was fully removed is hard when the text is in the way.
coolgit is offline   Reply With Quote
Old 13th October 2021, 15:18   #187  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
If you are taling about the ScSelect_HBD metrics, then cannot be done, ScSelect_HBD knows nothing of the [ external to ScSelect_HBD() ] subtitled border that will be added later.
Your only option might be to eg create a clip with metrics, and chop off and keep the metrics, and another without metrics,
stack the metrics above the no metric clip.
You would also need a dummy [blankclip] clip so that your Stacked frames are same dimensions.

Do that asnwer your question ?

EDIT: I dont actually see anywhere in script that has an Addborders nor a BlackClip.
__________________
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; 13th October 2021 at 15:28.
StainlessS is offline   Reply With Quote
Old 13th October 2021, 18:05   #188  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
The addborder was removed as it didn't work. I will do a small border for spotless script.

SO i should have source clip then clip with metrics then clip without metric then blank clip? 2x2 stacked.
coolgit is offline   Reply With Quote
Old 14th October 2021, 01:14   #189  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
2x2 stack sounds good.
__________________
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 October 2021, 14:00   #190  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Final update. Works like a dream.

Changed to dfactor,5.0 and MinDif,5.0 to prevent false scene changes in static scenes like SCSelect did. On average most scene changes were 20 or above for both.

Code:
source=FFVideoSource("F:\whatever filename directory .avi").convertTOYV12(interlaced=false).killaudio()


# VARIABLES--------------------------------------------------------------------

txt_sz = 24          # Test size if infos displayed
src = source


# Spotless variables, to remove dirt and spots.-------------------------------
RadT = 1             # Temporal radius. (MCompensate arg)
BlkSzT = 16           # Default 8. MAnalyse BlkSize. 16 is better for eliminating all spots. Maybe also better where BIG noise.
BlkSzF = 8            # Default 8. MAnalyse BlkSize. Stay on 8 for greater accuracy in motion analysis and keeping details same as source file.
OLapT = (BlkSzT/2)     #important not too low (eg 4 for blksz 12, because creates stairs). Can use 4 if blksz 16 in some cases.
OLapF = (BlkSzF/2)     #important not too low (eg 4 for blksz 12, because creates stairs)
BblurT = 0.3          # Default 0.6. Suggest about 0.3 for denoised temporal clean clip.
BblurF = 0.6          # Default 0.6. Rare times about 0.9 helps with hands movement close to camera for better motion analysis, but a bit slower.

# Remove spots-----------------------------------------------------------------
SpotLessT=SpotLess(src,BlkSz=BlkSzT,OLap=OLapT,pel=2,Tm=True,Bblur=BblurT,ThSAD=6000,RadT=RadT)    # Truemotion=True for fixing almost all spots but will have missing details where there is too much motion.
SpotLessF=SpotLess(src,BlkSz=BlkSzF,OLap=OLapF,pel=1,Tm=False,Bblur=BblurF,ThSAD=1000,RadT=RadT)   # Truemotion=False for retaining almost all details when there is too much motion but less and smaller spots fixed.
                                                                                              # Use these frames to overwrite above frames whenever necessary.


# FUNCTIONS
#------------------------------------------------------------------------------------------------------------------
function sub(c, label, txt_sz) {
	return subtitle(c, label, size = txt_sz, align=8)
}

Function SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion, float "dfactor",Float "MinDif",bool "show",String "S_Frames",String "E_Frames") {
    dfactor = Float(Default(dfactor,5.0))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif,5.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
    Show    = Default(show,true)
    S_Frames= Default(S_Frames,"")
    E_Frames= Default(E_Frames,"")
    Assert(!DClip.IsRGB,"SCSelect_HBD: DClip YUV Only")
    Assert(1.0 <= dFactor,"SCSelect_HBD: 1.0 <= dFactor")
    Assert(0.0 <= Mindif ,"SCSelect_HBD: 0.0 <= MinDif")
    try { bpc = DClip.BitsPerComponent } catch(err_msg) { bpc = 8 }
    DClip = (bpc!=8) ? DClip.ConvertBits(8) : DClip
    Sz  = Max(Round(Motion.Height*0.05),12)
    S_Frames = (S_Frames!="") ? S_Frames.RT_GetFullPathName : ""
    E_Frames = (E_Frames!="") ? E_Frames.RT_GetFullPathName : ""
    (S_Frames !="") ? RT_FileDelete(S_Frames) : NOP
    (E_Frames !="") ? RT_FileDelete(E_Frames) : NOP
    Motion.GScriptClip("""
        n   = current_frame
        pDf = Dclip.YDifferenceFromPrevious
        nDf = Dclip.YDifferenceToNext
        pTh = nDf*dfactor+MinDif
        nTh = pDf*dfactor+MinDif
        SC  = 2                 # Default To SC = MOTION (Last is MOTION clip)
        if     (n==0)           { SC = 0 Start S_Frames!=""?RT_WriteFile(S_Frames,"%d",n,Append=true):NOP} # SOS
        else if(n==FrameCount-1){ SC = 1 End   E_Frames!=""?RT_WriteFile(E_Frames,"%d",n,Append=true):NOP} # EOS, Fixes ScSelect SOS detect on Last frame
        else if(pDf>pTh)        { SC = 0 Start S_Frames!=""?RT_WriteFile(S_Frames,"%d",n,Append=true):NOP} # SOS
        else if(nDf>nTh)        { SC = 1 End   E_Frames!=""?RT_WriteFile(E_Frames,"%d",n,Append=true):NOP} # EOS
        if(show) {
            mx = Max(pDf,nDf)
            mn = Min(pDf,nDf)
            Can_dF = (mx > mn + Mindif)    # Can any values of dfactor(1.0 and aove) cause scene detect ?
            Can_Md = (mx > dFactor * mn)   # Can any values of MinDif(0.0 and above) cause scene detect ?
            if(Can_dF || Can_Md) {
                E_dF = (Can_dF) ? String(Min((mx - Mindif) / max(mn,0.00001),99.9999),"dFact=%7.4f") : ""
                E_Md = (Can_Md) ? String(mx - dFactor * mn,"MinD=%7.4f") : ""
                EdfS = E_dF + ((Can_dF && Can_Md) ? ":" : "") + E_Md + ""
                EdfS = ((pDf==mx) ? "SOS:" :"EOS:") + EdfS
            } else { EdfS = "" }
            Subtitle(
            \ String() + EdfS + "\n" +
            \ String(pDf,"SOS") + (SC==0 ? " <":"") + "\n" +
            \ String(nDf,"EOS") + (SC==1 ? " <":"")
            \ ,Font="Courier New",Size=Sz,lsp=0)
        }
        Return Last
    """,Args="dfactor,Start,End,Dclip,MinDif,show,S_Frames,E_Frames,Sz",Local=true)  # Needs Grunt for args
    return Last
}

Function SpotLess(clip c,int "RadT",int "ThSAD",int "ThSAD2",int "pel",bool "chroma", int "BlkSz",Int "Olap",bool "tm",Bool "glob", Float "bBlur", clip "dc" ) {
    myName   = "SpotLess: "
    RadT     = Default(RadT,1)        # Temporal radius. (MCompensate arg)
    ThSAD    = Default(ThSAD,6000)    # SAD threshold at radius 1 (Default Nearly OFF).
    ThSAD2   = Default(ThSAD2,ThSAD)   # SAD threshold at radius RadT.
    Pel      = Default(pel,2)         # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
    Chroma   = Default(chroma,True)   # MAnalyse chroma arg. If set to true, use chroma in block matching.
    BlkSz    = Default(BlkSz,16)       # Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps  better, esp for HD clips. Maybe also better where BIG noise.
    OLap     = Default(OLap,BlkSz/2)   # Default half of BlkSz.
    Tm       = Default(tm,True)       # TrueMotion, Some folk swear MAnalyse(truemotion=false) is better.
    Glob     = Default(glob,True)     # Default True, Allow set MAnalyse(global) independently of TrueMotion.
    bBlur    = Default(bblur,0.6)     # Default 0.6. Suggest about 0.6 for better motion analysis, but a bit slower.
    HasDC    = dc.Defined             # bblur ignored if HasDC, ie user already provided prefiltered clip.
    Assert(1 <= RadT,myName + " 1 <= RadT")
    Assert(0.0 <= bblur <= 1.58, myName + "0.0 <= bblur <= 1.58")
    Assert(pel==1 || pel==2 || pel==4, myName + "pel==1 || pel==2 || pel==4")
    pad = max(BlkSz,8)
    sup = (HasDC ? dc : bBlur>0.0  ? c.blur(bBlur) : c ).MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2)
    # Only 1 Level required where not MAnalyse-ing.
    sup_rend = (HasDC||bBlur>0.0) ? c.MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2,Levels=1) : sup
    MultiVec = sup.MAnalyse(multi=true,delta=RadT,blksize=BlkSz,overlap=OLap,chroma=Chroma,truemotion=Tm,global=Glob)
    c.MCompensate(sup_rend,MultiVec,tr=RadT,thSad=ThSAD,thSad2=ThSAD2)
    MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT)  # Temporal median blur only [not spatial]
    SelectEvery(RadT*2+1,RadT)                                       # Return middle frame
}

prev = SpotLessT.selectevery(1,-1)
next = SpotLessT.selectevery(1,1)
SpotLessSCT=src.SCSelect_HBD(next,prev,SpotLessT,show=false)

S1 = StackHorizontal(\
sub(src, "Source", txt_sz),\
sub(SpotLessT, "Spotless TM true", txt_sz)\
)
S2 = StackHorizontal(\
sub(SpotLessF, "Spotless TM false", txt_sz),\
sub(SpotLessSCT, "Spotless and scene change", txt_sz)\
)
output = StackVertical(S1,S2)

#Return output                           # Comparison

#return SpotLessSCT                      # Conversion
#return SpotLessT
#return SpotLessF

# Debugging to check scene change detection------------------------------------
prev = SpotLessT.selectevery(1,-1)
next = SpotLessT.selectevery(1,1)
SpotLessSCTDM=src.SCSelect_HBD(next,prev,SpotLessT,show=true)

SSCTD1 = StackHorizontal(\
sub(src.AddBorders(0,30,0,0), "Source", txt_sz),\
sub(SpotLessSCTDM.AddBorders(0,30,0,0), "Spotless and scene change with metrics", txt_sz)\
)
SSCTD2 = StackHorizontal(\
sub(SpotLessSCT.AddBorders(0,30,0,0), "Spotless and scene change without metrics", txt_sz),\
sub(BlankClip(src).AddBorders(0,30,0,0), "Blank", txt_sz)\
)
outputD = StackVertical(SSCTD1,SSCTD2)

Return outputD                           # Comparison

Last edited by coolgit; 14th October 2021 at 14:28.
coolgit is offline   Reply With Quote
Old 14th October 2021, 15:11   #191  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
CoolG, bout ScSecelct_HBD,
Did this lot make any sense to you, was it at all useful/usable ? [its not immediately obvious to me unless I got the below doc in front of me ].

Code:
        Show,       Default False. In original ScSelect, this arg is called Debug, and output some info to DebugView (google),
                    we show info on frame and so have changed arg name to Show but of roughly same functionality.

                    Metrics when Show=True (metrics provided as if in 8 bit range):
                      >>>>>>>>>>>>>>>>>
                      20531 ] S {SOS: dFact= 19.7365:MinD=54.6495}
                      SOS: P{ 66.214} > pTh{ 12.565}<==
                      EOS: N{  3.304} > nTh{232.750}
                      <<<<<<<<<<<<<<<<<

                      20531,                              Is current Frame Number
                          S,                              Is flagging a detected Start-Of-Scene (Also 'E'=End-Of-Scene, and 'G' = Global motion.
                      SOS: P{ 66.214} > pTh{ 12.565} <==  The arrow "<==" at the end denotes a SOS (Start Of Scene) detection.
                                                          'P' (short for pDf, screen space saving) is difference to previous frame.
                                                          pTh = dFactor * nDf + MinDif
                      EOS: N{  3.304} > nTh{232.750}      Much as Above, but no EOS (End Of Scene) detection.
                                                          'N' (short for nDf), is difference to next frame.
                                                          nTh = dFactor * pDf + MinDif

                      {SOS: dFact= 19.7365:MinD=54.6495}, NOT ALWAYS SHOWN.
                                                          The Scene change Arg, matching estimate info, in this case for SOS estimate.
                                                          Shown only if pDf, nDF, and arg limits on dFactor and MinDif could
                                                          produce either SOS or EOS. This indicator only makes any sense on frames
                                                          that YOU have decided should be a scene change frame, otherwise ignore.
                                                          dFact is the dFactor that will produce an EXACT match of the threshold
                                                          (SOS pTh or EOS nTh) to the higher difference {SOS pDf or EOS nDf), when
                                                          MinDif unchanged.
                                                          As this example shows SOS, so the threshold is pTh and higher difference is pDf,
                                                          so it balances this line,
                                                              P{ 66.214} == pTh{66.214}, or
                                                              P{ 66.214} == {dfact   * nDf + MinDif)
                                                              P{ 66.214} == {19.7365 * nDf + MinDif)
                                                          So in this particular instance it shows that the maximum value for dFactor arg
                                                          that could produce SOS on this frame with current Mindif is LESS THAN 19.7365.
                                                          It shows that lowest value of dFactor that would fail to produce a SOS, so the maxium
                                                          value of dFactor that would succeed to detect SOS for current frame is just below this
                                                          value. (pDf has to be greater than pTh so when equal will fail SOS detect).
                                                          Similar can be deduced when EOS estimator is shown.
                                                          MinD is similar estimator (in this case again for SOS) which shows where MinDif
                                                          will balance (with current dFactor unchanged)
                                                              P{ 66.214} == pTh{66.214}, or
                                                              P{ 66.214} == {dfactor * nDf + MinD)
                                                              P{ 66.214} == {dfactor * nDf + 54.641195)
                                                          Similar can be deduced when EOS estimator is shown.
                                                          Hope some of that made at least a little sense, is intended to give you some
                                                          idea about how much you can raise (or lower) dFactor or Mindif to get
                                                          a successful detection on current frame.
Quote:
Changed to dfactor,5.0 and MinDif,5.0 to prevent false scene changes in static scenes like SCSelect did
Did you actually experience false detects ?
Default values should have been pretty good. MinDif=1.0 (default) should avoid almost all false scene change detects [possible exception some anime].
__________________
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; 14th October 2021 at 15:39.
StainlessS is offline   Reply With Quote
Old 14th October 2021, 16:27   #192  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Quote:
Originally Posted by StainlessS View Post
CoolG, bout ScSecelct_HBD,
Did this lot make any sense to you, was it at all useful/usable ?
A bit of it.

Only dfactor and mindif are important in deciding scene change. The rest doesn't do anything hence why I'd removed it from the subtitle. There is such a thing called 'information overload'. If both are above the variables of, currently, 5.0 then it is a scene change.

Test it on s2 ep7 A Race Through Dark Places, frames 3300 onwards where Bester was torturing a guy for info. Pay attention to the static frames where the background was black and white (like chess board pattern), behind Bester. Some frames jumped up 2 ish pixels then back down to normal. SCSelect flagged this as scene change and swap frames. Yours, because of mindif, didn't except for 1 frame because mindif was 1.0. Hence why putting it up to 5.0 is the solution and doesn't affect real scene changes.

In GROPOS I had 1 scene change that wasn't detected but was detected by vdub. My vdub is set at 240. It does the job and stops when there too much motion as those frames will mostly needs replacing by spotlessF file. The failed detection was because the background was the same except the camera moved from 1 actor to another. Does it matter? If vdub stops then i can see if there is any spots before moving on. If there isn't then detection failure doesn't matter, no frames are swapped. However in this case there was a spot and that is when I knew the detection failed. That was the only frame I had to fix in photoshop, just 1, bloody brilliant compare to 50 to 70.

In essence explaining dfactor and mindif is enough. P, Pth, ndf, are not important and just confused the hell out of me.
coolgit is offline   Reply With Quote
Old 15th October 2021, 00:15   #193  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Thanks for your insight
[it is though of use to me to find out why something caused +ve/-ve detect, even if diags from numbers not immediately obvious, even to me].

EDIT: I could though add a "verbose" type arg to allow switch on/off dfact/minD estimates.
__________________
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; 15th October 2021 at 02:02.
StainlessS is offline   Reply With Quote
Old 16th October 2021, 15:49   #194  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Just curious how this happened. Clear scene change but not detected and low dfactor and 0 mindif. Vdub had no problems.

https://i.ibb.co/vHpKztV/029835.png

https://i.ibb.co/MfFphtG/029836.png

Also Mindif reduce to 3.0. It worked better as 5.0 was an overkill on my part.

Last edited by coolgit; 16th October 2021 at 15:58.
coolgit is offline   Reply With Quote
Old 16th October 2021, 16:05   #195  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Full script in two parts. Include both functions explanations. Put it together ok.

Code:
/*
    SpotLess v1.07Beta. temporal spot/noise remover, by StainlessS @ Doom9.   https://forum.doom9.org/showthread.php?t=181777
    Original idea from Didée post :-                                      https://forum.doom9.org/showthread.p...90#post1402690
    Req:- Pinterf MvTools2(), Pinterf Medianblur2() with MedianBlurTemporal rather than the MedianBlurT() from Didée post.
          With appropriate plugins, will be AVS+ colorspace and x64 compatible.
          Fine using Avs+ Prefetch() so long as current Pinterf plugins, and Frame Accurate source. RequestLinear() following the source filter might suffice as frame accurate source filter.

    NOT FOR cartoon/anime, live video only, sorry.

    v1.01, Remove RadT Max check. Add MSuper(hpad=16,vpad=16). Add BlkSz arg.
    v1.02, Add some stuff.
    v1.03, Frame size auto config of args removed (found instances where caused problems). Added Glob and bBlur args.
    v1.04, Script breaking changes, I guess is more flexible if can also set ThSAD, inserted ThSAD 3rd arg. RadT now default 1, was 2, dont over denoise unless requested.
    v1.05, Additional checks on args.
    v1.06, Glob Default true, Almost always better.
    v1.07Beta, bBlur Default changed from 0.0 OFF, to 0.6, slower but better for mc analysis. Maybe try 1.0 for HD to overcome HD 'gritiness'.
               Added dc arg, detect clip.

    SpotLess(clip c,int "RadT"=1,int "ThSAD"=10000,int "ThSAD2"=ThSAD,int "pel"=2,bool "chroma"=true, int "BlkSz"=8,Int "Olap"=BlkSz/2,
            \ bool "tm"=true,Bool "glob"=True,Float "bBlur"=0.6, clip "dc"=Undefined)

    RadT, 1 or more, Default 1. Removes Spots on up to RadT [Temporal Radius] consecutive frames.
        RadT > 2 will usually be overkill. Setting too high could possibly result in blurring.
        Each pixel in result frame is median pixel value of (2*RadT+1) motion compensated frames (including source, ie current_frame-RadT to current_frame+RadT).

    ThSAD, Default 10000=NEARLY OFF(ie ignore hardly any bad blocks), 0 < ThSAD < 16320(8*8*255). 8x8 block SAD threshold at radius 1 (ie at current_frame +- 1) [SAD, Sum of Absolute (pixelwise) Differences].
        ThSAD and ThSAD2 suggested absolute minimum of maybe about 400.
        ThSAD and ThSAD2 thresholds are based on 8 bit 8x8 block, irrespective of colorspace depth or BlkSz, max=8x8x255=16320, use same thresholds where High Bit Depth.
        In mvTools MCompensate(), when creating a compensated block the SAD between compensated block and the same original block in current_frame, the 8 bit SAD is measured and if
        greater than SAD threshold then that block is ignored and uses original block from current frame instead. [The compensated block is judged too different, so ignored & original block used instead
        in the result MCompensated frame].
        Where eg ThSAD=64, AVERAGE absolute single pixel difference threshold would be 64/(8*8)=1, so AVERAGE absolute pixel difference greater than 1 would ignore that mcompensated block and use the
        block from current frame in the resulting mcompensated frame instead. This example allows for all pixels in a 8x8 block to be different by 1, or a single pixel in 8x8 block to be different by 64,
        or some other mixture.
          A problem with above is, if a low ThSAD and current_frame block is mostly noise, so compensated blocks could be judged bad because they are too different to the bad noisey block, and the result
        block may/will be just as bad as the noisy source block. A possible solution to this problem is to have a higher SAD threshold and/or have a bigger BlkSize so that the number of bad source pixels
        after converting/scaling to as if an 8x8 block, will contain fewer bad noise pixels. So, SpotLess BlkSz arg would ideally maybe 4 or more times the area of the largest spots that you have, and a SAD
        threshold big enough so as to not ignore the block [ wild guess minimum SAD threshold for big spot sizes of (8x8x255)/4 = 4080 ].
        Where a complete source frame is bad, then maybe should have very high (eg 10000) SAD threshold, and BlkSz may not really matter too much.
          It is not the end of the world if some of the compensated blocks are ignored and swapped for the original current_frame block. Nor is it the end of the world if
        no blocks were ignored because of high SAD threshold. The final result pixel is median pixel value of (2*RadT+1) motion compensated blocks, so allowing for some mistakes by choosing the
        middle pixel value.
        I've just tested real bad double frame, full frame luma and chroma corruption, with below line:
            SpotLess(RadT=5,ThSAD=1000000,ThSAD2=1000000,pel=2,chroma=false,BlkSz=8,Olap=4,tm=false,glob=false,bBlur=0.0)
        And although both SAD thresholds of 1 million, are totally impossible and so no blocks could possibly be ignored and yet we still got pretty good results, all frames were fixed
        as we still had the temporal median filter to fall back on and pick the middle pixel value.

        From mvtools2 docs:
          ThSAD is SAD threshold for safe (dummy) compensation.
              If block SAD is above the thSAD, the block is bad, and we use source block instead of the compensated block. Default is 10000 (practically disabled).

    ThSAD2, Default ThSAD, 0 < ThSAD2 < 16320(8*8*255), Lower removes fewer spots, but less chance of blurring.
        ThSAD2 sets the SAD [Sum of Absolute Differences] threshold for most distant frame from current_frame at distance RadT, with those frames that are distances in-between 1 and RadT
        acquiring a SAD threshold linearly interpolated between the two.
        From mvtools2 docs:
          ThSAD2:
              Defines the SAD soft threshold for the furthest frames at current_frame +- RadT.
              The actual SAD threshold for each reference frame is a smooth interpolation between the original thSAD (close to the current frame)
              and thSAD2. Setting thSAD2 lower than thSAD allows large temporal radii and good compensation for low SAD blocks while reducing the global error and the
              risk of bluring when the result of MCompensate is passed to a temporal denoising filter.
        EDIT: Although I have said that SAD threshold being too high could result in blurred frames, that is really taken from above "risk of bluring" line from mvtools docs,
        however, that warning says "temporal denoising filter", which might suggest pixel averaging, whereas we are using pixel median. I'm not sure that blurring would be the result
        of having too high a SAD threshold.

    Pel,     Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=half pixel, 4=quarter pixel)

    Chroma,  Default True. MAnalyse chroma arg. If true, use chroma in block matching when creating vectors. Maybe use False if source B&W or color noise.

    BlkSz,   Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps better for HD clips. [Info: current Pinterf MvTools allows for BlkSize=12, and overlap=6]

    OLap,    Default half BlkSz, Block overlap.

    Tm,      TrueMotion Default True. Some folk swear truemotion=false is better.

    Glob,    Default True (True v1.06, was same as Tm, true almost always better), Allow set MAnalyse(global) independently of TrueMotion.
             From MvTools2 docs for MAnalyse,
               global
                 Estimate global motion (at every level) and use it as an additional predictor.
                 Only pan shift is estimated (no zoom and rotation).
                 Use false to disable, use true to enable.

    bBlur,   Default 0.6. If used, Suggest about 0.6, where MAnalyse create vectors is performed on denoised (blurred) super clip
             for better motion analysis. Maybe try 1.0 for HD clip to counteract HD 'grittiness'. bBlur ignored if dc clip specified,
             If providing bBlur, then ALWAYS specify as named argument ie bBlur=bBlur, we will likely insert any additional MvTools args
             before bBlur to keep them together.

    dc,      Default UnDefined. If dc Specified, then must be same size and colorspace as source clip.
             If detection clip specified then bBlur prefilter arg is ignored, and analysis is performed on
             dc.MSuper() clip [ instead of c.Blur(bBlur).MSuper() ]. Allows to provide your own prefiltered clip.
             If providing dc clip, then ALWAYS specify as named argument ie dc=DC, we will likely insert any additional MvTools args
             before bBlur to keep them together.

#---------------------------------------------------------------------------------------------------------------------------------------

ScSelect_HBD(), v0.01. by StainlessS @ Doom9. : https://forum.doom9.org/showthread.php?t=182392
        Requires Grunt (c) Gavino. If S_Frames or E_Frames != "" then also requires RT_Stats.

    SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion,
        float "dfactor"=3.5,Float "MinDif"=1.0,
        bool "show"=False,String "S_Frames"="",String "E_Frames"="")

    ScSelect_HBD(), Mod of ScSelect_Like():- https://forum.doom9.org/showthread.p...23#post1644023
    Named with "_HDB" extender as should work ok with HBD in AVS+.
    ScSelect_Like() emulated ScSelect() from RemoveDirt.
        RemoveDirt's SCSelect(clip input, clip scene_begin, clip scene_end, clip global_motion, float dfactor, bool debug, bool planar)
        To emulate original ScSelect results, use ScSelect_HBD(dFactor=4.0,MinDif=0.0).

    Args:
        dClip,      Detection clip. May be different size and colorspace to Start, End and Motion clips. YUV only.
                    If High Bit Depth (greater than 8 bits per channel) then will be converted to 8 bit for scene change
                    detection stage. For larger source clips, you may want to downsize the dClip to speed up detection .

        Start,      Clip of frames that will replace frames from Motion clip when Start-Of-Scene detected.
        End,        Clip of frames that will replace frames from Motion clip when End-Of-Scene detected.
        Motion,     Clip the will be used where neither start nor end of scene detected.
                    Start, End, and Motion, clips can be different colorspace and size compared to dClip (unlike ScSelect),
                    but must all be same colorspace and size as each other, also can be high-bit-depth or RGB.

        dFactor,    Default 3.5. (1.0 <= dFactor) Detection factor, a multiplier applied to frame difference
                        metrics to decide if a scene change.
        Mindif,     Default 1.0. (0.0 <= Mindif, Supply MinDif as if in 8 bit range, 0.0 -> 255.0)
                      An additional component part of scene change detection.
                      Where difference measurements,
                        pDf = Average per pixel Luma difference, between dClip current frame and previous frame (0.0->255.0).
                        nDf = Average per pixel Luma difference, between dClip current frame and next frame (0.0->255.0).
                        pTh = dFactor * nDf + MinDif : If pDf greater than this then is SOS, Start-Of-Scene.
                        nTh = dFactor * pDf + MinDif : If nDf greater than this then is EOS, End-Of-Scene.
                        Detect method,
                          SOS = pDf > pTh : SOS = pDf > dFactor * nDf + MinDif,    Also,
                          EOS = nDf > nTh : EOS = nDf > dFactor * pDf + MinDif.
                          (If pDf > pTh, then pDf is also greater than nDf as dFactor is at least 1.0 and MinDif at least 0.0)
                      Original ScSelect, used default dFactor=4.0, and equivalent of MinDif=0.0 (It had no MinDif arg).
                      Using only dFactor, and no Mindif (ie 0.0), is not too good as a detector, especially where
                      scene of low motion or near static scene, eg when nDf=0.0 then pDf value of anything above 0.0
                      would detect a scene change, not exactly as desired for near static scene, additinal component is needed.
                      In same situation where MinDif=1.0 and  nDf=0.0, so SOS = pDf > pTh : SOS = pDf > 4.0 * 0.0 + 1.0
                      so, to detect Start of scene then pDf has to be greater than 1.0 for a start of scene detect.
                      In near static scene, we are most reliant upon Mindif being of sufficient magnitude to avoid a false
                      detection. In scene with plenty of motion, then value of dFactor becomes more important to prevent false
                      detection. In a very jerky or anime scene, then probably a high dFactor and high Mindif are required.
                      In this crazy mixed up world, you have to find a good compromise for dFactor and MinDif
                      so as to detect scene changes without producing false detections.
                      Our default of dFactor=3.5 and Mindif=1.0, is just one combination, you might prefer bigger Mindif
                      and smaller dFactor,(whatever you choose, some clips will require an alternative set).
                      I suggest dFactor usually no less than about 2.5 and no more than 4.0, and Mindif no less than 0.5, and
                      maybe no more than about 4.0. As you lower dFactor, you might want to raise Mindif, and vise versa.
                      Anime is likely to have different requirments with bigger MinDif (maybe 4 or more but depends upon the clip).
coolgit is offline   Reply With Quote
Old 16th October 2021, 16:07   #196  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Part 2

Code:
        Show,       Default False. In original ScSelect, this arg is called Debug, and output some info to DebugView (google),
                    we show info on frame and so have changed arg name to Show but of roughly same functionality.

                    Metrics when Show=True (metrics provided as if in 8 bit range):
                      >>>>>>>>>>>>>>>>>
                      20531 ] S {SOS: dFact= 19.7365:MinD=54.6495}
                      SOS: P{ 66.214} > pTh{ 12.565}<==
                      EOS: N{  3.304} > nTh{232.750}
                      <<<<<<<<<<<<<<<<<

                      20531,                              Is current Frame Number
                          S,                              Is flagging a detected Start-Of-Scene (Also 'E'=End-Of-Scene, and 'G' = Global motion.
                      SOS: P{ 66.214} > pTh{ 12.565} <==  The arrow "<==" at the end denotes a SOS (Start Of Scene) detection.
                                                          'P' (short for pDf, screen space saving) is difference to previous frame.
                                                          pTh = dFactor * nDf + MinDif
                      EOS: N{  3.304} > nTh{232.750}      Much as Above, but no EOS (End Of Scene) detection.
                                                          'N' (short for nDf), is difference to next frame.
                                                          nTh = dFactor * pDf + MinDif

                      {SOS: dFact= 19.7365:MinD=54.6495}, NOT ALWAYS SHOWN.
                                                          The Scene change Arg, matching estimate info, in this case for SOS estimate.
                                                          Shown only if pDf, nDF, and arg limits on dFactor and MinDif could
                                                          produce either SOS or EOS. This indicator only makes any sense on frames
                                                          that YOU have decided should be a scene change frame, otherwise ignore.
                                                          dFact is the dFactor that will produce an EXACT match of the threshold
                                                          (SOS pTh or EOS nTh) to the higher difference {SOS pDf or EOS nDf), when
                                                          MinDif unchanged.
                                                          As this example shows SOS, so the threshold is pTh and higher difference is pDf,
                                                          so it balances this line,
                                                              P{ 66.214} == pTh{66.214}, or
                                                              P{ 66.214} == {dfact   * nDf + MinDif)
                                                              P{ 66.214} == {19.7365 * nDf + MinDif)
                                                          So in this particular instance it shows that the maximum value for dFactor arg
                                                          that could produce SOS on this frame with current Mindif is LESS THAN 19.7365.
                                                          It shows that lowest value of dFactor that would fail to produce a SOS, so the maxium
                                                          value of dFactor that would succeed to detect SOS for current frame is just below this
                                                          value. (pDf has to be greater than pTh so when equal will fail SOS detect).
                                                          Similar can be deduced when EOS estimator is shown.
                                                          MinD is similar estimator (in this case again for SOS) which shows where MinDif
                                                          will balance (with current dFactor unchanged)
                                                              P{ 66.214} == pTh{66.214}, or
                                                              P{ 66.214} == {dfactor * nDf + MinD)
                                                              P{ 66.214} == {dfactor * nDf + 54.641195)
                                                          Similar can be deduced when EOS estimator is shown.
                                                          Hope some of that made at least a little sense, is intended to give you some
                                                          idea about how much you can raise (or lower) dFactor or Mindif to get
                                                          a successful detection on current frame.

        S_Frames,   Default "". Name of Start-Of-Scene Frames text file. Req RT_Stats if non "".
        E_Frames,   Default "". Name of End-Of-Scene Frames text file. Req RT_Stats if non "".
*/

source=FFVideoSource("F:\whatever .avi").convertTOYV12(interlaced=false).killaudio()

# VARIABLES--------------------------------------------------------------------

txt_sz = 24          # Test size if infos displayed
src = source


# Spotless variables, to remove dirt and spots.-------------------------------
RadT = 1             # Temporal radius. (MCompensate arg)
BlkSzT = 16           # Default 8. MAnalyse BlkSize. 16 is better for eliminating all spots. Maybe also better where BIG noise.
BlkSzF = 8            # Default 8. MAnalyse BlkSize. Stay on 8 for greater accuracy in motion analysis and keeping details same as source file.
OLapT = (BlkSzT/2)     #important not too low (eg 4 for blksz 12, because creates stairs). Can use 4 if blksz 16 in some cases.
OLapF = (BlkSzF/2)     #important not too low (eg 4 for blksz 12, because creates stairs)
BblurT = 0.3          # Default 0.6. Suggest about 0.3 for denoised temporal clean clip.
BblurF = 0.6          # Default 0.6. Rare times about 0.9 helps with hands movement close to camera for better motion analysis, but a bit slower.

# Remove spots-----------------------------------------------------------------
SpotLessT=SpotLess(src,BlkSz=BlkSzT,OLap=OLapT,pel=2,Tm=True,Bblur=BblurT,ThSAD=6000,RadT=RadT)    # Truemotion=True for fixing almost all spots but will have missing details where there is too much motion.
SpotLessF=SpotLess(src,BlkSz=BlkSzF,OLap=OLapF,pel=1,Tm=False,Bblur=BblurF,ThSAD=1000,RadT=RadT)   # Truemotion=False for retaining almost all details when there is too much motion but less and smaller spots fixed.
                                                                                              # Use these frames to overwrite above frames whenever necessary.


# FUNCTIONS
#------------------------------------------------------------------------------------------------------------------
function sub(c, label, txt_sz) {
	return subtitle(c, label, size = txt_sz, align=8)
}

Function SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion, float "dfactor",Float "MinDif",bool "show",String "S_Frames",String "E_Frames") {
    dfactor = Float(Default(dfactor,3.5))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif,1.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
    Show    = Default(show,true)
    S_Frames= Default(S_Frames,"")
    E_Frames= Default(E_Frames,"")
    Assert(!DClip.IsRGB,"SCSelect_HBD: DClip YUV Only")
    Assert(1.0 <= dFactor,"SCSelect_HBD: 1.0 <= dFactor")
    Assert(0.0 <= Mindif ,"SCSelect_HBD: 0.0 <= MinDif")
    try { bpc = DClip.BitsPerComponent } catch(err_msg) { bpc = 8 }
    DClip = (bpc!=8) ? DClip.ConvertBits(8) : DClip
    Sz  = Max(Round(Motion.Height*0.05),12)
    S_Frames = (S_Frames!="") ? S_Frames.RT_GetFullPathName : ""
    E_Frames = (E_Frames!="") ? E_Frames.RT_GetFullPathName : ""
    (S_Frames !="") ? RT_FileDelete(S_Frames) : NOP
    (E_Frames !="") ? RT_FileDelete(E_Frames) : NOP
    Motion.GScriptClip("""
        n   = current_frame
        pDf = Dclip.YDifferenceFromPrevious
        nDf = Dclip.YDifferenceToNext
        pTh = nDf*dfactor+MinDif
        nTh = pDf*dfactor+MinDif
        SC  = 2                 # Default To SC = MOTION (Last is MOTION clip)
        if     (n==0)           { SC = 0 Start S_Frames!=""?RT_WriteFile(S_Frames,"%d",n,Append=true):NOP} # SOS
        else if(n==FrameCount-1){ SC = 1 End   E_Frames!=""?RT_WriteFile(E_Frames,"%d",n,Append=true):NOP} # EOS, Fixes ScSelect SOS detect on Last frame
        else if(pDf>pTh)        { SC = 0 Start S_Frames!=""?RT_WriteFile(S_Frames,"%d",n,Append=true):NOP} # SOS
        else if(nDf>nTh)        { SC = 1 End   E_Frames!=""?RT_WriteFile(E_Frames,"%d",n,Append=true):NOP} # EOS
        if(show) {
            mx = Max(pDf,nDf)
            mn = Min(pDf,nDf)
            Can_dF = (mx > mn + Mindif)    # Can any values of dfactor(1.0 and aove) cause scene detect ?
            Can_Md = (mx > dFactor * mn)   # Can any values of MinDif(0.0 and above) cause scene detect ?
            if(Can_dF || Can_Md) {
                E_dF = (Can_dF) ? String(Min((mx - Mindif) / max(mn,0.00001),99.9999),"dFact=%7.4f") : ""
                E_Md = (Can_Md) ? String(mx - dFactor * mn,"MinD=%7.4f") : ""
                EdfS = E_dF + ((Can_dF && Can_Md) ? ":" : "") + E_Md + ""
                EdfS = ((pDf==mx) ? "SOS:" :"EOS:") + EdfS
            } else { EdfS = "" }
            Subtitle(
            \ String(n,"%.0f ") + MidStr("SEG",SC+1,1) + " " + EdfS + "\n" +
            \ String(pDf,"SOS: P{%7.3f} > ") + String(pTh,"pTh{%7.3f}") + (SC==0 ? " <==":"") + "\n" +
            \ String(nDf,"EOS: N{%7.3f} > ") + String(nTh,"nTh{%7.3f}") + (SC==1 ? " <==":"")
            \ ,Font="Courier New",Size=Sz,lsp=0)
        }
        Return Last
    """,Args="dfactor,Start,End,Dclip,MinDif,show,S_Frames,E_Frames,Sz",Local=true)  # Needs Grunt for args
    return Last
}

Function SpotLess(clip c,int "RadT",int "ThSAD",int "ThSAD2",int "pel",bool "chroma", int "BlkSz",Int "Olap",bool "tm",Bool "glob", Float "bBlur", clip "dc" ) {
    myName   = "SpotLess: "
    RadT     = Default(RadT,1)        # Temporal radius. (MCompensate arg)
    ThSAD    = Default(ThSAD,6000)    # SAD threshold at radius 1 (Default Nearly OFF).
    ThSAD2   = Default(ThSAD2,ThSAD)   # SAD threshold at radius RadT.
    Pel      = Default(pel,2)         # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
    Chroma   = Default(chroma,True)   # MAnalyse chroma arg. If set to true, use chroma in block matching.
    BlkSz    = Default(BlkSz,16)       # Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps  better, esp for HD clips. Maybe also better where BIG noise.
    OLap     = Default(OLap,BlkSz/2)   # Default half of BlkSz.
    Tm       = Default(tm,True)       # TrueMotion, Some folk swear MAnalyse(truemotion=false) is better.
    Glob     = Default(glob,True)     # Default True, Allow set MAnalyse(global) independently of TrueMotion.
    bBlur    = Default(bblur,0.6)     # Default 0.6. Suggest about 0.6 for better motion analysis, but a bit slower.
    HasDC    = dc.Defined             # bblur ignored if HasDC, ie user already provided prefiltered clip.
    Assert(1 <= RadT,myName + " 1 <= RadT")
    Assert(0.0 <= bblur <= 1.58, myName + "0.0 <= bblur <= 1.58")
    Assert(pel==1 || pel==2 || pel==4, myName + "pel==1 || pel==2 || pel==4")
    pad = max(BlkSz,8)
    sup = (HasDC ? dc : bBlur>0.0  ? c.blur(bBlur) : c ).MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2)
    # Only 1 Level required where not MAnalyse-ing.
    sup_rend = (HasDC||bBlur>0.0) ? c.MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2,Levels=1) : sup
    MultiVec = sup.MAnalyse(multi=true,delta=RadT,blksize=BlkSz,overlap=OLap,chroma=Chroma,truemotion=Tm,global=Glob)
    c.MCompensate(sup_rend,MultiVec,tr=RadT,thSad=ThSAD,thSad2=ThSAD2)
    MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT)  # Temporal median blur only [not spatial]
    SelectEvery(RadT*2+1,RadT)                                       # Return middle frame
}

prev = SpotLessT.selectevery(1,-1)
next = SpotLessT.selectevery(1,1)
SpotLessSCT=src.SCSelect_HBD(next,prev,SpotLessT,show=false)

S1 = StackHorizontal(\
sub(src, "Source", txt_sz),\
sub(SpotLessT, "Spotless TM true", txt_sz)\
)
S2 = StackHorizontal(\
sub(SpotLessF, "Spotless TM false", txt_sz),\
sub(SpotLessSCT, "Spotless and scene change", txt_sz)\
)
output = StackVertical(S1,S2)

#Return output                           # Comparison

return SpotLessSCT                      # Conversion
#return SpotLessT
#return SpotLessF

# Debugging to check scene change detection------------------------------------
prev = SpotLessT.selectevery(1,-1)
next = SpotLessT.selectevery(1,1)
SpotLessSCTDM=src.SCSelect_HBD(next,prev,SpotLessT,show=true)

SSCTD1 = StackHorizontal(\
sub(src.AddBorders(0,30,0,0), "Source", txt_sz),\
sub(SpotLessSCTDM.AddBorders(0,30,0,0), "Spotless and scene change with metrics", txt_sz)\
)
SSCTD2 = StackHorizontal(\
sub(SpotLessSCT.AddBorders(0,30,0,0), "Spotless and scene change without metrics", txt_sz),\
sub(BlankClip(src).AddBorders(0,30,0,0), "Blank", txt_sz)\
)
outputD = StackVertical(SSCTD1,SSCTD2)

#Return outputD                           # Comparison

Last edited by coolgit; 16th October 2021 at 20:33. Reason: Reset to defaults.
coolgit is offline   Reply With Quote
Old 16th October 2021, 17:43   #197  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
You should not really change defaults inside the script,
Defaults
Code:
    dfactor = Float(Default(dfactor,3.5))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif ,1.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
Your mod
Code:
    dfactor = Float(Default(dfactor,5.0))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif,3.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
They are both still a bit on the high side, and i would only really suggest MinDif = 3.0 or 4.0 for some anime.

On 29836 [SOS] it shows that with current MinDif (3.0) the maximum DFact that could detect as SOS is 2.0028 which is a lot less
than your DFact setting of 5.0. Even reducing Dfact to suggested 3.5 and MidDif to suggested default 1.0, it would still not detect,
problem is the big frame 29836 difference to next frame 29837 which is 8.641,
Difference to Previous (ie 20.306) has to be bigger than (5.0 * 8.641 + 3.0) [ie 46.205] to be detected as SOS,
even with defaults, would have to be greater than (3.5 * 8.641 + 1.0) [ie 31.2435] to be detected as SOS.
EDIT: 29836 -> 29837, diff will be a bit of a jolt, maybe a small pan. [EDIT: We dont know, we cant see it]

SCSelect / SCSelect_HBD are not a perfect solution to detect scene change, sad but there you go.
__________________
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; 16th October 2021 at 21:39.
StainlessS is offline   Reply With Quote
Old 16th October 2021, 20:47   #198  |  Link
coolgit
Registered User
 
Join Date: Apr 2019
Posts: 217
Quote:
Originally Posted by StainlessS View Post
You should not really change defaults inside the script,
Defaults
Code:
    dfactor = Float(Default(dfactor,3.5))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif ,1.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
Your mod
Code:
    dfactor = Float(Default(dfactor,5.0))  # Suggest 2.5 -> 4.0 ::: Change default to 4.0 to emulate ScSelect
    Mindif  = Float(Default(MinDif,3.0))  # Suggest 0.5 -> 4.0 ::: Change default to 0.0 to emulate ScSelect
They are both still a bit on the high side, and i would only really suggest MinDif = 3.0 or 4.0 for some anime.
Done.

Quote:
Originally Posted by StainlessS View Post
On 29836 [SOS] it shows that with current MinDif (3.0) the maximum DFact that could detect as SOS is 2.0028 which is a lot less
than your DFact setting of 5.0. Even reducing Dfact to suggested 3.5 and MidDif to suggested default 1.0, it would still not detect,
problem is the big frame 29836 difference to next frame 29837 which is 8.641,
Difference to Previous (ie 20.306) has to be bigger than (5.0 * 8.641 + 3.0) [ie 46.205] to be detected as SOS,
even with defaults, would have to be greater than (3.5 * 8.641 + 1.0) [ie 31.2435] to be detected as SOS.
EDIT: 29836 -> 29837, diff will be a bit of a jolt, maybe a small pan.

SCSelect / SCSelect_HBD are not a perfect solution to detect scene change, sad but there you go.
Just curious how it works. Perhaps the lack of colours in 29839 threw off the calculations.

However some common sense has to come into play here.

If there is an end of scene change then obviously the next frame must be the start of scene change, no matter what the maths is. What else can it be?
coolgit is offline   Reply With Quote
Old 16th October 2021, 21:31   #199  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
then obviously the next frame must be the start of scene change
ScSelect always had the problem of SOS sometimes not following EOS or EOS not always before SOS, my mod does not change that.
EOS frame considers only itself and those either side, SOS frame considers only itself and those either side,
so EOS knows nothing of the frame following SOS and SOS knows nothing of the frame before EOS.
Quote:
no matter what the maths is
It aint the math, its logic that fails, ie the algorithm, but IIRC, mvTools scene change detect has exact same problem. [ie mismatched EOS / SOS detects]

ScSelect_HBD is definitely better than ScSelect, but it aint perfect by any means.

EDIT: Maybe you can make some use of the stuff here:- https://forum.doom9.org/showthread.p...85#post1954985
EndOfSceneClip() and StartOfSceneClip.
__________________
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; 16th October 2021 at 23:41.
StainlessS is offline   Reply With Quote
Old 16th October 2021, 22:36   #200  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Or maybe you could try this [not much testing at all].

Code:
Function SceneCutSelectClip(clip dClip,clip Start,clip End,clip Both,clip Motion,Int "thSCD1",Int "thSCD2") { # (c) ssS:  https://forum.doom9.org/showthread.php?p=1955111#post1955111
    thSCD1=Default(thSCD1,400)  thSCD2=Default(thSCD2,130)
    Sup  = dClip.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    BvEos= Sup.MAnalyse(isb=True,  delta=1,blksize=16)
    FvSos= Sup.MAnalyse(isb=False, delta=1,blksize=16)
    Eos  = dClip.MSCDetection(BvEos,thSCD1=thSCD1,thSCD2=thSCD2).crop(0,0,4,4)
    Sos  = dClip.MSCDetection(FvSos,thSCD1=thSCD1,thSCD2=thSCD2).crop(0,0,4,4)
    CondS="""
        ix = (Sos.AverageLuma>0?1:0) + (Eos.AverageLuma>0?2:0)
        Return ix==0?Motion:ix==1?Start:ix==2?End:Both
    """
    ARGS="Motion,CondS,Motion,Start,End,Both,Eos,Sos"
    Motion.GSCriptClip(CondS,Args=ARGS,After_Frame=True,Local=True) # Requires Grunt
}
EDIT: Added the Crop(0,0,4,4) things.

It works sorta like ScSelect/ScSelect_HBD, but you must also Provide a "BOTH" [ie both EOS and SOS detect] clip (you can choose whatever solution you like for that possible outcome).
Code:
AviSource("D:\hard sub - 01 WEBdlRip 720p, 23.976.mkv.AVI")
dclip = BilinearResize(320,240).Blur(1.0)  # Whatever (just testing frame size can be different to other clips)
ConvertToRGB32                             # Just testing works where Dclip colorspace is differenct from the other clips.
Motion = Last
Start  = Subtitle("START",size=64,align=5)
End    = Subtitle("END",size=64,align=5)
Both   = Subtitle("BOTH",size=64,align=5)
SceneCutSelectClip(dClip,Start,End,Both,Motion,400,130)
EDIT: You will likely fire a BOTH if there is a single frame scene cut, ie an 'odd' frame that belongs neither with previous nor following scenes.
EDIT: There is at least one frame that will fire BOTH in either X-Men 1 or X-Men 2. [excluding intro where CGI flashes wildly and you cant tell where real scene changes are]
__________________
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 October 2021 at 09:57.
StainlessS is offline   Reply With Quote
Reply

Tags
denoise, despot, prefilter

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 18:18.


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