Bull-winkle
22nd April 2006, 19:27
I have been playing around with creating log files of scene changes for a while now.
It took me a while to come up with the idea that at least in the material I have been working with the non-motion parts of the
picture change quite a bit during a scene change.
Using MaskTools v2.0a28, Masktools v1.5.8 & call.dll I have built this function.
What it is supposed to do is greate a full frame png file of the first scene represenative frame(after any dissolves or wipes are
completed),a small jpg thumbnail of the same image and a comma delimited file with:
Rendered FileName,
First Frame of Scene,
Time of scenestart,
Full Frame File Name,
Thumbnail File Name
####################################################################################################################
function AddLogLine(clip clip1,string clipname)
{
global thumbclip=PointResize(clip1,240,180)
noise=10
noise2=2
global c=clip1.ConvertToYV12().ReduceBy2().ReduceBy2()
c1a=c.mt_motion( thy1=noise,thy2=noise,thc1=noise,thc2=noise,y=3,u=1,v=1).GreyScale()
c1b=c.mt_motion( thy1=noise2,thy2=noise2,thc1=noise2,thc2=noise2,y=3,u=1,v=1).GreyScale()
global M_Mask=HysteresyMask(c1a,c1b).mt_inflate().GreyScale()
global L_Mask= mt_LUTxy(c.DuplicateFrame(0), c,expr = "x y - abs 8 > 255 0 ?", y=3, u=1, v=3).GreyScale()
global S_Mask=mt_logic(M_Mask,L_Mask,"andn")
global clip1name=clipname
global LastChanged = 0
global FirstChanged = 1
global FirstUnChanged = 2
global ThisFrameDifference=0.0
global ThisFrameChanged=false
global FrameToWrite=0
global WriteThisFrame=false
global LThreshHold=1
global MinChangeTimeThreshHold=0.5
global Framefolder = leftstr(clip1name,strlen(clip1name)-4) +"\"
global Thumbfolder = FrameFolder +"Thumbs\"
global scenelog = FrameFolder + "scenelog.csv"
global writeline =""
Global LastChecked=0
CallCmd="cmd /c md '" + thumbfolder +"'"
call(blankclip,callcmd,"-2")
clip1=clip1.WriteFileStart(scenelog,""" "VideoFileName,FrameToWrite,Time,FrameName,ThumbName" """,False)
global WriteFrame = "(WriteThisFrame) ? ImageWriter(ConvertToRGB(), "+chr(34)+ FrameFolder + "Frame-" +chr(34)+
\", Current_Frame , Current_Frame, "+chr(34)+ "png"+chr(34)+").RGBDifferenceFromPrevious() : Nop()"
global WriteThumb = "(WriteThisFrame) ? ImageWriter(thumbclip, "+chr(34)+ ThumbFolder + "Thumb-" +chr(34)+
\", Current_Frame , Current_Frame, "+chr(34)+ "jpg"+chr(34)+").RGBDifferenceFromPrevious() : Nop()"
clip1=clip1.frameevaluate(WriteFrame, show=false)
clip1=clip1.frameevaluate(WriteThumb, show=false)
clip1=clip1.frameevaluate("""
ThisFrameDifference=S_Mask.averageLuma()
ThisFrameChanged=((Current_Frame==1)
\||(ThisFrameDifference>LThreshHold))
\?true:false
FirstChanged=((ThisFrameChanged==true)
\ && (LastChanged<(Current_Frame-int(MinChangeTimeThreshHold*c.Framerate())))
\)?Current_Frame:FirstChanged
LastChanged=(ThisFrameChanged)?Current_Frame:LastChanged
FirstUnchanged=((ThisFrameChanged==False)
\ && (LastChanged > (Current_Frame-int(MinChangeTimeThreshHold*c.Framerate())))
\ && (FirstUnchanged < (Current_Frame-int(MinChangeTimeThreshHold*c.Framerate())))
\)? Current_Frame : FirstUnchanged
LastChecked = ((LastChecked>(c.Framecount()-1))&&(LastChecked>=Current_Frame))?LastChecked:Current_Frame
WriteThisFrame=((FirstUnchanged==Current_Frame) && (ThisFrameChanged==False) && (LastChecked!=(c.Framecount()-1)))?True:False
FrametoWrite=FirstChanged
WriteLine= "" + clip1name
\+ "," + string(FrametoWrite)
\+ "," + string(timeformat(FirstChanged / c.Framerate()))
\+ "," + FrameFolder + "Frame-" + string(Current_Frame,"%06.0f") + ".png"
\+ "," + ThumbFolder + "Thumb-" + string(Current_Frame,"%06.0f") + ".jpg"
""") #Closes Frame Evaluate
clip1 = clip1.WriteFileif(scenelog," WriteThisFrame "," writeline ",true,true)
clip1 = clip1.WriteFileif(scenelog," (Current_Frame==c.Framecount()-1)",""" "" + clip1name
\+ "," + string(c.Framecount())
\+ "," + string(timeformat(c.Framecount() / c.Framerate()))
\+ "," + "Last Frame" """,true)
return clip1
}
##########################################################################################
I am working on using the resultant files to create something like a graphical DVD Menu in Flash 8
This script is a little slow but not horribly so. I suspect by fixing some of my faulty logic and perhaps delving into C++ and
making some of this work directly in a plugin, speed may increase.
One note: mt_hysteresis crashed for me which is why I use the masktools 1.5.8 for this function
I would appreciate any feedback - particularly as to how to streamline this
Thanks
It took me a while to come up with the idea that at least in the material I have been working with the non-motion parts of the
picture change quite a bit during a scene change.
Using MaskTools v2.0a28, Masktools v1.5.8 & call.dll I have built this function.
What it is supposed to do is greate a full frame png file of the first scene represenative frame(after any dissolves or wipes are
completed),a small jpg thumbnail of the same image and a comma delimited file with:
Rendered FileName,
First Frame of Scene,
Time of scenestart,
Full Frame File Name,
Thumbnail File Name
####################################################################################################################
function AddLogLine(clip clip1,string clipname)
{
global thumbclip=PointResize(clip1,240,180)
noise=10
noise2=2
global c=clip1.ConvertToYV12().ReduceBy2().ReduceBy2()
c1a=c.mt_motion( thy1=noise,thy2=noise,thc1=noise,thc2=noise,y=3,u=1,v=1).GreyScale()
c1b=c.mt_motion( thy1=noise2,thy2=noise2,thc1=noise2,thc2=noise2,y=3,u=1,v=1).GreyScale()
global M_Mask=HysteresyMask(c1a,c1b).mt_inflate().GreyScale()
global L_Mask= mt_LUTxy(c.DuplicateFrame(0), c,expr = "x y - abs 8 > 255 0 ?", y=3, u=1, v=3).GreyScale()
global S_Mask=mt_logic(M_Mask,L_Mask,"andn")
global clip1name=clipname
global LastChanged = 0
global FirstChanged = 1
global FirstUnChanged = 2
global ThisFrameDifference=0.0
global ThisFrameChanged=false
global FrameToWrite=0
global WriteThisFrame=false
global LThreshHold=1
global MinChangeTimeThreshHold=0.5
global Framefolder = leftstr(clip1name,strlen(clip1name)-4) +"\"
global Thumbfolder = FrameFolder +"Thumbs\"
global scenelog = FrameFolder + "scenelog.csv"
global writeline =""
Global LastChecked=0
CallCmd="cmd /c md '" + thumbfolder +"'"
call(blankclip,callcmd,"-2")
clip1=clip1.WriteFileStart(scenelog,""" "VideoFileName,FrameToWrite,Time,FrameName,ThumbName" """,False)
global WriteFrame = "(WriteThisFrame) ? ImageWriter(ConvertToRGB(), "+chr(34)+ FrameFolder + "Frame-" +chr(34)+
\", Current_Frame , Current_Frame, "+chr(34)+ "png"+chr(34)+").RGBDifferenceFromPrevious() : Nop()"
global WriteThumb = "(WriteThisFrame) ? ImageWriter(thumbclip, "+chr(34)+ ThumbFolder + "Thumb-" +chr(34)+
\", Current_Frame , Current_Frame, "+chr(34)+ "jpg"+chr(34)+").RGBDifferenceFromPrevious() : Nop()"
clip1=clip1.frameevaluate(WriteFrame, show=false)
clip1=clip1.frameevaluate(WriteThumb, show=false)
clip1=clip1.frameevaluate("""
ThisFrameDifference=S_Mask.averageLuma()
ThisFrameChanged=((Current_Frame==1)
\||(ThisFrameDifference>LThreshHold))
\?true:false
FirstChanged=((ThisFrameChanged==true)
\ && (LastChanged<(Current_Frame-int(MinChangeTimeThreshHold*c.Framerate())))
\)?Current_Frame:FirstChanged
LastChanged=(ThisFrameChanged)?Current_Frame:LastChanged
FirstUnchanged=((ThisFrameChanged==False)
\ && (LastChanged > (Current_Frame-int(MinChangeTimeThreshHold*c.Framerate())))
\ && (FirstUnchanged < (Current_Frame-int(MinChangeTimeThreshHold*c.Framerate())))
\)? Current_Frame : FirstUnchanged
LastChecked = ((LastChecked>(c.Framecount()-1))&&(LastChecked>=Current_Frame))?LastChecked:Current_Frame
WriteThisFrame=((FirstUnchanged==Current_Frame) && (ThisFrameChanged==False) && (LastChecked!=(c.Framecount()-1)))?True:False
FrametoWrite=FirstChanged
WriteLine= "" + clip1name
\+ "," + string(FrametoWrite)
\+ "," + string(timeformat(FirstChanged / c.Framerate()))
\+ "," + FrameFolder + "Frame-" + string(Current_Frame,"%06.0f") + ".png"
\+ "," + ThumbFolder + "Thumb-" + string(Current_Frame,"%06.0f") + ".jpg"
""") #Closes Frame Evaluate
clip1 = clip1.WriteFileif(scenelog," WriteThisFrame "," writeline ",true,true)
clip1 = clip1.WriteFileif(scenelog," (Current_Frame==c.Framecount()-1)",""" "" + clip1name
\+ "," + string(c.Framecount())
\+ "," + string(timeformat(c.Framecount() / c.Framerate()))
\+ "," + "Last Frame" """,true)
return clip1
}
##########################################################################################
I am working on using the resultant files to create something like a graphical DVD Menu in Flash 8
This script is a little slow but not horribly so. I suspect by fixing some of my faulty logic and perhaps delving into C++ and
making some of this work directly in a plugin, speed may increase.
One note: mt_hysteresis crashed for me which is why I use the masktools 1.5.8 for this function
I would appreciate any feedback - particularly as to how to streamline this
Thanks