zee944
25th April 2014, 12:52
I remember a few years ago Didée shared or discussed a near perfect scene change detection script, but now - although I've found a fair amount of threads discussing the matter - I can't find it. Does anyone remember that and willing to share?
Possibly it was a combination of threshold and motion analysis, along this line (but I'm not sure):
Scharfis brain wrote:
"scene changes can be detected in an automated way using AVIsynth:
- create a motionmask
- calculate the averageluma x()
- if [x(c) > x(p) * fac + off] AND [x(c) > x(n) * fac + off] then scenechange else noscenechangeThe harder way is trying to implement this. (Okay, it's not THAT hard, but still....)
The easier way is to load RemoveDirt.dll, and simply use the SCSelect() filter. ;)
johnmeyer
25th April 2014, 18:47
There is no "near perfect" scene detection because they all can be fooled by things like a person entering the scene quickly, close to the camera.
However, I did a search of this forum about two months ago, looking to improve scene detection for a project I was working on. I came up with four different approaches to the problem. Here they are. None is better or best, that's for sure. I was very intrigued by the script that uses some new code that StainlessS created a few months ago [edit] I thought I posted that script below, but it turns out it was the RemoveDirt scene detection -- I'll try to post the StainlessS-based scene detection later.[/end edit]
In every script, you must "tune" the script to match your video footage. In the following examples, I have the script set to put the detection variable on screen. When you actually run the script to detect scenes, you comment out the line(s) that display detection numbers, and un-comment the "WriteFile" line(s).
Simple Scene Detection Using YDifference
#Script to find scene changes
filename = "e:\scenes.txt"
global blankthreshold=2.0
source = AVISource("e:\fs.avi").convertTOYV12().killaudio()
#Comment out the following lines after blankthreshold has been determined
script = """Subtitle("\nNext/Prev = " + String( YDifferenceToNext(last) \
/ YDifferenceFromPrevious(last) ), lsp=0)"""
final = ScriptClip(source,script)
return final
#Uncomment the following two lines when doing the actual scene detection
#WriteFileIf(source, filename, "(YDifferenceToNext(last) / \
# YDifferenceFromPrevious(last)>blankthreshold)", "current_frame+1", append = false)
Scene Detection Using MVTools2
#Script to find scene changes
Loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools2.dll")
filename = "e:\scenes.txt"
BlockChangeThresh = 350 # Default: 350. Increase to reduce number of scenes detected;
# Determines whether a block has changed from prev frame.
Num_blocks_changed = 90 # Default: 90. Increase to reduce number of scenes detected;
# How many changed blocks (given threshhold) must change to trigger scene change
source=AVISource("e:\fs.avi").killaudio().colorYUV(autogain=true) #add this to increase contrast
source_fields=source.separatefields().selecteven().convertTOYV12(interlaced=false)
source_super = source_fields.MSuper(pel=2, sharp=0)
backward_vec = MAnalyse(source_super,isb = true, delta = 1, blksize=16,search=0)
SceneChange = MSCDetection (source_fields, backward_vec,thSCD1=BlockChangeThresh,thSCD2=Num_blocks_changed)
#Uncomment following line for troubleshooting. It puts the scene change threshold numbers on the screen.
ScriptClip(source_fields,"Subtitle(String(AverageLuma(SceneChange ) ),align=5)")
#This line writes frame numbers to file. These can be imported into Vegas or other editor
#WriteFileIf(source_fields,filename, "(AverageLuma(SceneChange)>30)" , "current_frame+1", flush=false)
Scene Detection Using Depanestimate
#Script to find scene changes
loadPlugin("c:\Program Files\AviSynth 2.5\plugins\depanestimate.dll")
loadPlugin("c:\Program Files\AviSynth 2.5\plugins\depan.dll")
filename = "e:\scenes.txt"
AVISource("e:\fs.avi").convertTOYV12(interlaced=true).killaudio()
separatefields().selecteven().convertTOYV12(interlaced=false)
#The "trust" parameter is what determines the scene change threshold.
#Lower number results in fewer scenes.
data=DepanScenes( DepanEstimate(trust=2) )
#Uncomment following line to help determine "trust" value.
ScriptClip("Subtitle(String(AverageLuma(data ) ),align=5)")
#WriteFileIf(filename, "(AverageLuma(data)>30)" , "current_frame", flush=false)
Scene Detection Using Remove Dirt
#Script to find scene changes
filename = "e:\scenes.txt"
Scene_Thresh = 2.0 #Higher number = more scenes
AVISource("e:\fs.avi").ConvertToYV12()
Begin = Blackness(last)
End=Subtitle("END OF SCENE", align=1,size=30)
Motion=Subtitle("GLOBAL MOTION",align=5,size=30)
#ScriptClip("Subtitle(String(SCSelect(Last,BlackFrame) ),align=5)")
scene_change = SCSelect(Last,Begin,End,Motion,Dfactor=Scene_Thresh )
#Remove comment to see scene change numbers
ScriptClip("Subtitle(String(AverageLuma(scene_change ) ),align=5)")
#Uncomment next line to actually create scene change numbers
#WriteFileIf(filename, "AverageLuma(scene_change )<17" , "current_frame", flush=false)
johnmeyer
25th April 2014, 20:18
I don't have time to completely reconstruct what I did with StainlessS' scene detection, but here's the link to the thread where he introduced the concept:
AVS script to detect and log scene changes (http://forum.doom9.org/showthread.php?t=168697)
And here's a sample starter script that uses his code (supplied by StainlessS in that thread):
AVISource("e:\fs.avi") #.Trim(32,0)
Import("C:\Program Files\AviSynth 2.5\plugins\Dynacrop.avs")
Avisource("e:\fs.avi").separatefields()
DClip=Last
Start=Last
End=Last
Motion=Last
SC_SceneSelect(dclip,start,end,motion,show=true,dfact=4.0,minim=4.0,Bias=0.0,gain=1.0,cont=1.0,rpow=1.0,spow=1.0,SPMid=0.5,pord=false)
I don't have time now to play around with the settings in order to tell you which ones you have to tune. I have used essentially the same plugin to create a motion detection script for security cameras (StainlessS did all the work), and it worked unbelievably well. Scene change detection is a related, but different problem, and I don't know if this code can, or cannot, be tuned to achieve results that are as remarkable as what I got with the security camera movement detection. I did just test the above code with some OTA footage, and it worked pretty well, but clearly still needed some tuning.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.