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 25th April 2014, 12:52   #1  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
near perfect scene change detection? (and log the frames into a textfile)

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):

Quote:
Originally Posted by Didée View Post
Quote:
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 noscenechange
The 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.
zee944 is offline   Reply With Quote
Old 25th April 2014, 18:47   #2  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,691
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
Code:
#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
Code:
#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
Code:
#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
Code:
#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)

Last edited by johnmeyer; 25th April 2014 at 19:45. Reason: MVTools2 script comments were wrong; Corrected major error re: StainlessS script
johnmeyer is offline   Reply With Quote
Old 25th April 2014, 20:18   #3  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,691
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

And here's a sample starter script that uses his code (supplied by StainlessS in that thread):

Code:
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.
johnmeyer is offline   Reply With Quote
Reply

Tags
detection, scene change

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 21:58.


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