Log in

View Full Version : My function to find the static/snow and blue screen from captured tapes.


mkanel
8th September 2004, 12:52
I wrote this function to find the static/snow and blue screen frames that occur during gaps between recordings on an analog tape. It's slow, about 20 fps on my PIII 933mhz computer. You'll need Avisynth 2.55 or newer to use this.

To use it make a file with a text editor called anything.avsi (ex. findjunk.avsi) cut and paste from the code section below to your new avsi file and put the file in the Avisynth plugin directory. When used it will write a bunch of trims to two files, goodframes.txt and badframes.txt. The idea is to use goodframes.txt for processing the video. Badframes.txt is only to verify that the cut frames are really junk frames. The junkframes also include an overlap of 3 goodframes just to make sure the trim is in about the right place. Notepad shouldn't be used to view the text files because notepad doesn't understand the formatting commands. Wordpad works fine and so should most other editors.

The first argument is a prefix for the output files. The following script would output MyVideoGoodframes.txt and MyVideoBadFrames.txt

Avisource=("c:\some.avi")
FindJunk(prefix="MyVideo")

The second argument changes the path, make sure to include the last "\", the defuault is "c:\"
findjunk(path="C:\somefolder\"). It would probably be easier just to change the default value in the avsi.

The last two variables firstgood and lastgood change the frame where the cut between good frames and bad frames occur they're positive or negative intergers, -1 moves the cutframe forward one frame. The default is zero.

It works best if you scroll to the first frame of your video in VirtualDubMod and then do a refresh F5, and then preview output from start ctrl-F5. If you start the preview from somewhere in the middle of the video you'll likely get some unfinished trim commands in the output text files, they should still be useable after a little manual tweaking.

You can put the output files into your AVS script with cut and paste or with import.

Avisource=("c:\some.avi")
import ("C:\GoodFrames.txt")

That should be enough to use it, it works for me but I'm assuming that blue screen and snow/static is similar on most videotape.

Here's the script
function findjunk(clip c, string "prefix", string "path",int "firstgood", int "lastgood")
{
prefix=default(prefix,"")
path=default(path,"c:\") #change your default path here
global firstgood=default(firstgood,0) #change default cut positions
global lastgood=default(lastgood,0) #change default cut positions
c=c.converttoyv12
count = name(2,prefix,path)
BadFile= (exist(path+prefix+"badframes.txt")||exist(path+prefix+"goodframes.txt")) \
?path+prefix+"badframes"+string(count)+".txt" : path+prefix+"badframes.txt"
GoodFile= (exist(path+prefix+"goodframes.txt")||exist(path+prefix+"badframes.txt")) \
?path+prefix+"goodframes"+string(count)+".txt" : path+prefix+"goodframes.txt"
WriteFileStart(c,BadFile,""" "showframenumber" """)
WriteFileStart(last,GoodFile, """ "#Trims of good frames" """)

global needtrim = false
global newtext = ""
global FindNext_Good2_Bad1=0 #1=Find next junk, 2=find next useable, 0=check first frame
global useabletrims = ""
global junktrims = ""
global transitiontrims = ""
global futureblue=last.trim(3,0)
global count=-1
global goodframe = true
Junk=ScriptClip(c,"maketrims(last, current_frame, averageluma, averagechromau, goodframe)")
Conditionalfilter(last, Junk, c, "NeedTrim", "=", "true" , show = false)
WriteFileIf(last,BadFile, "strlen(junktrims)>75 && needtrim==true","junktrims")

FrameEvaluate(last,"NeedTrim = current_frame==framecount-3 \
|| (FindNext_Good2_Bad1 == 1 && GoodFrame==false) \
|| (FindNext_Good2_Bad1 == 2 && GoodFrame==true && AverageChromaU(futureblue)<200) \
|| FindNext_Good2_Bad1 ==0 \
? true : false",after_frame=true)

FrameEvaluate(last,"GoodFrame = AverageChromaU()>200 \
|| (AverageLuma>215 && YDifferenceFromPrevious>30 && YDifferenceToNext>30 && UPlaneMin>20) \
?false :true")

subtitle("") # needed to catch a single frame of smow ???.
WriteFileIf(last,GoodFile, "current_frame==framecount-2","leftstr(useabletrims,strlen(useableTrims)-3)", \
"chr(13)",""" "#Completed " """, """ time(" %c") ""","chr(13)","chr(13)" )
last.converttoyuy2 #speed up the script by removing this conversion if able.
}

function name(int count, string prefix,string path)
{
return exist(path+prefix+"goodframes"+string(count)+".txt")\
||exist(path+prefix+"badframes"+string(count)+".txt") ?name(count+1,prefix,path) : count
}

function maketrims(clip c, int frame, float luma, float chroma, bool goodframe)
{
JunkTrims = (strlen(junktrims)>80) ?" \++" :junktrims
UseableTrims = (FindNext_Good2_Bad1==1 && 2<frame<framecount(c)-2) \
?UseableTrims + "," + string(frame-4+lastgood) + ") ++ ": UseableTrims
JunkTrims = (FindNext_Good2_Bad1==2 && 2<frame<framecount(c)-2) \
?JunkTrims + "," + string(frame-1+firstgood) + ").subtitle("+chr(34) + "JUNK"+chr(34) \
+ ",x=-1,size=34) ++ " + "Trim(" + string(frame+firstgood) + "," + string(frame+2+firstgood) \
+ ").subtitle("+chr(34) + "GOOD" + chr(34) + ",x=-1,size=34)" + " ++ Trim(0,-1).blankclip" \
: JunkTrims
UseableTrims = (FindNext_Good2_Bad1==2 && 8<count<11 && 2<frame<framecount(c)-2 ) \
?chr(13) + " \" + UseableTrims :UseableTrims
UseableTrims = (FindNext_Good2_Bad1==2 && 2<frame<framecount(c)-2) \
?UseableTrims + "Trim(" + string(frame+firstgood) : UseableTrims
JunkTrims = (FindNext_Good2_Bad1==1 && frame<framecount(c)-2) ?JunkTrims + \
"Trim(" + string(frame-6+lastgood)+ "," + string(frame-4+lastgood) + \
").subtitle("+chr(34) + "GOOD"+chr(34) + ",x=-1,size=34) ++ " \
+ "Trim(" + string(frame-3+lastgood) : JunkTrims
UseableTrims = (FindNext_Good2_Bad1==0 && GoodFrame==true) ?UseableTrims + "Trim(0" : UseableTrims
JunkTrims = (FindNext_Good2_Bad1==0 && GoodFrame==false) ?JunkTrims + "Trim(0" : JunkTrims
global UseableTrims = (frame >=framecount(c)-2 && FindNext_Good2_Bad1==1) ?UseableTrims + ",0) ++" \
: UseableTrims
global JunkTrims = (frame >=framecount(c)-2 && FindNext_Good2_Bad1==2) ?JunkTrims + \
",0).subtitle("+chr(34) + "JUNK"+chr(34) + ",x=-1,size=34)" : JunkTrims
FindNext_Good2_Bad1 = (FindNext_Good2_Bad1==2) ?1 :2
FindNext_Good2_Bad1 = (FindNext_Good2_Bad1==0 && GoodFrame==true) ?1 :FindNext_Good2_Bad1
global FindNext_Good2_Bad1 = (FindNext_Good2_Bad1==0 && GoodFrame==false) ?2 :FindNext_Good2_Bad1
global count= (count==10) ?1 : count+1

return c
}


function MoreInfo(clip c)
{

global v=c.ConvertToYV12 # we need YV12
last=v

ScriptClip("Subtitle ((String(AverageLuma(v))),x=150,y=25) ")
subtitle("AverageLuma",y=25)
ScriptClip("Subtitle ((String(AverageChromaU(v))),x=150,y=50) ")
subtitle("AverageChromaU",y=50)
ScriptClip("Subtitle ((String(AverageChromaV(v))),x=150,y=75) ")
subtitle("AverageChromaV",y=75)
ScriptClip("Subtitle ((String(YPlaneMedian(v))),x=150,y=100) ")
subtitle("YPlaneMedian",y=100)
ScriptClip("Subtitle ((String(UPlaneMedian(v))),x=150,y=125) ")
subtitle("UPlaneMedian",y=125)
ScriptClip("Subtitle ((String(VPlaneMedian(v))),x=150,y=150) ")
subtitle("VPlaneMedian",y=150)
##################################################
ScriptClip("Subtitle ((String(YPlaneMax(v))),x=400,y=25) ")
subtitle("YPlaneMax",x=300,y=25)
ScriptClip("Subtitle ((String(UPlaneMax(v))),x=400,y=50) ")
subtitle("UPlaneMax",x=300,y=50)
ScriptClip("Subtitle ((String(VPlaneMax(v))),x=400,y=75) ")
subtitle("VPlaneMax",x=300,y=75)
ScriptClip("Subtitle ((String(YPlaneMin(v))),x=400,y=100) ")
subtitle("YPlaneMin",x=300,y=100)
ScriptClip("Subtitle ((String(UPlaneMin(v))),x=400,y=125) ")
subtitle("UPlaneMin",x=300,y=125)
ScriptClip("Subtitle ((String(VPlaneMin(v))),x=400,y=150) ")
subtitle("VPlaneMin",x=300,y=150)
#####################################################
ScriptClip("Subtitle ((String(YDifferenceFromPrevious(v))),x=185,y=175) ")
subtitle("YDifferenceFromPrev",y=175)
ScriptClip("Subtitle ((String(UDifferenceFromPrevious(v))),x=185,y=200) ")
subtitle("UDifferenceFromPrev",y=200)
ScriptClip("Subtitle ((String(VDifferenceFromPrevious(v))),x=185,y=225) ")
subtitle("VDifferenceFromPrev",y=225)
#####################################################
ScriptClip("Subtitle ((String(YDifferenceToNext(v))),x=455,y=175) ")
subtitle("YDifferenceToNext",x=300,y=175)
ScriptClip("Subtitle ((String(UDifferenceToNext(v))),x=455,y=200) ")
subtitle("UDifferenceToNext",x=300,y=200)
ScriptClip("Subtitle ((String(VDifferenceToNext(v))),x=455,y=225) ")
subtitle("VDifferenceToNext",x=300,y=225)



ConvertToYUY2
}




In case anyone would like to improve this I'm providing more details below, it's pretty messy and if the idea has merit it might be easier to just start from scratch than use my script, but here goes.

First the script decides if the first frame is good or junk. If it finds junk it starts looking for the next good frame or visa versa, once it finds a good frame it notes the location and starts looking for a junk frame and so on. Defining junk is the interesting part and I have added more conditions as I have encountered false positives for junk. So far blue screen has been easiest with no false positives, I look for a frame with an AverageChromaU greater than 200, I haven't had any false positives yet with that setting. To find static/snow I look for an AverageLuma greater than 215, unfortunately beach scenes normally trigger this. YDifferenceToNext is low on beach scenes but high on static/snow so I look for YDifferenceToNext, YDifferenceFromPrevious of greater than 30, I check both next and previous to prevent a false positive if there's a duplicate beach scene. I've also had a few false positive where the AverageLuma is way too high for just a few frames, I don't know if t!
his is caused by the camera or the operator but I don't want to trim these scenes if only because it would chop up the audio, they happen to have a lower UPlaneMin, if it's less than 20 it's deemed not junk. The last trick is not to identify the transition between static/snow and the blue frames as good frames, on my captures as the snow morphs into blue it loses it's "junkiness", so if I'm looking for and find a good frame I peek ahead three frames to see if that frame is blue, if so the current frame is still considered junk and the search for the next good frame continues.

One of the functions with FindJunk is MoreInfo, a horribly slow function but it gives you lots of parameters that you can use when testing a frame for "junkiness", you can use it if you're getting false positives for junk or to find your own way of determining what's junk.

The goodframe trims are stored in the variable goodfile and are written at the end of processing the video. Badframe trims are stored in badfile and written at various times during processing. I tried to use the same method for badfile as goodfile but the variable soon contained to many characters and caused a crash. The same could possibly happen to goodfile in a video with many gaps.

I hope it's useful to someone else. Mike.

tsp
8th September 2004, 15:29
To detect white noise as this (http://www.tsp.person.dk/frame1.jpg) and similar I use this function:


global a = DEdgeMask(last,thY1=75,thY2=75,thC1=100,thC2=100 ).expand()
WriteFileIf(a, "badframes.txt", "AverageLuma(a)>1", "current_frame")


It requires masktools but is quite sensitive to static. I still need to find a easy way to make the trim part without manual editing but with your script I think it will work.

mkanel
8th September 2004, 18:52
Tsp,

Thanks for the input. I've never used masktools but I wouldn't mind finding a simpler or faster way to detect static or white noise. I downloaded masktools and tested it with this simple script borrowing the DEdgeMask from your post. Moreinfo is a function in the script I posted above.


AVISource("D:\Static.avi").converttoyv12
DEdgeMask(last,thY1=75,thY2=75,thC1=100,thC2=100 ).expand()
moreinfo


In your script it looks like white noise is any frame that has an AverageLuma>1. Many of my good frames have an AverageLuma>1 after applying DEdgeMask. Did I do something wrong? Is there a typo in my DEdgeMask line or yours? If I use this as currently written it will consider many of my "good" frames as junk. Since it works for you I'd be happy to test it again if you have any ideas.

tsp
8th September 2004, 21:16
Well it's not a typo. It works well with my vhs source but you can try to change thY and thC to a higher value or try to increase the average luma that is considered noise to a value greater than 1 if the frames width static have a higher value than the good frames. The vhs-machine I use is a JVC HR-S 7960 and it has a digital noise filter that maybe smooths the edges in the good frames. You could try a temporal or spatial noisefilter before applying the edgemask if increasing the threshold isn't sufficient.

mkanel
8th September 2004, 21:51
tsp,


I was trying to test it without doing my homework, I guess I'll have to read the documentation that comes with MaskTools to see what it's all about. The fact that it works as is with your VHS tape but not with my Super8 video makes me wonder if my snow definitions will work with most analog video as I had hoped or just my particular source. Thanks again for the input. Mike.

mkanel
9th September 2004, 16:02
tsp,
After tweaking the thresholds fom my video I was able to make masktools work for finding static by changing thY1 to 140. I haven't tested it on some of the trickier footage like beach scenes. It slows down the script by about 30% so I think I'll stick with my current method of detecting static but if my script might be useful to you you can modify it to use masktools.

Just add this line near the top of the script below the first "{"


{
c=c.DEdgeMask(thY1=75,thY2=75,thC1=100,thC2=100 ).expand()#Add this line
prefix=default(prefix,"")

And change this
FrameEvaluate(last,"NeedTrim = current_frame==framecount-3 \
|| (FindNext_Good2_Bad1 == 1 && GoodFrame==false) \
|| (FindNext_Good2_Bad1 == 2 && GoodFrame==true && AverageChromaU(futureblue)<200) \
|| FindNext_Good2_Bad1 ==0 \
? true : false",after_frame=true)

FrameEvaluate(last,"GoodFrame = AverageChromaU()>200 \
|| (AverageLuma>215 && YDifferenceFromPrevious>30 && YDifferenceToNext>30 && UPlaneMin>20) \
?false :true")


To this
FrameEvaluate(last,"NeedTrim = current_frame==framecount-3 \
|| (FindNext_Good2_Bad1 == 1 && GoodFrame==false) \
|| (FindNext_Good2_Bad1 == 2 && GoodFrame==true) \
|| FindNext_Good2_Bad1 ==0 \
? true : false",after_frame=true)

FrameEvaluate(last,"GoodFrame = AverageLuma>215 ?false :true")


I took out the test for blue frames for the sake of simplicity. Maybe a better option for this would be to only look for blue frames assuming that most tape players now produce blue frames when finding static. Mine plays about 12 frames of static and then switches to blue frames, one could just set the cut point 12 frames prior to the first detected blue frame, you'd miss very short static only gaps (in my case 12 frames or less) but that's probably not a big deal.

tsp
9th September 2004, 21:04
Because the mask functions are so slow you could consider using them only as an extra test on the bad frames to avoid false positive bad frames. It will of course only work if the mask function detects the good frames when the ordinary functions don't. I think it will work because the noise detecting principle is different. Masktools the very strong edges in the static noise and the luma functions detects well the luma difference. Also I’m working on a small program that can decode a file with the frame numbers of bad frames to an avs file to avoid spending time on this in the filter. This ought to speed your script up.

mkanel
9th September 2004, 22:07
Because the mask functions are so slow you could consider using them only as an extra test on the bad frames to avoid false positive bad frames. It will of course only work if the mask function detects the good frames when the ordinary functions don't.

That's a good idea, I'm sure I'll encounter other false positives as I process more video, this could be useful in the bag of tricks to tease out the good frames.

I'll be interested in trying out your program too.

I think I've attached a zip file with FindJunk.avsi in it. If anyone wants to test it just unzip it to your avisynth plugin directory.

tsp
10th September 2004, 01:42
well I completed the first version of the the program. I call it trim maker. It's a quick and dirty program but it works. You can get it here (http://tsp.person.dk/trimmaker.zip). It should make it possible to simplify your script a lot.

ADLANCAS
10th September 2004, 04:08
Interesting ideas!
I´ll give a try maybe in this weekend.

Alexandre

mkanel
10th September 2004, 12:49
tsp,

Thanks for posting trimmaker so fast. Your method is somewhat different from mine but it works. Since I'm naturally biased to my own creation there are some aspects of my method that I prefer. I also see a couple of current advantages to your method and maybe some future advantages.

By my method I like the badfile.txt output format, it's a good way to make sure only junk has been deleted and to manually tweak it if needed. It shows all the frame numbers referenced to the source video and adds three good frames to the front and back of a sequence of junk frames, it labels good frames "GOOD" and junk frames "JUNK". Here's a sample of the output in badframes.txt in case you want to paste it into an AVS script just to get and idea of what it looks like. It's probably something trimmaker could do in the future if it's useful.

showframenumber
Trim(13,15).subtitle("GOOD",x=-1,size=34) ++ Trim(16,22).subtitle("JUNK",x=-1,size=34) ++ Trim(23,25).subtitle("GOOD",x=-1,size=34) ++ Trim(0,-1).blankclip
\++Trim(138,140).subtitle("GOOD",x=-1,size=34)++Trim(141,144).subtitle("JUNK",x=-1,size=34)++Trim(145,147).subtitle("GOOD",x=-1,size=34)++Trim(0,-1).blankclip
\++Trim(151,153).subtitle("GOOD",x=-1,size=34) ++ Trim(154,0).subtitle("JUNK",x=-1,size=34)


This junk output might be irrelevant if over time the definitions of junk can be improved to the point where we can always trust the output.

What I like about your method is that it makes tweaking the junk definitions much easier, if others are interested in the niche use of avisynth maybe eventually a standard definition(s) of junk could be developed. Maybe each source could have a standard junk definition template. My script is busy, to say the least, yours makes the junk definitions obvious. With your method or mine it's time consuming to process a long video. With yours if the cut or offset points were chosen poorly it can be remedied quickly with your trimmaker, with mine the tweaking would have to be done manually or you would have to wait out the entire processing phase again.

I realize this is your first rendition of trimmaker, I don't know visual basic (or any other programming language) but I assume it could be developed further. Possibly it could write the first avs script with the junk definitions (much like AVISynthesizer) maybe it could even launch VirtualDub to process the AVS. Eventually maybe it could be a one click solution to creating the final AVS with all the trims. I won't go on but the point is trimmaker could has room to grow.

Speaking of finding junk, I accused your DEdgeMask method of too many false positives, well it was a random piece of video that I tested and as it turns out it caused false positives with my method too, I was able too tweak your setting to eliminate the false positive and still find the real junk. Again I like your idea of using mask tools as a means to tease out the false positives for junk from the real positives.

If I find the magic bullet for junk definitions, or have any other bright ideas I'll let you know. Mike.

mkanel
10th September 2004, 14:54
tsp,

Getting back to a more basic problem of defining what is static. While testing your masktools method of static detection I did a quick capture of some video that had been recorded to a type of tape I hadn't used before, metal evaporated. Not only did I get a false positive with my method but my method also missed some junk frames. My thresholds for YDifferenceFromPrevious and YDifferenceToNext were set at 30 to try to eliminate false positives for junk. The static on this tape kept showing up at about 29.5 for YDiff. I could easily tweak my script to handle this but when I get some time I think I'll do as you suggested and add masktools as a second filter to eliminate the false positives. Hopefully I can have a simplified screening process. First check for high averageluma values to signal potential junk and then use your DEdgeMask method to separate real junk from false positives. It'll be a while before I get to this but I'll let you know how it goes. Finding better definitions of static should be helpful to your method, my method, or to anyone that comes up with a different/better system. Mike.

tsp
10th September 2004, 22:36
It's not a bad idea to see the junk part so I have included it in version 0.02 of trimmaker. I have uploaded two version. A small (http://www.tsp.person.dk/trimmaker.zip) version(12 KB) including just the exe file and readme and a larger (http://www.tsp.person.dk/trimmaker.rar)(1626 KB) setup file including all the neccesary files.
If you would like other features I will try to see if I can get it in.
Also maybe we should try to collect screnshoots of the various types of junk frames.

mkanel
10th September 2004, 22:49
tsp,

This is starting to look like fun. I probably won't be able to test things for a few days but I'll let you know how it looks when I do. I'll also see how combining you masktools method with some frameevaluate parameters work. That's a good idea to collect some examples of junk. Mike.

@Adlancas,

Good to hear from you again, I'm curious to hear if this is useful to anyone else besides me and tsp.

tsp
11th September 2004, 17:09
I fixed a stupid bug preventing the program to work with frames higher than 32768. At the moment I use this script to generate the logfile

global a = DEdgeMask(last,thY1=79,thY2=79,thC1=140,thC2=140 ).expand()
WriteFileIf(last, "log.txt",\
"AverageLuma(a)>1&& (AverageLuma(a.trim(current_frame-1,-1))>4?true:UDifferenceFromPrevious()>4)"
\, "current_frame")

mkanel
11th September 2004, 18:14
tsp,

Ok I'm sold, I like your method. Thanks for including all the new stuff with your most recent trimmaker, it does everything my script does for output plus a handy GUI and more options.

Here's the script I've been using to create the log file

AVISource("D:\Static.avi").converttoyv12
output="d:\log.txt"
WriteFileIf(output,\
"AverageChromaU()>200|| (AverageLuma>215 && YDifferenceFromPrevious>25 && YDifferenceToNext>25 && UPlaneMin>20)",\
"current_frame")

This has two problems it tags a very few overly bright frames as junk, and calls three frames between static and blue frames as good.

using this from tsp's earlier post (I changed thy1 to 140)

global a = DEdgeMask(last,thY1=140,thY2=75,thC1=100,thC2=100 ).expand()
WriteFileIf(a, "badframes.txt", "AverageLuma(a)>1", "current_frame")

gets rid of the false positive that I have so far seen. I just need to write the script to invoke mask tools only after finding a potential scene of static/snow.

To correctly call the 3 frames between the end of static/snow and the beginning of the blue frames may be trickier, I think it may slow down the avs script. Is that something trimmaker could do? Since we normally won't see three good frames all alone surrounded by junk could trimmaker have an option to call 3 or 4 or 5 isolated good frames junk frames?

Some other ideas, I wouldn't even call them suggestions just possibilities to see what other ideas are out there for trimmaker to slightly reduce the cutting and pasting involved. Perhaps trimmaker could automatically output 2 files. One would be the avs, the other could be .txt or .avs. The main avs would have a video source if that's possible and an import for the bad frames. It might look like this.

#by trimmaker version x
avisource=("c:\some.avi")
Trim(x,y) ++ Trim(x,y) ++ Trim(x,y) ++ Trim(x,y) ++ Trim(x,y)
#import logfile_badframes.avs

Showframenumber would be useful in the badframes file so that you could tweak the trimsets actually used.

Ideally the avs script that produces the logfile would also write out the source "avisource=whatever.avi" for trimmaker but I don't think avisynth can do that. Maybe trimmaker could have one more box to select a video source file at the same time that one selects the logfile to use.

tsp
11th September 2004, 22:13
I have just completed version 0.04 of trimmaker. It now includes the ability to add text from the input file and a minimum length of the good parts. The text in the input file before the last frame is added before the trim and the text after are added after. You can use it in the script that generates the input file like this:

sStart="""AVISource("c:\testclip.avi")"""
sEnd="DeGrainMedian(limitY=5,limitUV=10,mode=0)"
#this is added before the trim part in the output
WriteFileStart(outputfile,"sStart")

#and this is added after the trim part in the output
WriteFileEnd(outputfile, "sEnd")


Also I have found a better matrix to be used with Dedgemask. It is more selective to noise. So cuurently my script looks like this:

AVISource("G:\30.avi").Telecide(1,guide = 2).converttoyv12.crop(18,0,720-32,576-12)

global a = DEdgeMask(last,thY1=79,thY2=79,thC1=140,thC2=140,matrix="-2 1 -2 0 6 0 -2 1 -2" ).expand()

WriteFileIf(last, "g:\30log.txt",\
"AverageLuma(a)>1 && (AverageLuma(a.trim(current_frame-1,-1))>1?true:UDifferenceFromPrevious()>3)"
\, "current_frame")


The problem with my video source is that the minimum AverageChromaU is 119 for the junk frames and the maximum for the good frames is 157 also the averageLuma for the junk frames fluctuate greatly from 38 to 181. This forces me to use EdgeMask.

Mkanel how much faster is your script when you use just generates the log file compared with the original long script. Also how much slower is it when you use Dedgemask?

mkanel
11th September 2004, 22:39
tsp,
Disregard the pm.

Original script=17-18 fps
logfile only script=20-21 fps
dedgemask on all frames=12-13 fps
dedgemask only on possible static/snow frames=not yet tested.

Thanks for the new trimmaker, could you post a link.

Mike.

tsp
11th September 2004, 22:44
Trimmaker ver 0.04
Setup with all nesesary files(1.6MB) (http://www.tsp.person.dk/trimmaker.rar)
exe and readme only ( 12 KB) (http://www.tsp.person.dk/trimmaker.zip)

mkanel
12th September 2004, 06:37
tsp,
Mkanel how much faster is your script when you use just generates the log file compared with the original long script. Also how much slower is it when you use Dedgemask?
Original script=17-18 fps
logfile only script=20-21 fps
dedgemask on all frames=12-13 fps
dedgemask only on possible static/snow frames=20-21 fps


This script has worked well on initial testing, it's reported no false positives for junk and and has successfully separated static from bright beach scenes.

AVISource("D:\Static.avi").converttoyv12

output="d:\log.txt"
WriteFileIf(output,"AverageChromaU()>200\
||(AverageLuma>215\
&&AverageLuma(DEdgeMask(last,thY1=140,thY2=75,thC1=100,thC2=100 ).expand())>1)"\
,"current_frame",append=false)

It first checks for blue screen, AverageChromaU()>200, if that's true the frame is automatically junk and no more testing is performed. It then tests for brightness, AverageLuma>215, if that's false it's a good frame and no more testing is performed, if it's true it performs one more test for snow/static, AverageLuma(DEdgeMask(last,thY1=140,thY2=75,thC1=100,thC2=100 ).expand())>1.

This does miss three junk frames between static and blue but trimmaker catches this and produces the correct avisynth trims. Also you should check averageluma before dedgemask or it really slows down the script. I hope this works for you. If you need to tweak some of the setting you could cut and paste the MoreInfo function out of my first post.

I tried this setting from your last post,DEdgeMask(last,thY1=79,thY2=79,thC1=140,thC2=140,matrix="-2 1 -2 0 6 0 -2 1 -2" ).expand() it worked pretty well but produced one false positive on a very bright scene.

On a totally different subject maybe you should start a new thread introducing your trimmaker. The title of this thread is not correct, it's no longer about "my function". Also my first post here is nothing if not brutal, it's too long and that script code is scary to a casual observer. Trimmaker is much friendlier but probably never seen by many who get turned off by my first post. If more people tried it you'd probably get some good suggestions for trimmaker and maybe we'd see more people experimenting with junk definitions.

Edit: Please note that you need yv12 for the frameevaluate parameters. You might not get an error otherwise but WriteFileIf will identify all your frames as junk frames. If you're not set up up to view yv12 just convert back to yuy2 or whatever color space you prefer at the end of the avisynth script.