Archiv verlassen und diese Seite im Standarddesign anzeigen : Vertikales Zittern entfernen
Hallo,
ich habe hier ein großes Problem und komme nicht weiter. Ich habe einen alten selbstgedrehten Film in zweiter Generation. Der ist aber leider mittlerweile in so schlechtem Zustand, daß er beim Abspielen mit meinem Recorder sehr stark vertikal um 1 oder zwei Bildzeilen wackelt. Ich habe mal ein Sample angehängt (13.1 MB http://www.stadtfunk-essen.de/wackeln.rar). Das ist wirklich ein altes Schätzken an dem mir sehr viel liegt und ich möchte den jetzt in der bestmöglichen Qualität auf DVD bringen. Ich habe hier schon ein paar Scripte ausprobiert, aber die sind ja zumeißt für horizontalen jitter und ich hab keine Idee wie ich das vertikale Zittern wegbekomme. Könnt ihr mir helfen?
MOmonster
6. April 2006, 12:08
Wäre gut, wenn du das Sample wo anders hochladen könntest, ich brauche ewig um es runterzuladen. Ist die Vertikale Verschiebung zeilenweise oder betrifft sie immer den ganzen Frame bzw. das ganze Feld. Bei einzelnen Zeilen wäre das vermutlich nur sehr schwer zu stabilisieren und auch so wird das wohl kein leichtes Vorhaben.
Ok, hier ist es nochmal:
http://rapidshare.de/files/17334265/wackeln.rar.html
Ich bin leider kein Profi, deshalb kann ich gar nicht genau sagen warum und wie genau es vertikal zittert. Wie kann ich das am besten selber herausfinden?
Ich konnte jetzt nur einen kurzen Blick drauf werfen, aber es scheint jeweils ein komplettes Field um eine Zeile zu verrutschen. Und anhand der horizontalen Linien oben müsste sich das recht zuverlässig erkennen und dann beheben lassen.
Hallo nochmal,
Ich bin jetzt für eine Woche im Urlaub, also nicht wundern wenn ich nicht antworte! Falls jemand von Euch ein Script weiß wie man das Zittern wegbekommt, dann postet es bitte! Der alte Film liegt mir wirklich sehr am Herzen!
Ein Script? Das müsste dann jemand wie scharfis_brain oder MOmonster machen, ich bin noch nicht soweit, sowas aus dem Ärmel schütteln zu können. ;)
Meine Grundidee wäre:
In Fields zerlegen
Da die oberste Zeile jedes Fields in Deinem Sample schwarz ist, wenn alles OK ist und Bild enthält, wenn nicht alles OK ist, kann man das nachprüfen. Dann jeweils die Fields um die entsprechende Zeile verschieben.
Fields zusammensetzen, fertig.
OK, in der Praxis wird's wohl komplexer sein, aber machbar.
scharfis_brain
8. April 2006, 11:42
Die einfachste lösung: Deshaker drüber laufen lassen...
Ist aber hat suboptimal, da skaliert wird...
Für scripterei habe ich ATM keine Zeit.
(und die nächsten Wochen wohl auch nicht)
MOmonster
10. April 2006, 08:06
Habe im Moment leider auch keine Zeit dafür. Falls die Resultate mit Deshaker allerdings nicht zufriedenstellend sein sollten und Ende nächster Woche ausreichend wäre (habe bis nach Ostern definitiv keine Zeit), dann könnte ich dir gern ein kleines Skript dazu schreiben.;D
Trekkie2
10. April 2006, 08:32
Moin zusammen!
Muss erstmal gestehen, dass ich nicht den ganzen Thread gelesen habe, aber man kann Deshaker skalieren und rotieren verbieten - dann sollte er also keine Pixeloperationen mehr machen, sondern nur noch "schieben". Habs aber noch nie probiert.
Hallö!
Bin jetzt wieder aus dem Urlaub zurück. Habe das gerade mit dem Deshaker probiert, aber irgendwie bekomm ich das nicht hin.
@MOmonster: Falls Du Zeit haben solltet wäre es wirklich toll, wenn Du vielleicht eine Idee für ein Script hast! Danke auf jeden Fall für Dein Angebot!
MOmonster
24. April 2006, 08:34
Zeit ist immer knapp, aber eine kleine Funktion habe ich denn doch zusammengekriegt:
tdeint(mode=1)
vshift_repair(wrange=true)
#crop(8,8,-8,-8)
changefps(25)
Function vshift_repair(clip clp, bool "wrange")
{
global wrange = default(wrange,false)
global out = clp
global clc = clp.crop(8,8,-8,-8)
global clb = clp.crop(8,6,-8,-10)
global cla = clp.crop(8,4,-8,-12)
global cld = clp.crop(8,10,-8,-6)
global cle = clp.crop(8,12,-8,-4)
global prev = clc.duplicateframe(0)
global repair = 0
global difc2 = 1.0
global difc1 = 1.0
c99=scriptclip(out, " repair==0 ? out : (repair==1 ? out.addborders(0,0,0,2).crop(0,2,0,0) : (repair==-1 ? out.addborders(0,2,0,0).crop(0,0,0,-2) :
\ (repair==2 ? out.addborders(0,0,0,4).crop(0,4,0,0) : out.addborders(0,4,0,0).crop(0,0,0,-4) ))) ")
c5=FrameEvaluate(c99, " repair = repair!=0 || difc0<difc2 || difc1<difc2 || (difc1+difc0<difb1+difb0 && difc1+difc0<difd1+difd0) ? 0 :
\ ( difb1+difb0<difd1+difd0 ? (wrange==false || difb1+difb0<difa1+difa0 ? -1 : -2) :
\ (wrange==false || difd1+difd0<dife1+dife0 ? 1 : 2) ) ")
c4=FrameEvaluate(c5, " global difc2 = YDifferenceToNext(clc.trim(1,0))
global difb1 = LumaDifference(clb,clc.trim(1,0))
global difd1 = LumaDifference(cld,clc.trim(1,0))
global difa1 = wrange==false ? 1.0 : LumaDifference(cla,clc.trim(1,0))
global dife1 = wrange==false ? 1.0 : LumaDifference(cle,clc.trim(1,0))
global difb0 = LumaDifference(prev,clb)
global difd0 = LumaDifference(prev,cld)
global difa0 = wrange==false ? 1.0 : LumaDifference(prev,cla)
global dife0 = wrange==false ? 1.0 : LumaDifference(prev,cle)")
c3=FrameEvaluate(c4, " global difc1 = difc2")
c2=FrameEvaluate(c3, " global difc0 = difc1 ")
return(c2)
}
Die Funktion ist recht einfach gehalten, aber tut ihren Dienst recht gut. Für akkuratere Resultate wäre sie einfach zu schnell zu komplex geworden.
Es sollte, wie im Skript, vorher gebobbt werden, da häufig nur ein Feld dazwischen an der richtigen Position sitzt. Deshalb auch der Aufruf von changefps anschließend. Vielleicht war das ja auch das Problem mit Deshaker, ich habe diesen Filter bis jetzt aber leider noch nie genutzt und kann deshalb nichts dazu sagen.
Auf jeden Fall solltest du noch etwas gegen die Rainboweffekte tun (mit bifrost, fft3d, ..., weiß nicht welcher hierfür optimal ist), keine Ahnung in wie weit das vertikale Zittern hier beeinflussend wirkt.
@MOmonster
Vielen vielen Dank!!!!! Ich werde das Script ausgiebig testen und die Ergebnisse hier posten. Bin jetzt auch wieder beruflich unterwegs, sodaß es auch wieder ein paar Tage daurn kann.
Nochmals danke!!!
MOmonster
26. April 2006, 13:45
Wahrscheinlich wird die Funktion im ersten Durchgang nicht alle Ruckler erkennen. Eine Zwischencodierung und eine erneute Anwendung (denn aber nur noch vshift_repair(wrange=true)) wird wahrscheinlich noch bessere Resultate bringen.
So, jetzt habe ich mal getestet. Ich habe mal verschiedene Scripts ausprobiert, aber mit diesem hier und Deiner Funktion ist das Ergebnis eindeutig am besten und 100mal besser als das Ausgangsmaterial:
converttoyv12()
tdeint(mode=1)
vshift_repair(wrange=true)
assumebff() #Ausgabefieldorder
separatefields().selectevery(4,0,3).weave()
Es sind jetzt noch 2 Wackler drin, die ich aber auch mit einem zweiten pass nicht wegbekomme. Ich habe mal das Ergebnis hierhin gelegt:
http://rapidshare.de/files/19058146/entwackelt.rar.html
MOmonster
28. April 2006, 10:21
@ftm
Halt!
Wenn du reinterlaced, ist das natürlich was anderes. Zunächst mal ist dafür bestimmt nicht tdeint notwendig, zumal ich glaube, dass tdeint auch die Originalfelder verändert. Soweit ich weiß, ist das bei ibob nicht so und der ist zudem deutlich schneller.
Wenn du reinterlaced und im zweiten Durchgang das gleiche Skript nochmal anwendest, verändert sich natürlich nichts. Das Problem besteht nämlich darin, dass nur Ruckler erkannt werden, die ordentlich positionierte Nachbarn haben. Tritt also dieser Fall ein:
+0 +0 +2 +2 +0 +0 -2 +0
(Grad der Verschiebung zur ursprünglichen Source)
So wird zwar die "-2" als Ruckler erkannt nicht jedoch die beiden "+2", da sie benachbart sind. Dieses Verhalten ändert sich im zweiten Durchgang denn natürlich auch nicht. Wird jetzt das deinterlaced Material (wie in meinen Skriptbeispiel) mit changefps auf die halbe Framerate gebracht, ergibt sich für den zweiten Durchgang:
+0 +2 +0 +0
Diese Verschiebung lässt sich allerdings erkennen und beheben.
Mit einer kleinen Modifikation lässt sich dieses Prinzip auch "verhältnismäßig gut" auf dein reinterlaced Material übertragen. Da ich hier kein Avisynth habe, müsstest du dich aber noch ein paar Tage gedulden insofern du es überhaupt für sinnvoll erachtest eine zweiten Filterdurchlauf zu machen.
Danke für die Erklärung! Habe zwar nicht alles verstanden da ich bei weitem nicht den Einblick in die Materie habe wie Du, ich versuche Dir aber so gut wie möglich zu folgen! Das Problem mit changefps ist ja, daß die Hälfte der Bewegungsinformation wegfällt und das Bild dadurch viel weniger flüssig wirkt. Deswegen habe ich da "mein" Script benutzt.
Und Du meinst statt tdeint sollte ich da ibob benutzen? Dann werde ich mir das mal in Ruhe anschauen!
Mit einer kleinen Modifikation lässt sich dieses Prinzip auch "verhältnismäßig gut" auf dein reinterlaced Material übertragen. Da ich hier kein Avisynth habe, müsstest du dich aber noch ein paar Tage gedulden insofern du es überhaupt für sinnvoll erachtest eine zweiten Filterdurchlauf zu machen.
Also wie gesagt, im Gegensatz zum Originalvideo ist das erste Ergebnis ja schon wirklich um Längen besser. Wenn Du natürlich noch die Muße hast das Script anzupassen sodaß alle Wackler verschwinden, dann wäre ich Dir natürlich sehr sehr dankbar! Ein 2. pass wäre echt kein Problem, da es mir wirklich um die Qualität geht und die Zeit gar keine Rolle spielt.
MOmonster
4. May 2006, 08:25
So, ich habe zwar etwas auf mich warten lassen, konnte mir gestern aber deine Source nochmal anschauen. Ich muss meine Aussage revidieren. Zwar ist die Überlegung nicht falsch, jedoch ist das auch nicht der Grund für die beiden übrigen Wackler. Der zweite Ruckler wurde wegen den Sicherheitsbedingungen um falsche Erkennungen zu vermeiden nicht erkannt. Ich habe dazu der Funktion einen neuen Parameter gegeben, der diese Bedingung abschaltet:
Function vshift_repair(clip clp, bool "wrange", bool "agressive")
{
global wrange = default(wrange,false)
global agressive = default(agressive,false)
global out = clp
global clc = clp.crop(8,8,-8,-8)
global clb = clp.crop(8,6,-8,-10)
global cla = clp.crop(8,4,-8,-12)
global cld = clp.crop(8,10,-8,-6)
global cle = clp.crop(8,12,-8,-4)
global prev = clc.duplicateframe(0)
global repair = 0
global difc2 = 1.0
global difc1 = 1.0
c99=scriptclip(out, " repair==0 ? out : (repair==1 ? out.addborders(0,0,0,2).crop(0,2,0,0) : (repair==-1 ? out.addborders(0,2,0,0).crop(0,0,0,-2) :
\ (repair==2 ? out.addborders(0,0,0,4).crop(0,4,0,0) : out.addborders(0,4,0,0).crop(0,0,0,-4) ))) ")
c5=FrameEvaluate(c99, " repair = agressive==false && (repair!=0 || difc0<difc2 || difc1<difc2) || (difc1+difc0<difb1+difb0 && difc1+difc0<difd1+difd0) ? 0 :
\ ( difb1+difb0<difd1+difd0 ? (wrange==false || difb1+difb0<difa1+difa0 ? -1 : -2) :
\ (wrange==false || difd1+difd0<dife1+dife0 ? 1 : 2) ) ")
c4=FrameEvaluate(c5, " global difc2 = YDifferenceToNext(clc.trim(1,0))
global difb1 = LumaDifference(clb,clc.trim(1,0))
global difd1 = LumaDifference(cld,clc.trim(1,0))
global difa1 = wrange==false ? 1.0 : LumaDifference(cla,clc.trim(1,0))
global dife1 = wrange==false ? 1.0 : LumaDifference(cle,clc.trim(1,0))
global difb0 = LumaDifference(prev,clb)
global difd0 = LumaDifference(prev,cld)
global difa0 = wrange==false ? 1.0 : LumaDifference(prev,cla)
global dife0 = wrange==false ? 1.0 : LumaDifference(prev,cle)")
c3=FrameEvaluate(c4, " global difc1 = difc2")
c2=FrameEvaluate(c3, " global difc0 = difc1 ")
return(c2)
} Der zweite Ruckler wird nicht erkannt, weil dem vorherigen Feld mitten im Bild Zeilen fehlen. Eine Funktion um solche Spezialfälle abzufangen werde ich allerdings nicht erstellen, passt einfach nicht mehr in meinen Zeitplan.
Getestet habe ich so:
1.Durchlauf
#tcomb() ?
leakkernelbob(order=0, threshold=4, twoway=false, sharp=false)
vshift_repair(wrange=true)
2.Durchlauf
vshift_repair(agressive=true,wrange=true)
crop(8,8,-8,-8)
assumebff() #Ausgabefieldorder
separatefields().selectevery(4,0,3).weave()
Agressive==true schaltet die Sicherheitsbedingungen ab. Achtung, das kann auch zu Fehlverhalten führen und sollte wirklich erst im zweiten Durchgang verwendet werden. Für dein kurzes Sample war aber alles ok. Ich habe leakkernelbob verwendet, da ich ibob gerade nicht auf dem Rechner hatte. Aus Zeitgründen habe ich nur einmal gebobbt (1.Skript) und einmal reinterlaced (2.Skript).
Auf jeden Fall solltest du noch irgendetwas gegen die Rainbows tun. Tcomb ist eine Möglichkeit, wurde allerdings nicht getestet. Bis auf die eine angesprochene Ausnahme wurden auf diese Art alle Ruckler entfernt.
Viel Spaß damit.;)
@momonster
Nochmals herzlichsten Dank für die Zeit und das Wissen, das Du meinem Problem gewidmet hast! Find ich super! :) :) :)
scharfis_brain
4. May 2006, 19:04
Wie gefällt Dir das angehängte interlaced kodierte XVid?
MOmonster
5. May 2006, 08:07
Wieso packen blos immer alle rar? Ich kann es mir hier leider nicht anschauen. Viel interessanter wäre doch dein Skript Scharfi. Ich würde es zumindest gerne sehen.:ja:
Hallo scharfi!
Sieht wirklich gut aus, wenn auch ein klein wenig unschärfer. Hast Du das mit dem Deshaker gemacht? Wäre nett wenn Du mal Deine Einstellungen posten könntest. Ich würde gerne mal mit dem Script von MOmonster und Deiner Methode ein wesentlich längeres Filmstück bearbeiten um das zu vergleichen. Danke auch Dir für Deine Hilfe!
@scharfi
Kannst Du nicht mal freundlicherweise Deine Einstellungen posten? Wäre supernett!
MOmonster
25. May 2006, 10:35
@Scharfis_Brain
Wir sind beide immer noch sehr an dein Skript interessiert, Scharfi. Wäre wirklich nett, wenn du es posten würdest.
(Ansonsten starte ich demnächst eine PM-Attacke auf dich.;D )
scharfis_brain
25. May 2006, 13:22
Warnig: This is a Braindump. So expect mistakes:
avisource("blah.avi").assume?ff()
eedibob()
Das dann in den Deshaker füttern und die deshaker werte so niedrig einstellen wie möglich, ausser fürr die vertikale korrektur. Ich weiss die Werte nicht mehr. Also: Ausprobieren.
Nach dem Deshaker:
r=2
AVIsource("blah2.avi")
e=depanestimate(...)
depaninterleave(e,next=r,prev=r...) #global motion compensation
ttempsmooth(radius=r,....) # deoising
mergechroma(reduceflicker) #farben beruhigen
selectevery(r+r+1,r)
converrtoyuy2()
assume?ff()
separatatefields().selectevery(4,0,3).weave()
vBulletin® v3.7.3, Copyright ©2000-2009, Jelsoft Enterprises Ltd.