PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Szenenwechsel mit Avisynth erkennen


Eastermeyer
20. August 2005, 14:34
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 ?

Eastermeyer
20. August 2005, 15:13
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 :

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

Wilbert
20. August 2005, 17:16
Wie kann ich mir die Framenummern anzeigen lassen?
(Und wenn es möglich ist , sogar als TXT exportieren?)
http://www.avisynth.org/Write

Eastermeyer
20. August 2005, 17:20
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).

Didée
20. August 2005, 17:40
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.)

Eastermeyer
20. August 2005, 17:43
Ehm...

Ich hatte gedacht , soetwas währe in eurem Fundus schon vorhanden.
Soetwas selber zu schreiben leigt leider nicht im Bereich meiner Kenntnisse.

incredible
20. August 2005, 22:52
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.

Eastermeyer
20. August 2005, 23:02
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.

incredible
20. August 2005, 23:06
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 :)

Matt Kirby
2. September 2005, 21:31
es gibt ein Tool namens "AVCutty" das erkennt Szenenwechsel ziemlich gut ( man kann bei Unzfriedenheit noch die Parameter anpassen) und es erstellt AVS Scripte.

incredible
2. September 2005, 21:59
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 ...

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.

Didée
3. September 2005, 00:56
Ich finde dieses Script einfach nicht mehr shitttte. *grrrrr

[ ICH SOLLTE VERDAMMT NOCHMAL AUFRÄUMEN. ]
Oh ja. Meine Worte, ganz meine Worte ... :redface: :D


Es 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:
|
|
* * * * *|
|* * * * *
|
|
* * |
* * *|
|* * *
| * *
|
|
* * |
* * *| * *
|* * *
|
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? :)

Kika
3. September 2005, 01:00
Meinst Du sowas?


clip = segmentedavisource("capture.avi")

clip1=ScriptClip(clip, "diff = YDifferenceToNext()"+chr(13)+"diff > 1.5 ? IrgendeinFilter(): DerandereFilter()")
Return(clip1)

Nachtrag: Heut' komm' ich ständig zu spät... ;)

incredible
3. September 2005, 10:32
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?Ruuuuuhig Brauner, ruuuhhing :D

@Kika
Das war die ausgangsbasis, hatte ich aus dem MA Script geklaut.
(Es gibt wirklich Leuts die damit noch enkodieren :nein: )

scharfis_brain
3. September 2005, 11:02
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...

Eastermeyer
10. September 2005, 18:02
Wie geht's vorran mit dem operieren , scharfi ?

Eastermeyer
19. September 2005, 14:47
Hat Keiner mehr eine Idee ?

scharfis_brain
19. September 2005, 15:14
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)")
}

einfach mal mit

avisource("blah.avi")
scd()

aufrufen.


Nur weiss ich nicht, wie ich bei einer funktion nen bool zurückgeben kann?

Eastermeyer
20. September 2005, 18:02
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 ? ;)

katjarella
20. September 2005, 18:15
evt. per http://www.avisynth.org/Write und nen mix mit http://www.avisynth.org/ConditionalFilter

scharfis_brain
20. September 2005, 20:16
zur zeit erkennt diese Funktion beide Frames (Vorgänger & Nachfolger) eines Szenenwechsels als solchen.

Es kann aber abgewandelt werden, dass nur noch eines erkannt wird.
Nur auf welches Frame legt man dann den erkannten Szenenwechsel?

auf das den Szenenwechsel einläutende Frame?
oder auf das den Szenenwechsel abschließende Frame?


Wieso soll da ne Textdatei draus werden?

Eastermeyer
20. September 2005, 20:20
oder auf das den Szenenwechsel abschließende Frame?Dito. Weil da ja das I-Frame hin muss.

scharfis_brain
20. September 2005, 20:34
ah! jetzt erschliesst sich mir auch, warum Du ein Textfile haben willst.

Modifikation kommt.

Aber nichtmehr heute.

Kika
21. September 2005, 09:59
Ui, das wäre nicht schlecht, dann könnte ich eventuell doch noch meine Super-CQ-Idee für TMPGEnc umsetzen. ;)
Denn dazu wäre es nötig, eine Textdatei (das genau Format hab' ich zurzeit nicht im Kopf) zu haben, bei der:

1. Die Szenenwechsel klar markiert sind
2. Die Szenen selbst in High- und Low-Motion-Szenen unterteilt bzw. als solche markiert werden.

Ich hatte dazu mal mit der "normalen" Szenenerkennung experimentiert, aber die war einfach nicht gut genug dafür, besonders Punkt 2 ließ sich damit nicht umsetzen.

Eastermeyer
4. October 2005, 10:21
Modifikation kommt. Wie weit bist du ?

Eastermeyer
8. October 2005, 14:28
http://www.cheesebuerger.de/smiliegenerator/ablage/172/165.png

scharfis_brain
8. October 2005, 14:55
Huch, ganz vergessen. Sorry.

Büddechöhn:

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 blk=i #blankclip(i)
global wht=i.subtitle("scenechange") #blk.invert()

f1=scriptclip(i,"sc")
f2=f1.frameevaluate("sc=( (a2 > (a1*fac+off)) && (a2 > (a3*fac+off)) ) ? wht : blk")
f3=f2.frameevaluate("a3=averageluma(msk2)")
f4=f3.frameevaluate("a2=averageluma(msk1)")
f4.frameevaluate("a1=averageluma(msk0)")
}

das dateioutput musst Du aber selbst einbauen. Da habsch keinen Plan von.

Eastermeyer
8. October 2005, 15:02
das dateioutput musst Du aber selbst einbauen. Da habsch keinen Plan von.Das krieg ich schon irgendwie hin. Danke für die Arbeit!