Hallo!
Dieses Thema wurde im Forum schon mehrfach angesprochen , jedoch gab es nie eine Antwort.
Wo finde ich ein Script das die Szenenwechsel in einem Video erkennt und mir die Framenummern ausgibt ?
Hallo!
Dieses Thema wurde im Forum schon mehrfach angesprochen , jedoch gab es nie eine Antwort.
Wo finde ich ein Script das die Szenenwechsel in einem Video erkennt und mir die Framenummern ausgibt ?
Ich hab mich mal im englishen Forum umgesehen:
http://forum.doom9.org/showthread.php?t=65934
Ich hab aber nun das gleiche Problem wie der Herr im Thread :
Zitat von KKLLAlles anzeigen
Thanks. Opening:
a=AVISource("myavi.avi")
subtract(a.trim(1,0),a)
..in VirtualDub shows a gray screen for every frame except show that have a change.
How do I generate a text file, containing something like:
Frame 100
Frame 250
Frame 255
..etc. which lists all the frames that contain a "scene change".
Wie kann ich mir die Framenummern anzeigen lassen?
(Und wenn es möglich ist , sogar als TXT exportieren?)
ZitatWie kann ich mir die Framenummern anzeigen lassen?
(Und wenn es möglich ist , sogar als TXT exportieren?)
Aber ich habe doch die Nummern noch gar nicht!
Ich habe bis jetzt nur einen Grauen-Clip.
Jetzt müsste ich die Nummern von allen Frames herausgekommen , die komplett grau sind (scene change).
Szenenwechsel-Erkennung mit dieser einfachen Differenz-Methode macht nicht sehr viel Sinn - das ist *vieeel* zu unzuverlässig. Szenenwechsel mit sehr "ähnlichen" Szenen werden nicht erkannt, insbesondere auch bei "dunklen" Szenen, oder schnelle Bewegung wird fälschlicherweise als Szenenwechsel erkannt, "Blitzlichter" ebenso, oder alles zusammen ...
Das muss anders gemacht werden. Scharfi hat mal 'ne Szenenwechsel-Erkennung per MVMask zusammengebaut (um Szenenwechsel bei MVConvertFPS zu schützen), das könnte man wohl heranziehen.
Ich hatte mal über etwas anderes nachgedacht, so ne Art 1. Ableitung:
Untersuche die Differenzen zwischen drei (besser: fünf) aufeinanderfolgen Frame-Paaren, und untersuche dann die Differenzen dieser Differenzen. Wenn *da* ein Sprung drin ist, *dann* haben wir einen Scenechange. (Wahrscheinlich ... hab's noch nicht ausprobiert.)
Ehm...
Ich hatte gedacht , soetwas währe in eurem Fundus schon vorhanden.
Soetwas selber zu schreiben leigt leider nicht im Bereich meiner Kenntnisse.
Ich hatte mal genau so ein Script mit Lumaerkennung und "write" als SC Textfile via Avisynth hier irgendwo gepostet ... weiss der Teufel wo der Beitrag steckt.
Funktioniert sehr gut, selbst bei viel Aktion/Motion in scenen konnte ein SC unterschieden werden.
Eine Forensuche mit dem Stichwort "write" und dem Benutzernamen "incredible" fördert nur diesen Beitrag zu Tage:heul:
Aber schön zu hören , das es sowas schon fertig gibt.:daumen:
Ich versuch's mal zu finden.
Ja, habe auch breits die Forensuche Bemüht. Ich weiss noch genau, dass ich jenes Script an einem Capture "Taxi Driver" ausprobiert hatte. Auf meiner Pladde finde ich es nicht, bzw. ... ICH SOLLTE VERDAMMT NOCHMAL AUFRÄUMEN.
Hatte schon mal angefangen eine DVD mit allen benötigten PRGs, Avisynth VErsionen, Scripten, etc ect ect zusammenzustellen. Nach dem Motto, wenn ich mal unter der Brücke bin, kann ich noch weiter machen
es gibt ein Tool namens "AVCutty" das erkennt Szenenwechsel ziemlich gut ( man kann bei Unzfriedenheit noch die Parameter anpassen) und es erstellt AVS Scripte.
Zitat von DidéeSzenenwechsel mit sehr "ähnlichen" Szenen werden nicht erkannt, insbesondere auch bei "dunklen" Szenen, oder schnelle Bewegung wird fälschlicherweise als Szenenwechsel erkannt, "Blitzlichter" ebenso, oder alles zusammen ...
Ich finde dieses Script einfach nicht mehr shitttte. *grrrrr
Es geht, wenn du nicht nur aus YDifferenceToNext(), sondern auch YDifferenceFromPrevious() mit in die Routine einbeziehst. Beide werden im verhältnis zueinander gestellt. Wenn du nur YDiffToNext() nimmst, werden eben auch leider reine fast motions erkannt. Ich hatte das ganze mal via ScriptClip() gemacht, wobei als analyse clip ein via levels getunter greyscale() mit 352x288 oder so des Input clips genommen wurde. Das Ding war sehr fix und funktionierte klasse.
Zitat von incredibleIch finde dieses Script einfach nicht mehr shitttte. *grrrrr
[ ICH SOLLTE VERDAMMT NOCHMAL AUFRÄUMEN. ]
Oh ja. Meine Worte, ganz meine Worte ... :redface:
ZitatEs geht, wenn du nicht nur aus YDifferenceToNext(), sondern auch YDifferenceFromPrevious() mit in die Routine einbeziehst. Beide werden im verhältnis zueinander gestellt.
...
Das Ding war sehr fix und funktionierte klasse.
Durch die Verhältnisbildung kommst Du schon mal von der primitiven Threshold-Geschichte weg - das ist schon mal "smarter", ganz klar.
Trotzdem: Mit nur jeweils einem YDifferenceFromPrevious() und YDifferenceToNext() sollte sich der Erfolg noch ziemlich in Grenzen halten ... könnte Wetten, dass dem Ding doch noch so einige Sachen durchgegangen sind.
Weil: Auswertung der Verhältnisse von nur drei Frames ist einfach zu wenig, um vorhandene Änderungen auf beiden Seiten des Scenechanges richtig interpretieren zu können. Meiner Meinung nach müssen allermindestens zwei, besser drei Frames auf jeder Seite berücksichtigt werden, also ein Fenster von sechs Frames.
Schau mal:
|
|
* * * * *|
|* * * * *
|
|
* * |
* * *|
|* * *
| * *
|
|
* * |
* * *| * *
|* * *
|
Alles anzeigen
Oben ist der "synthetische" Fall. Der ist leicht auszuwerten, da funktioniert auch eine einfacheThreshold-Methode. Kommt aber in der Praxis leider seeehr selten vor.
In der Mitte ist ein "realer" Fall. Bei dem wird's schon schwieriger. Die einfache Threshold-Methode wird entweder nix erkennen, oder muss so grob eingestellt werden, dass sie "viel zu viel" erkennt.
Dieser Fall ist aber z.B. mit der von Dir beschriebenen 3-Frame-Verhältnis-Methode zu erkennen.
Und unten ... das ist auch ein realer Fall. Hier lässt Dich die 3-Frame-Methode aber ganz schön im Regen stehen. Hier müssen mindestens vier Frames ausgewertet werden, und i.d. Praxis ist das noch ziemlich wackelig. Mit sechs Frames wird's sicher.
Und das sind nur Beispiele für tatsächliche Scenechanges. Die high-Motion-Problematik haben wir ja aber auch noch ...
Was ist, wenn etwa ein großes dunkles Objekt sehr schnell durch die Szene durchfliegt - in Frame 1 ein kleiner Fleck, in Frame 2 eine daumennagelgroße Scheibe, in Frame 3 werden 30% der Framefläche bedeckt. In Frame 4 isses wieder weg.
Sowas geht sehr leicht ungewollt als Scenechange durch. Bei Denoising und so mag das manchmal noch angehen, manchmal auch nicht. Aber angenommen, man ist z.B. gerade dabei, die ersten/letzten Frames nach/vor Scenchanges einzufrieren, oder sowas ... au weia.
90%-Methoden sind Kinderkram. 95%-Methoden sind einfach, 98% nicht schwierig. Aber was wir haben wollen, ist doch mindestens die 99.9%-Methode, oder etwa nicht?
Zitat90%-Methoden sind Kinderkram. 95%-Methoden sind einfach, 98% nicht schwierig. Aber was wir haben wollen, ist doch mindestens die 99.9%-Methode, oder etwa nicht?
Ruuuuuhig Brauner, ruuuhhing
Kika
Das war die ausgangsbasis, hatte ich aus dem MA Script geklaut.
(Es gibt wirklich Leuts die damit noch enkodieren :nein: )
in mvfpsscd habe ich eine eben solche szenenerkennung eingebaut.
- motionmask erstellen -> szenenwechsel hat ein überhöhtes averageluma
- den aktuellen frameübergang mit dem beiden vorherigen und nachfolgenden vergleichen
- ist der aktuelle frameübergang faktor x plus offset größer als jeder der frames im suchradius (hier 4=2+2), dann szenenwechsel.
- x -> faktor, um die das averageluma der motionmask gegenüber vorgänger und nachfolgerframes steigen muss, damit szenenwechsel erkannt wird
- offset -> rauschunterdrücker, weil bei No-Motion szenen das averageluma SO klein wird, dass bereits geringstes rauschen die szenenerkennung auslöst (denn: z.B. 0.1 * faktor ist nicht viel!)
mal gucken, ob ich das heute noch aus mvfpsscd rausoperiere...
Wie geht's vorran mit dem operieren , scharfi ?
Hat Keiner mehr eine Idee ?
function scd(clip i, int "factor", int "offset")
{
global fac=default(factor,5)
global off=default(offset,25)
global msk0=i.duplicateframe(0).reduceby2().reduceby2().motionmask(thsd=255,y=3,u=1,v=1)
global msk1=msk0.trim(1,0)
global msk2=msk0.trim(2,0)
global msk3=msk0.trim(3,0)
global blk=i #blankclip(i)
global wht=i.subtitle("scenechange") #blk.invert()
f0=scriptclip(i,"sc")
f1=f0.frameevaluate("sc=(sc2 || sc1) ? wht : blk")
f2=f1.frameevaluate("sc2=( (a2 > (a1*fac+off)) && (a2 > (a3*fac+off)) ) ? true : false")
f3=f2.frameevaluate("sc1=( (a1 > (a0*fac+off)) && (a1 > (a2*fac+off)) ) ? true : false")
f4=f3.frameevaluate("a3=averageluma(msk3)")
f5=f4.frameevaluate("a2=averageluma(msk2)")
f6=f5.frameevaluate("a1=averageluma(msk1)")
f6 .frameevaluate("a0=averageluma(msk0)")
}
Alles anzeigen
einfach mal mit
avisource("blah.avi")
scd()
aufrufen.
Nur weiss ich nicht, wie ich bei einer funktion nen bool zurückgeben kann?
D A N K E !
Funktioniert sehr gut!
Wie kann ich mir denn jetzt die Nummern der Frames als txt exportieren *grübel*
Wilbert , wo bist du ?
evt. per http://www.avisynth.org/Write und nen mix mit http://www.avisynth.org/ConditionalFilter
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!