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
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 7th April 2020, 18:54   #1  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
Detecting blinking Timestamp

Heya,

I've got a captured VHS video containing a blinking timestamp.
The timestamp doesn't change since the clock-battery of the camcorder was empty. The timestamp is present for approx 1 second and absent for another second.

I want to reliably detect the timestamp when it occurs.
(When it is being detected, I'll cover it with a mask followed by interpolation stuff.)

Here you'll find a cropped example (It is field-separated VHS followed by selectevery(25,1) ):
https://easyupload.io/w0wlqw

I hope that someone is able to help me out.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.
scharfis_brain is offline   Reply With Quote
Old 7th April 2020, 20:45   #2  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,695
I've created a lot of scripts to detect big changes from one frame to the next, including detecting a photographer flash; detecting black frames; detecting dropped frames (tough, but doable); and detecting scene changes.

There are some functions that StainlessS has developed, but most of the time I find that the built-in AVISynth YDifference functions do the best job. They simply sum the difference in pixel luma value, for each pixel location to the same pixel location in an adjacent frame, either looking forward to the next frame or backwards to the previous frame.

If I were doing your job, I'd first mask the entire video, leaving only the portion where the timestamp appears. I'd then apply a YDifference function to just that small area and compare it to an adjacent frame. When the timestamp either appears or disappears, you should get a massive jump in the YDifference value.

One other thing I've done when just that simple test isn't reliable enough is to create a moving average of YDifference values and then compare the YDifference (to next or previous) to that moving average. I do this because some portions of the video have a lot of movement, and therefore the YDifference values will go up when that happens. All you are trying to do is detect when the YDifference gets large compared to what is "normal" for the nearby video.

You know what you're doing, but if you need code, you can either search on my name or I can post some code snippets.
johnmeyer is offline   Reply With Quote
Old 7th April 2020, 21:26   #3  |  Link
ChaosKing
Registered User
 
Join Date: Dec 2005
Location: Germany
Posts: 1,795
My simple attempt in Vapoursynth. Works surprisingly well except for some scenes where the clock is blending with the rest of the video like the car around frame 420
Sample https://filehorst.de/d/dgfEJadh

Code:
import vapoursynth as vs
import mvsfunc as mvf
import functools
core = vs.core

clip = core.lsmas.LWLibavSource(source=r"D:\Invalid-Timestamp.avi")

clock = mvf.ToRGB(clip)
clock = core.std.CropRel(clock, left=202, top=38, right=91, bottom=36).flux.SmoothT(temporal_threshold=9)


def NaiveDetect(n, f, clip, clock ):
	
	clip =  core.text.Text(clip, text="Min: "+str(f.props.PlaneStatsMin) 
				+"\nMax: " + str(f.props.PlaneStatsMax) 
				+"\nAvg: " + str(f.props.PlaneStatsAverage)[0:7] )
	
	if (f.props.PlaneStatsMin + f.props.PlaneStatsAverage) < 2 and  f.props.PlaneStatsMax > 210:
		return core.text.Text(clip, text="CLOCK", alignment=2)
	else:
		return clip
	
clip = clip.std.FrameEval(functools.partial(NaiveDetect, clip=clip, clock=clock), prop_src=clock.std.PlaneStats())
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth
VapourSynth Portable FATPACK || VapourSynth Database
ChaosKing is offline   Reply With Quote
Old 7th April 2020, 21:29   #4  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
Personally I would use a fixed mask without worrying about when the timestamp disappears. It's fairly narrow text, so should be hidden quite well by most delogo filters, and switching it on and off will only draw more attention to the area.
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline   Reply With Quote
Old 7th April 2020, 21:39   #5  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
@johnmeyer: I'll give that a shot.
I tried using edgemasks before. But this wasn't satisfying.

@ChaosKing: Hmm, now I have to figure out VapourSynth ;-) Newer used it before.

@wonkey_monkey: I will use Deshaker to temporally fill in the gaps. Since the footage is very shaky it will benefit from temporally unmasking the area of the timestamp when the timestamp is not present.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.

Last edited by scharfis_brain; 7th April 2020 at 21:41.
scharfis_brain is offline   Reply With Quote
Old 7th April 2020, 22:46   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
This nearly works in avs [as per CK post, but detector does not fire], needs some added chaos from the king. [I dont know VS]

What it looks like, Chaos King test area bounded by red. [Re-Done after fix, removed AverageLuma]
Code:
# Fixed with AveLuma removed
clip = AviSource(".\Invalid-Timestamp.avi").ConvertToYV24
clock = clip.Crop(202,38,-91,-36).FluxsmoothT(temporal_threshold=9)

SSS = """
    n       = current_frame                     # Frame number
    ymin    = clock.YPlaneMin                   # Testing CLOCK not clip
    ymax    = clock.YPlaneMax                   #   Ditto
    IsClock = (Ymin < 2 && Ymax > 210)
    Subtitle(String(n,"%.0f] ")+((IsClock) ? " *** CLOCK ***\n" : "\n") + String(Ymin," Mn=%3.0f") + String(Ymax," : Mx=%3.0f"),lsp=0,Font="Courier New")
    return Last
"""
clockShow=clock.Addborders(2,2,2,2,$FF0000)                           # Surround test area in red border for display
clockShow=clockShow.Addborders(0,2*20,clip.width-clockShow.width,2)   #  Add space for 2 lines of text and extend to same width as clip
clip=StackVertical(clockShow,clip)                                    # Stack display area above clip
Clip.Scriptclip(SSS)
No clock


Clock
__________________
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; 8th April 2020 at 13:58.
StainlessS is offline   Reply With Quote
Old 7th April 2020, 23:30   #7  |  Link
ChaosKing
Registered User
 
Join Date: Dec 2005
Location: Germany
Posts: 1,795
Remove the Yave and it should work

Code:
IsClock = (Ymin < 2 && Ymax > 210)  
Subtitle(String(n,"%.0f ")+((IsClock) ? " *** CLOCK ***\n" : "\n") + String(Yave,"Av=%.3f") + String(Ymin," Mn=%.3f") + String(Ymax," Mx=%.3f"),lsp=0)
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth
VapourSynth Portable FATPACK || VapourSynth Database
ChaosKing is offline   Reply With Quote
Old 7th April 2020, 23:52   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Yep works fine, thanks.

script 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 ???
StainlessS is offline   Reply With Quote
Old 8th April 2020, 00:25   #9  |  Link
ChaosKing
Registered User
 
Join Date: Dec 2005
Location: Germany
Posts: 1,795
Code:
clock = mvf.ToRGB(adjust.Tweak(clip, bright=20))

[...]
	if (f.props.PlaneStatsMin < 10 and  f.props.PlaneStatsMax > 250)
With these changes it is almost perfect... but I get different values in the avisynth version. Happy testing.
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth
VapourSynth Portable FATPACK || VapourSynth Database
ChaosKing is offline   Reply With Quote
Old 8th April 2020, 02:21   #10  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Without the tweak, seems that the artificial clock halo is always 1 [darkest pixels of it], and is the main detect item (in avs, presume other dark pixels in pic are 16->235).

EDIT: Also presume that Clock halo deliberately 1 [ie lowest without being 0], where 0 has special meaning [vertical blanking flyback or something].

EDIT: There is the occasional NON clock pixel that is also YMIn=1, eg Frame 585 (but YMAX=135 so NON detect OK).
__________________
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; 8th April 2020 at 15:57.
StainlessS is offline   Reply With Quote
Old 8th April 2020, 15:09   #11  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by StainlessS View Post
EDIT: There is the occasional NON clock pixel that is also YMIn=1, eg Frame 585 (but YMAX=135 so NON detect OK).
Dont know if my below logic is messed up or not, but think can possibly apply some additional check on CLOCK detect as per prev post using ChaosKing logic.
Seems to me that YPlaneMedian should be within a certain range given that where CLOCK present then there are a minimum number of low Luma pixels(HALO), and
also a minumum number of high luma value pixels(TEXT). So, if YPlaneMedian is below some value, or above some value, then CLOCK is not present.

Is my logic correct here, or do I need a little more sleep ??? [EDIT: If wrong then AverageLuma should be within certain range instead, or maybe both]

Here script to additionally show YPlaneMedian for current frame clock detect area, and also min and max YPlaneMedian encountered so far, and where CLOCK was detected.
On Full scan on ONLY frames where clock detected, shows minimum YPlaneMedian as 41, and max YPlaneMedian as179,
so maybe additional check to clock detect should Override to NOT CLOCK if yplanemedian is below 41 or above 179 [or massage it a bit to below (41-2)=39 and above (179+2)=181].

Code:
# Show YMedian  min and max values, and also where clock detected
clip = AviSource(".\Invalid-Timestamp.avi").ConvertToYV24
clock = clip.Crop(202,38,-91,-36).FluxsmoothT(temporal_threshold=9)

Global MEDLO= 256
Global MEDHI= -1
Global CMEDLO= 256
Global CMEDHI= -1

SSS = """
    n       = current_frame                     # Frame number
    ymin    = clock.YPlaneMin                   # Testing CLOCK not clip
    ymax    = clock.YPlaneMax                   #   Ditto
    ymed    = clock.YPlaneMedian                # Ditto
    IsClock = (Ymin < 2 && Ymax > 210)

    if(ymed<MEDLO) {
        Global MEDLO=yMed
    }
    if(ymed>MEDHI) {
        Global MEDHI=yMed
    }
    if(IsClock) {
        if(ymed<CMEDLO) {
            Global CMEDLO=yMed
        }
        if(ymed>CMEDHI) {
            Global CMEDHI=yMed
        }
    }
    Subtitle(String(n,"%.0f] ") + ((IsClock) ? " *** CLOCK ***\n" : "\n") + String(Ymin,"Mn=%3.0f") + String(Ymax," : Mx=%3.0f") + String(Ymed," : Md=%3.0f") +
    \ String(MEDLO, "\nLO=%3.0f") + String(MEDHI, " : HI=%3.0f") + "(YMedian ALL)" +
    \ String(CMEDLO,"\nLO=%3.0f") + String(CMEDHI," : HI=%3.0f") + "(YMedian CLOCK )",lsp=0,Font="Courier New")

    return Last
"""
clockShow=clock.Addborders(2,2,2,2,$FF0000)                           # Surround test area in red border for display
clockShow=clockShow.Addborders(0,4*20,clip.width-clockShow.width,2)   #  Add space for 4 lines of text and extend to same width as clip
clip=StackVertical(clockShow,clip)                                    # Stack display area above clip.
Clip.Scriptclip(SSS)
Image on full scan, last frame.


EDIT: So IsClock maybe could be detected something like this
Code:
        TOL = 2
        IsClock = (Ymin < 2 && Ymax > 210) && (YMed >= (41-TOL) && YMed <= (179+TOL))
EDIT:
Here Frame 585 where YMin=1 YMax=135, so Ymax 135<= 210 Does not detect clock, but additionally YMed=62 also would override to not detect.
EDIT: "but additionally YMed=62 also would override to not detect"
RUBBISH, would not override here, I do need some sleep.
__________________
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; 8th April 2020 at 20:21.
StainlessS is offline   Reply With Quote
Old 8th April 2020, 17:30   #12  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Experimental version with optional Overrides for YPlaneMedian and AverageLuma, also shows Flags for 'C' Clock detected[EDIT: Pre-Override], 'M' Median override enabled, 'A' AvergeLuma override enabled,
and 'O' Overriden by either of the enabled overrides. Also shows Override count so far.

EDIT: Changed Flagging for 'M' and 'A', 'M' and 'A' show if in legal Clock range and relevant Override enabled, even if 'C' clock detect flag is not shown.
Code:
# Show YMedian  min and max values, and also where clock detected
clip = AviSource(".\Invalid-Timestamp.avi").ConvertToYV24
clock = clip.Crop(202,38,-91,-36).FluxsmoothT(temporal_threshold=9)

CLK_MIN = 1                                     # YPlaneMin Below or equal possible CLOCK
CLK_MAX = 211                                   # YPlaneMax Above or equal possible CLOCK

DET_WITH_MED_TOL=true                           # Detect override using YPlaneMedian with Tolerance
MEDLOLIM = 41                                   # Min val for Clk YPlaneMedian
MEDHILIM = 179                                  # Max val for Clk YPlaneMedian
MEDTOL   = 2                                    # Additional tolerance for YPlaneMedian check

DET_WITH_AVE_TOL=true                           # Detect override using AverageLuma with Tolerance
AVELOLIM = 47.0                                 # Min val for Clk AverageLuma
AVEHILIM = 156.36                               # Max val for Clk AverageLuma
AVETOL   = 2.0                                  # Additional tolerance for AverageLuma check

# Globals, extremes encountered so far in clip
Global MEDLO= 256
Global MEDHI= -1
Global CMEDLO= 256
Global CMEDHI= -1
Global AVELO= 256
Global AVEHI= -1
Global CAVELO= 256
Global CAVEHI= -1

Global TotalClks =0                             # Count of CLOCK frames detected
Global OverrideCnt = 0                          # Count of clock detects overriden by either Median or Average

SSS = """
    n       = current_frame                     # Frame number
    ymin    = clock.YPlaneMin                   # Testing CLOCK not clip
    ymax    = clock.YPlaneMax                   #   Ditto
    ymed    = clock.YPlaneMedian                #   Ditto
    yave    = clock.AverageLuma                 #   Ditto

    IsClk    = (Ymin <= CLK_MIN && Ymax >= CLK_MAX)
    MedIsCLK = (YMed >= MEDLOLIM-MEDTOL) && (YMed <= MEDHILIM+MEDTOL)
    AveIsCLK = (YAve >= AVELOLIM-AVETOL) && (YAve <= AVEHILIM+AVETOL)

    IsClock  = IsClk && (!DET_WITH_MED_TOL || MedIsCLK) && (!DET_WITH_AVE_TOL || AveIsCLK)
    Global OverrideCnt = (IsClock!=IsClk) ? OverrideCnt + 1 : OverrideCnt            # Overriden by either Med or Ave Flagged as 'O'(some overriden)

    if(yave<AVELO) {
        Global AVELO=yave
    }
    if(yave>AVEHI) {
        Global AVEHI=yave
    }
    if(IsClock) {
        if(yave<CAVELO) {
            Global CAVELO=yMed
        }
        if(yave>CAVEHI) {
            Global CAVEHI=yave
        }
    }
    if(ymed<MEDLO) {
        Global MEDLO=yMed
    }
    if(ymed>MEDHI) {
        Global MEDHI=yMed
    }
    if(IsClock) {
        if(ymed<CMEDLO) {
            Global CMEDLO=yMed
        }
        if(ymed>CMEDHI) {
            Global CMEDHI=yMed
        }
    }

    Global TotalClks = (IsClock) ? TotalClks + 1 : TotalClks    # Incr global count if detected

    FLGS=((IsClk)?"C":"-")+((MedIsClk&&DET_WITH_MED_TOL)?"M":"-")+((AveIsClk&&DET_WITH_AVE_TOL)?"A":"-") + ((IsClock!=IsClk)?"O":"-")
    Subtitle(String(n,"%.0f] ") + FLGS + String(TotalClks," : Clks=%.0f") + ((IsClock) ? " * CLOCK *\n" : "\n") +
    \ String(Ymin,"Mn=%3.0f") + String(Ymax,":Mx=%3.0f") + String(Ymed,":Md=%3.0f") + String(Yave,":Av=%.3f") +
    \ String(MEDLO, "\nMLO=%3.0f") + String(MEDHI, ":MHI=%3.0f") + "(YMedian ALL)" +
    \ String(CMEDLO,"\nMLO=%3.0f") + String(CMEDHI,":MHI=%3.0f") + "(YMedian CLK )" +
    \ String(AVELO, "\nALO=%7.3f") + String(AVEHI, ":AHI=%7.3f") + "(YAve ALL)" +
    \ String(CAVELO,"\nALO=%7.3f") + String(CAVEHI,":AHI=%7.3f") + "(YAve CLK)" +
    \ String(OverrideCnt,"\nOverrideCnt=%.0f")
    \ ,lsp=0,Font="Courier New"
    \)

    return Last
"""
clockShow=clock.Addborders(2,2,2,2,$FF0000)                           # Surround test area in red border for display
clockShow=clockShow.Addborders(0,7*20,clip.width-clockShow.width,2)   #  Add space for 7 lines of text and extend to same width as clip
clip=StackVertical(clockShow,clip)                                    # Stack display area above clip.
Clip.Scriptclip(SSS)
On last frame, both overrides enabled [EDIT: and also both in OK non-override range], no overriden detects found. (but this is only small sample of frames).


EDIT: 2nd last frame, with clock [EDIT: and also both in OK non-override range]


EDIT: Above, cropping on detect area may have chopped off some of clock halo, if cropping changed then will need modify override numbers limits for Ymedian and Averageluma.
EDIT: Overrides so that a couple of single stray noise pixels will not upset the apple cart. [clip exhibits some VHS noise]
__________________
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; 8th April 2020 at 18:44.
StainlessS is offline   Reply With Quote
Old 8th April 2020, 18:28   #13  |  Link
ChaosKing
Registered User
 
Join Date: Dec 2005
Location: Germany
Posts: 1,795
I had another idea. What if we remove the clock with a good delogo plugin. After that a "diff-value is calculated" between the original and the delogo clip. A clock frame should then in theory show a higher diff value. Could this work?
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth
VapourSynth Portable FATPACK || VapourSynth Database

Last edited by ChaosKing; 8th April 2020 at 18:30.
ChaosKing is offline   Reply With Quote
Old 8th April 2020, 18:48   #14  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Maybe but I think your clock crop coords chop off some halo [would also need a bit of extra size for noise around clock]

EDIT: Does the YPlaneMedia override sound OK to you [methinks avergeLuma override is a bit flawed (but still seems to work)].

EDIT: YPlaneMin=1 alone, pretty much nails it most of the time [but there is VHS noise and this only small sample of frames].

EDIT: Milk is sour (EDIT: well will be tomorrow), me gotta risk goin' out to the shops, wish me luck.
__________________
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; 8th April 2020 at 20:04.
StainlessS is offline   Reply With Quote
Old 8th April 2020, 19:34   #15  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,653
Quote:
Originally Posted by StainlessS View Post
but there is VHS noise and this only small sample of frames]
I could upload an undecimated file with all 50 fields per second, if you like.


@all: Thanks for your effort! I hope I've got some time during the easter holidays to try your suggestions.
__________________
Don't forget the 'c'!

Don't PM me for technical support, please.

Last edited by scharfis_brain; 8th April 2020 at 19:48.
scharfis_brain is offline   Reply With Quote
Old 8th April 2020, 20:02   #16  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
I could upload an undecimated file with all 50 fields per second, if you like.
Please dont, me is quite happy for you to do further tests.
You can easily switch off either of the overrides.

If you change crop coords to include chopped off halo, then, switch off both overrides, and use the new limits shown in metrics,
ie above metrics CLK lines
Code:
MEDLOLIM = 41                                   # Min val for Clk YPlaneMedian
MEDHILIM = 179                                  # Max val for Clk YPlaneMedian

AVELOLIM = 47.0                                 # Min val for Clk AverageLuma
AVEHILIM = 156.36                               # Max val for Clk AverageLuma
Maybe just do scan on this small sample again, then enable Overrides and scan the full clip (see if any were overridden).

Got some milk, beer and cider, so I'm sorted for a while.

EDIT: Let us know if you had complete success, was ChaosKing detector that does the job, Nice one CK

EDIT:
Quote:
Originally Posted by StainlessS View Post
EDIT:
Here Frame 585 where YMin=1 YMax=135, so Ymax 135<= 210 Does not detect clock, but additionally YMed=62 also would override to not detect.
RUBBISH, would not override here, I do need some sleep.
Would only Override if YMin[YMin<=1] <= YMed < (MEDLOLIM-MEDTOL ie 41-2) OR (MEDHILI+MEDTOL ie 179+2) < YMed <= YMax[YMax>=211] [allowing for YMed==YMin or YMed==YMax, I think ???]
__________________
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; 8th April 2020 at 20:46.
StainlessS is offline   Reply With Quote
Old 8th April 2020, 20:52   #17  |  Link
ChaosKing
Registered User
 
Join Date: Dec 2005
Location: Germany
Posts: 1,795
I think I got it to 100% detection rate (have not found a single miss detection yet)

Code:
clip = adjust.Tweak(clip, bright=18) # propably not nececcery
clock = mvf.ToRGB(clip)

clock = core.std.CropRel(clock, left=202, top=38, right=91, bottom=36).flux.SmoothT(temporal_threshold=9)

clock_frame = clock.std.FreezeFrames(first=0, last=clip.num_frames-1, replacement=300) # our reference frame for the clock mask
clock_mask = clock_frame.std.Binarize()###.std.Inflate() make frame black & white

blank = core.std.BlankClip(clock ) # blank clip
c3 = clock.std.Prewitt() # detect edges !!
clock3 = core.std.MaskedMerge( blank, c3 ,clock_mask) # cut out everything not clock related = content around the clock


# now we use only the Avg to detect the clock. (# Min is always 0 Max most of the time 255)
   if f.props.PlaneStatsAverage > 0.22:
#  rest of the code is the same

clip = haf.Overlay(clip,mvf.ToYUV(clock3), x=200) # show the detector 
Gif https://imgur.com/a/uuYhA4n
complete sample: https://filehorst.de/d/dtqEoqbJ
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth
VapourSynth Portable FATPACK || VapourSynth Database

Last edited by ChaosKing; 8th April 2020 at 21:10.
ChaosKing is offline   Reply With Quote
Old 8th April 2020, 21:13   #18  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Looks good to me, although I have to admit to blinking more than once.
Code:
clip = AviSource(".\Invalid-Timestamp.avi").ConvertToYV24
clock = clip.Crop(202,38,-91,-36).FluxsmoothT(temporal_threshold=9)
CK=FFVideoSource(".\detect.mkv")

CLK_MIN = 1                                     # YPlaneMin Below or equal possible CLOCK
CLK_MAX = 211                                   # YPlaneMax Above or equal possible CLOCK

DET_WITH_MED_TOL=true                           # Detect override using YPlaneMedian with Tolerance
MEDLOLIM = 41                                   # Min val for Clk YPlaneMedian
MEDHILIM = 179                                  # Max val for Clk YPlaneMedian
MEDTOL   = 2                                    # Additional tolerance for YPlaneMedian check

DET_WITH_AVE_TOL=true                           # Detect override using AverageLuma with Tolerance
AVELOLIM = 47.0                                 # Min val for Clk AverageLuma
AVEHILIM = 156.36                               # Max val for Clk AverageLuma
AVETOL   = 2.0                                  # Additional tolerance for AverageLuma check

# Globals, extremes encountered so far in clip
Global MEDLO= 256
Global MEDHI= -1
Global CMEDLO= 256
Global CMEDHI= -1
Global AVELO= 256
Global AVEHI= -1
Global CAVELO= 256
Global CAVEHI= -1

Global TotalClks =0                             # Count of CLOCK frames detected
Global OverrideCnt = 0                          # Count of clock detects overriden by either Median or Average

SSS = """
    n       = current_frame                     # Frame number
    ymin    = clock.YPlaneMin                   # Testing CLOCK not clip
    ymax    = clock.YPlaneMax                   #   Ditto
    ymed    = clock.YPlaneMedian                #   Ditto
    yave    = clock.AverageLuma                 #   Ditto

    IsClk    = (Ymin <= CLK_MIN && Ymax >= CLK_MAX)
    MedIsCLK = (YMed >= MEDLOLIM-MEDTOL) && (YMed <= MEDHILIM+MEDTOL)
    AveIsCLK = (YAve >= AVELOLIM-AVETOL) && (YAve <= AVEHILIM+AVETOL)

    IsClock  = IsClk && (!DET_WITH_MED_TOL || MedIsCLK) && (!DET_WITH_AVE_TOL || AveIsCLK)
    Global OverrideCnt = (IsClock!=IsClk) ? OverrideCnt + 1 : OverrideCnt            # Overriden by either Med or Ave Flagged as 'O'(some overriden)

    if(yave<AVELO) {
        Global AVELO=yave
    }
    if(yave>AVEHI) {
        Global AVEHI=yave
    }
    if(IsClock) {
        if(yave<CAVELO) {
            Global CAVELO=yMed
        }
        if(yave>CAVEHI) {
            Global CAVEHI=yave
        }
    }
    if(ymed<MEDLO) {
        Global MEDLO=yMed
    }
    if(ymed>MEDHI) {
        Global MEDHI=yMed
    }
    if(IsClock) {
        if(ymed<CMEDLO) {
            Global CMEDLO=yMed
        }
        if(ymed>CMEDHI) {
            Global CMEDHI=yMed
        }
    }

    Global TotalClks = (IsClock) ? TotalClks + 1 : TotalClks    # Incr global count if detected

    FLGS=((IsClk)?"C":"-")+((MedIsClk&&DET_WITH_MED_TOL)?"M":"-")+((AveIsClk&&DET_WITH_AVE_TOL)?"A":"-") + ((IsClock!=IsClk)?"O":"-")
    Subtitle(String(n,"%.0f] ") + FLGS + String(TotalClks," : Clks=%.0f") + ((IsClock) ? " * CLOCK *\n" : "\n") +
    \ String(Ymin,"Mn=%3.0f") + String(Ymax,":Mx=%3.0f") + String(Ymed,":Md=%3.0f") + String(Yave,":Av=%.3f") +
    \ String(MEDLO, "\nMLO=%3.0f") + String(MEDHI, ":MHI=%3.0f") + "(YMedian ALL)" +
    \ String(CMEDLO,"\nMLO=%3.0f") + String(CMEDHI,":MHI=%3.0f") + "(YMedian CLK )" +
    \ String(AVELO, "\nALO=%7.3f") + String(AVEHI, ":AHI=%7.3f") + "(YAve ALL)" +
    \ String(CAVELO,"\nALO=%7.3f") + String(CAVEHI,":AHI=%7.3f") + "(YAve CLK)" +
    \ String(OverrideCnt,"\nOverrideCnt=%.0f")
    \ ,lsp=0,Font="Courier New"
    \)

    return Last
"""
clockShow=clock.Addborders(2,2,2,2,$FF0000)                           # Surround test area in red border for display
clockShow=clockShow.Addborders(0,7*20,clip.width-clockShow.width,2)   #  Add space for 7 lines of text and extend to same width as clip
clip=StackVertical(clockShow,clip)                                    # Stack display area above clip.

Clip.Scriptclip(SSS)

StackVertical(CK.convertToYV24.AddBorders(0,0,clip.width-clockShow.width,0),Last)
No clock [CK 100% detector on top, Taken from CK linked MKV clip]


Clock


Nice Job CK.

EDIT: I dont fancy converting that into AVS, perhaps you could do it for Scharfis
__________________
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; 8th April 2020 at 21:53.
StainlessS is offline   Reply With Quote
Old 8th April 2020, 22:46   #19  |  Link
ChaosKing
Registered User
 
Join Date: Dec 2005
Location: Germany
Posts: 1,795
AVS version incomplete.
Code:
clip = AviSource(".\Invalid-Timestamp.avi").ConvertToYV24
clip = clip.Tweak(bright = 20)
clock = clip.Crop(202,38,-91,-36).FluxsmoothT(temporal_threshold=9)

clock_frame = clock.FreezeFrame(0, clock.framecount(),300)
clock_mask = clock_frame.mt_Binarize()

blank = BlankClip(clock)
c3 = clock.mt_edge(mode="prewitt") <-- output in avs is different from vapoursynth std.Prewitt()
clock3 = mt_merge(blank, c3, clock_mask)


SSS = """
    n       = current_frame                     # Frame number
    ymin    = clock3.YPlaneMin                   # Testing CLOCK not clip
    ymax    = clock3.YPlaneMax                   #   Ditto
    yave    = clock3.AverageLuma                 #   Ditto
    IsClock = (Ymin < 30 && Ymax > 250)     # TODO
    Subtitle(String(n,"%.0f ")+((IsClock) ? " *** CLOCK ***\n" : "\n") + String(Yave,"Av=%.3f") + String(Ymin," Mn=%.3f") + String(Ymax," Mx=%.3f"),lsp=0)
    return Last
"""
clockShow=clock3.Addborders(2,2,2,2,$FF0000)                           # Surround test area in red border for display
clockShow=clockShow.Addborders(0,2*20,clip.width-clockShow.width,2)   #  Add space for 2 lines of text and extend to same width as clip
clip=StackVertical(clockShow,clip)                                    # Stack display area above clip
Clip.Scriptclip(SSS)
Does someone know what the equivalent of std.Prewitt() in Avisynth would look like?
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth
VapourSynth Portable FATPACK || VapourSynth Database
ChaosKing is offline   Reply With Quote
Old 8th April 2020, 22:57   #20  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Is it not the mt_edge thing, http://avisynth.nl/index.php/MaskTools2/Mt_edge

Quote:
mt_edge (clip, string "mode", int "thY1", int "thY2", int "thC1", int "thC2", int "Y", int "U", int "V", string "chroma", int "offX", int "offY" int "w", int "h")

# ...

string mode = "sobel"

mode chooses the 3x3 convolution kernel used for the mask computing.
There are 7 predefined kernel, "sobel", "roberts", "laplace", "cartoon", "min/max", "hprewitt", and "prewitt".
Additionally, you can also enter also a custom 3x3 kernel. The normalization factor of the kernel is automatically
computed and ceiled to the closest power of 2, to allow faster processing. You can specify your own normalization
factor by adding it to the list of coefficients ( "1 1 1 1 -8 1 1 1 1 8" for example )

# ...

"hprewitt" is equivalent to:

mt_logic(mt_edge("1 2 1 0 0 0 -1 -2 -1 1"), mt_edge("1 0 -1 2 0 -2 1 0 -1 1"), mode="max")

"prewitt" is a more robust kernel and is equivalent to:

mt_logic(mt_logic(mt_edge("1 1 0 1 0 -1 0 -1 -1 1"),mt_edge("1 1 1 0 0 0 -1 -1 -1 1"),mode="max"),mt_logic(mt_edge("1 0 -1 1 0 -1 1 0 -1 1"),mt_edge("0 -1 -1 1 0 -1 1 1 0 1"),mode="max"),mode="max")
EDIT: So something like
Code:
# c3 = clock.std.Prewitt() # detect edges !!
c3=clock.mt_edge("prewitt")
__________________
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; 8th April 2020 at 23:02.
StainlessS is offline   Reply With Quote
Reply


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


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