Beiträge von Mars

    Moin,


    Vorab: Ich habe mich noch nicht näher mit dem Thema befasst und noch nichts ausprobiert. Das hier ist nur ein Thread in dem ich nachfrage ob jemand schonmal soetwas gebastelt hat, damit ich mir die Mühe ggf. sparen kann (wozu das Rad ein 10tes Mal erfinden).


    Es geht um folgendes:

    Ich suche eine Funktion (am besten in AutoIt gewrappt) die mit einem frei zugänglichen Decoder (z.B. ffmpeg) einen Frame (Angabe als Integer, Frame 0 = erster Frame des Videos) aus einer Videodatei dekodiert und in eine Struct legt (kein Dump auf die Festplatte), sodass man anschließend Zugriff auf die Pixeldaten hat. Dabei sollten verschiedene container (mp4, mov, avi, mkv, usw) sowie verschiedene interne Formate (VP9, h264, h265, usw) unterstützt werden. Schön wäre auch wenn man die Videodatei (die ggf ziemlich groß ist) nicht jedes Mal neu einlesen muss, sondern laden kann und dann beliebige Frames herausziehen kann.


    Ich weiß dass das möglich ist und villeicht hat ffmpeg sogar schon eine vorgefertigte Funktion für genau dieses Szenario (auf die Schnelle habe ich aber nur eine Funktion die den Frame auf die Platte schreibt gefunden).


    Ziel der Aktion:

    Ich möchte eine Methode basteln um "bessere" Screenshots von Videos machen zu können (dabei geht es vorallem um selbst aufgenommene Videos via Handy/Kamera usw). Leider ist da immer starkes Rauschen (insbesondere auf Pixelebene) involviert. Wenn man aber z.B. 5 Frames in Folge verwendet (vorausgesetzt Objekt und Kamera bewegen sich nicht viel) könnte man mit minimaler Bewegungskorrektur + Mittelwertbildung ein besseres Bild erhalten, als wenn man von den 5 Frames einfach den Mittleren auswählt.


    Daher die Frage: Hat das schonmal jemand gemacht und gibt es villeicht bereits eine gewrappte AutoIt Version?


    lg

    Mars

    Habe auch VSC installiert und das Beispiel tut bei mir auch was es soll.


    Üblicherweise habe ich VSC aber für Go und C++ in Verwendung, Für AutoIt gibts ja ISN (was für die Sprache zugeschnitten wurde), oder Scite, wenn man etwas mehr als Notepad, aber nicht "viel" mehr will :D


    M

    Wenn dein Spript Adminrechte braucht versuche mal #RequireAdmin am Anfang (in die erste Zeile) zu schreiben, dadurch kann das Programm nur als Admin ausgeführt werden, egal welcher Benutzer angegeben wird und egal wie der Admin heißt (glaube ich zumindest).


    edit. obwohl ich glaube du willst das das automatisch passiert (also dass das Windows Fenster in dem man sich als Admin anmeldet nicht erscheint). Dann hilft meine Idee nichts...

    Das ist wirklich seltsames Verhalten. Bei mir kann ich anstellen was ich will (msgboxen, tooltips, sonstiges) und der Text bleibt immer erhalten (Das liegt möglicherweise an irgendwelchen Windows-Updates, ich kann mich nämlich erinnern vor langer langer Zeit immer damit gekämpft zu haben das plötzlich Teile aus dem GFX/DC eines Fensters plötzlich "verschwunden" sind weil etwas davorlag. Aber das ist so lange her das ich kaum noch weiß warum das passiert ist). Was nicht abgedeckt ist in meinem Beispiel ist WM_PAINT (dafür braucht man einen weiteren Backbuffer der immer das letzte gerenderte Bild enthält. Den kann man dann Eventdriven ins GUI zeichnen ohne das etwas fehlt) und einige andere WMs. Falls es WM_PAINT ist sollte das Problem leicht zu beheben sein, falls nicht muss weiter gebohrt werden bis man weiß was der Verursacher ist.


    Schau mal ob das Problem hier immernoch auftritt, ich kann es bei mir leider nicht reproduzieren...


    M

    Habe mal ein Beispiel zu frei rotierbarem Text gemacht, ich hoffe das Löst dein Problem.



    Edit: Habe mir jetzt WriteRotate nicht ausprobiert, aber allgemein ist WinAPI und GDI+ nur in einigen Fällen kompatibel, im Allgemeinen greifen die Funktionen nicht ineinander. Man kann kein Rechteck via WinAPI auf ein GDI+ GFX zeichnen und kein GDI+ Rechteck auf einen usw...


    lg

    M

    Ich würde mir einfach die gewünschte Funktion via _GDIPlus_GraphicsDrawLine selbst basteln. Wenn du das Array für DrawCurve bereits hast, kannst du via DrawLine immer Punkt [i] und Punkt [i+1] verbinden (beginnend bei 1 und endend ein Element vor dem letzten Element).

    Ich verstehe einfach nicht wie die Antivirenhersteller so unfassbar bescheuert sein können und nicht mal den Interpreter whitelisten. Das ist als würde man das "PE" am Beginn einer .exe als Indikator nutzen um einen Virus zu erkennen. Die Probleme werden wohl nie aufhören, solange niemand merkt, dass ein Interpreter für sich weder gut noch schlecht ist, sondern eben einfach nur ein Interpreter.

    Also ich bin jetzt verwirrt.

    Hier ist ein Testskript. Wenn ich via _WinAPI_GetWindowDC (via GetDC bekommt man nur die ClientArea) den DC hole und via BitBlt hineinzeichne (BLACKNESS/WHITENESS brauchen dafür keine Brush/Bitmaps oder ähnliches sondern funktionieren direkt) sieht es für mich aus als würde das Koordinatensystem bei 0/0 oben links anfangen, aber die Titelleiste wird über den oberen Teil gezeichnet.

    Technisch gesehen wird auch nur der DC von der ClientArea und nicht vom "gesamten Fenster" geholt (Rand & Titelleiste sind da nicht enthalten).
    Edit: ich habe das "window" überlesen und gedacht es ginge um die Funktion GetDC. Diese Aussage stimmt so nicht.

    und ggf. bei allen _IsPressed() Funktionen ein "02" einfügen, dann wird das Skript aktiviert, sobald man die rechte Maustaste klickt statt der Mittleren (die ja heutzutage nicht mehr jeder hat)


    Außerdem kann ein Sleep(10) in der While _IsPressed() Schleife auch nicht schaden, sonst hat man volle CPU Auslastung obwohl das an dieser Stelle garnichts bringt.


    lg

    M

    Aus welcher Sprache wurde das denn Übersetzt?

    Ich habe schon einiges an Spielen programmiert (vorallem Minispiele in 2D), meistens waren das tausende Zeilen Code der wesentlich komplizierter war als ein einfaches Makro das die Maus irgendwie bewegt. Wenn ihr ein Spiel schreiben könnt könnt ihr auch die Maus bewegen um euer Spiel zu testen.

    Wenn man eine Datei die Funktionen enthält als .a3x kompiliert und diese in einem anderen Script per Include einfügt wird die Funktion nicht erkannt. Eine Lösung für dieses Problem ist, dass man die .a3x Datei umbenennt zu z.B. .a3y. Wenn man diese datei via Include einfügt funktioniert alles wie gewohnt.


    Code: a.au3
    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Outfile_type=a3x
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    Func MyFunc()
    MsgBox(1, 'Hallo', 'Hallo')
    EndFunc
    Code: b.au3
    #include 'a.a3x'
    MyFunc()


    Bin nicht sicher ob das bei jedem so ist, aber intuitiv ist dieses Verhalten nicht. Liegt vermutlich an Au3Check. Kann das jemand reproduzieren?


    lg

    M

    Eine weitere Methode wäre folgendes:

    - Schiebe deine Werte die du behalten möchtest (inplace) nach vorne und die die du loswerden möchtest nach hinten.

    - Benutze genau 1x Redim auf dein nun strukturiertes Array und schneide dir damit den Teil aus den du behalten möchtest.

    Code
    #include <Array.au3>
    Global $a[5][3] = [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12],[13, 14, 15]]
    _ArrayDisplay($a)
    ReDim $a[3][2] ; Redim Schneidet jeweils den Inhalt jedes Index' von 0 bis End aus.
    _ArrayDisplay($a)

    Der Code dient nur als Beispiel für das was ReDim macht.


    M

    Ein Trick um das "ausufern" zu verhindern ist die Energieerhaltung.


    Zu Beginn berechnet man die Gesamtenergie (EPot + EKin) und nach jedem Frame (wenn alle Werte vorliegen) berechnet sie ebenfalls. Da es immer kleine Abweichungen gibt (man kann kein kontinuierliches system fehlerfrei diskret simulieren) wird die Gesamtenergie im System nicht erhalten sein. Jetzt passt man nach jedem Frame die Werte etwas an, sodass die Energie trotzdem erhalten bleibt. Das ist zwar eigentlich grober Unfug, hilft aber dabei das ein System nach einiger Zeit immernoch stabil (wenn auch falsch) läuft.


    kleiner Tip hier: (tooltip mit Energie (die kartesisch berechnet wurde... ist mir auch erst im nachhinein aufgefallen dass das doof ist :D))

    Die Zahlen darin sind eigentlich vollkommen wurscht :D


    Das Verfahren funktioniert so:

    - "Habe" eine Wahrscheinlichkeitstabelle für jedes Zeichen (wenn man nichts weiß ist das eine Gleichverteilung, oder in diesem Fall das Default Histogramm)

    - Baue einen Baum aus der Tabelle, Kodiere/Dekodiere ein Zeichen und erstelle damit die Tabelle neu. -> solange bis keine Zeichen übrig sind.


    Was du da reinschreibst ist also egal, alles was sich dadurch ändert ist die Kompressionsrate zu Beginn. Allerdings kann man keinen Text dekodieren, wenn eine andere Tabelle benutzt wurde als im Encoder, also könnte man dieses 256 float Gebilde als eine Art "viel zu langes Passwort" missbrauchen :D


    Max Mustermann, Musterbergheimer Landstraße 1 99, 12345 Musterbergheim am Musterberg.


    Edit: Falls jemand das Teil nochmal angesehen hat, ich habe den Min-Heap ergänzt, somit ist es jetzt ca. 30% schneller als vorher. Da es immernoch inplace in einem Array funktioniert kann man das 1:1 in jede beliebige Sprache genauso übernehmen und es müsste immer ziemlich effizient arbeiten. Außerdem habe ich TreeToLookup optimiert, sodass sie statt 3ms nur noch 2ms benötigt, leider immernoch rekursiv...


    lg

    M

    Ich bin ein wenig verwirrt, die BitShift Funktion in AutoIt tut genau das was man vermuten würde oder?


    Poste doch bitte ein Skriptbeispiel das dein Problem reproduzieren kann (z.B. BitShift(abc, x) = 123, sollte aber eigentlich 234 sein). Dann kann man auch was damit anfangen und eine Lösung finden


    M

    Hehehe,


    ich wollte die Sache erst "ADH = ADaptive Huffman" nennen, dann ist es aber "AHE = Adaptive Huffman Encoder" geworden. Wahrscheinlich wäre "AHC = Adaptive Huffman Code" noch besser. Namensfindung ist so kompliziert :(


    Den Baum aufspannen dauert (mit der jetzigen Methode) in AutoIt ca. 50ms. Schätze man kommt noch auf ca. 20-30ms wenn man ein wenig optimiert. Da ich alles so umgebaut habe, dass es inplace in einem Array stattfindet könnte man es 1 zu 1 in ASM übersetzen. Dann werden aus 20ms -> 20µs.


    //OT:

    Mit dem Internet stimmt wirklich etwas nicht. Ich wollte mir letztens einen Stream auf YT ansehen, der hat furchtbar gehackt ist andauernd stehengeblieben und konnte nur via F5 wieder für ein paar Sekunden am laufen gehalten werden. Dieses Totalversagen schiebe ich aber auf die Software. Meine Leitung hat einen Ping von ca. 25ms und kann ca. 5MB/s (wenn sie gute Laune hat), ich erwarte dass ein Stream damit flüssig läuft :thumbdown:

    Moin,


    (Gleich zu Beginn mal ein Wiki-Link, jeder der nicht weiß worum es geht sollte den ggf. erst durchgehen :))


    Einen Huffman Encoder kann vermutlich jeder basteln (ist ja nicht so schwer) wo ich aber häufig Probleme beobachtet habe ist der Part mit dem Abspeichern der Wahrscheinlichkeitstabelle. Es ist nämlich so, dass der Decoder im Regelfall den Huffman-Baum zum dekodieren benötigt.


    Beispiel:

    Wenn ich jetzt aber meinen Text: "Hallo Test 123" verwende gibt es ein großes Problem: Der Text besteht aus vielen verschiedenen Zeichen (es ist ja nicht "aaaaaaabbabaaaa" oder soetwas) die jeweils auch nicht allzuoft vorkommen (Leerzeichen x2 und "l" x2), egal in welcher optimierten Darstellung ich den Huffman-Baum abspeichere, er wird in jedem Fall mehr Speicher verbrauchen als mein eigentlicher Text. Wenn ich jetzt den kodierten Text + Baum benötige um wieder meinen ursprünglichen Text zu erhalten ist nichts gewonnen. Hier kommt der adaptive Teil zum tragen.


    Ein adaptiver Kodierer beginnt mit irgendeiner vorgegebenen Wahrscheinlichkeitsverteilung (z.B. eine Gleichverteilung, dann hat jedes Zeichen beim erstmaligen auftreten 8 Bit, da es 256 theoretisch mögliche Asc Zeichen gibt), generiert daraus den Huffman-Baum und kodiert damit nur das allererste Zeichen des Textes. Dann wird dieses Zeichen mit einem gewissen Faktor zur Wahrscheinlichkeitstabelle hinzugefügt, ein neuer Baum generiert und damit das 2te Zeichen kodiert. usw usw. Das bedeutet, dass der Decoder KEINEN Baum benötigt, da dieser implizit durch die kodierte Nachricht selbst mitgeliefert wird. Das hat eine ganze Reihe Vor- und Nachteile.


    Vorteile:

    - Funktioniert auch für kurze Texte deren Huffman-Baum alleine schon größer wäre als der Text selbst

    - Falls man eine Dämpfung festlegt (in meinem Skript nicht enthalten) ist es möglich dass der Kodierer lokal besser arbeitet als wenn für den vollen Text die gleiche Verteilung angenommen werden würde.

    - Da die Wahrscheinlichkeitsverteilung laufend angepasst wird kann man von einem beliebigen Startpunkt aus loslaufen. Eine Gleichverteilung, oder ein Histogramm aller Zeichen in meinem UDF-Ordner, oder der Buchstabenverteilung in irgendeiner Sprache. In diesem Fall müsste man dem kodierten Text z.B. 2 bit voranstellen damit der Decoder weiß welche Verteilung er als Startwert nehmen soll. Man könnte auch die nicht adaptive Version so verwenden und statt einem Baum nur eine Baumnummer in den kodierten Text schreiben. Das wäre aber bei weitem suboptimaler, da dieser Baum dann nicht angepasst werden würde und man nicht für jeden beliebigen Text einen gut passenden Baum im Decoder hinterlegen kann. Eine Hand voll Verteilungen reichen bei der adaptiven Version aber vollkommen aus um immer ein gutes Ergebnis zu erzielen.


    Nachteile:

    - Da nach JEDEM ZEICHEN alles neu aufgebaut werden muss ist diese Methode unglaublich langsam (eine Version mit Min-Heap bastele ich gerade bin aber noch nicht zufrieden).

    - Da die Wahrscheinlichkeitstabelle laufend angepasst wird ist sie zu keinem Zeitpunkt "wirklich" optimal. Verglichen mit einem "normalen" Huffman-Code ist die adaptive Version je nach situation unterlegen und erzeugt längeren Output als notwendig.

    - Der Textanfang wird zwangsweise suboptimal kodiert, da die Startverteilung (z.B. die Gleichverteilung) nicht immer gut auf die vorliegende Zeichenfolge passt.

    - Habe ich langsam schon erwähnt? (auf meinem PC aktuell ca. 20-25 Zeichen/Sekunde)


    Villeicht kann ja jemand das Skript gebrauchen, daher landet es hier :)


    Edit: 12.03.19:

    Jetzt funktioniert das ganze mit Min-Heap und ist ca. 30% schneller als vorher. Es hat viel Spaß gemacht das Teil im Rahmen der Geschwindigkeit von AutoIt zu optimieren. Wenn man die Methode aber tatsächlich auch benutzen will sollte man es in einer anderen Sprache tun... 30 Zeichen/Sek ist unzureichend, alleine diesen Post hier zu kodieren würde ne Stunde dauern :D



    lg

    M