[GDI+] Bild aus anderem Bild zusammensetzen

  • Moin,


    habe letztens ein "Kunstwerk" gesehen das nichts anderes war als aus vielen kleinen Bildern/Teilbildern ein neues Bild zusammenzusetzen. Das lässt sich auch mit einem Skript ziemlich einfach erledigen.


    Meine Methode ist folgendes:

    - Teile Quellbild (Q), Zielbild (Z) und zusammengesetztes Bild (R) in Rechtecke der Größe P * P

    - Wähle zufälliges Teilbild von Z

    - Wähle aus den Teilbilgern von Q das Bild was am besten passt aus

    - Lösche das gewählte Bild aus Q (man kann Teilbilder nur 1x nutzen)

    - Setze das gewählte Bild an die richtige Stelle von R

    - Solange bis keine Teilbilder von Q mehr übrig sind


    Probleme:

    - Ewig lange Laufzeit (und aus irgendwelchen Gründen gibt mein ASM manchmal nichts aus, wenn man zu schnell auf den Speicher zugreift, daher das Sleep(0) vor jedem Aufruf)

    - Die letzten paar Teilbilder passen nicht gut, da in Q nur noch z.B. 5 übrig sind die aber alle nicht zu den letzten 5 Teilen aus Z passen.

    - (Zumindest in jetziger Ausführung) müssen Q und Z exakt gleichgroß sein und Breite sowie Höhe muss durch P teilbar sein.

    - Nicht optimiert, da geht geschwindigkeitstechnisch noch einiges, aber ich hatte keine Lust :(


    Im Beispiel habe ich natürlich etwas geschummelt und zwei Bilder beigelegt die sich super ineinander umwandeln lassen weil sie gleich viel Schwarz und Weiß enthalten.:*


    Falls jemand Ideen für einen besseren Algorithmus hat, oder genau das gleiche auch schonmal gebastelt hat kann es ja hier verlinken :)


    Edit 20.10.2018:

    Habe erstmal den Code aufgeräumt (und den Algorithmus klarer gemacht, sodass man jetzt viel leichter daran herumbasteln kann) und ein paar kleine Änderungen vorgenommen. Die Funktionalität ist vollständig unverändert (es wird nach wie vor der gleiche O(n²) schwere Algorithmus verwendet). Durch einige Optimierungen/Fehlerbeseitigungen (DANKE an Andy für seinen xmm0 Tip) konnte ich ca. 30% mehr Tempo rausholen (statt 15s braucht das Skript nun nur noch 11s).


    Beim nächsten Mal wird der Algorithmus selbst angegangen, habe da schon einige gute Ideen die eine n^(3/2) Komplexität erreichen könnten. Ausprobieren hat gezeigt, die Laufzeit damit ca. 10-15x kürzer ist (für das kleine Testbild), bei großen Bildern ist da natürlich weeesentlich mehr drin, allerdings bin ich mit dem Ergebnis noch nicht zufrieden.


    Wer es ausprobieren will kann in Zeile 98 und 102 das $iUBound_SrcLinear durch Ceiling($iUBound_SrcLinear^0.5) ersetzen, damit wird nicht mehr allzuviel verglichen, das Resultat leidet aber deutlich. Andere Exponenten wie z.B. 0.8 ergeben nahezu das gleiche Ergebnis bei ca. 1/3 Laufzeit, da geht also was.


    Meine Hoffnung ist, dass zufälliges versuchen (anstatt lineares) ein nahezu identisches Ergebnis liefert wie die Ursprungsfunktion, aber 10x schneller läuft.) Zuletzt kommt noch eine Fehlerkorrektur die ich in Post3 schon angerissen habe, damit sollten die Resultätbilder weniger störende "offensichtlich falsche" Rechtecke mehr haben.


    Weiterhin halte ich vom Vergleich der Durchschnittsfarbe nicht viel, das würde zwar den ASM Teil beschleunigen (der sowieso schon schnell ist). Habe ausprobiert, dass eine Verkleinerung des Bildes von 512x512 auf 256x256 bei gleicher Zerlegung (also gleicher Anzahl) ca. 10% mehr Tempo bringt. Man könnte intern das Bild auf 1/x herunterskalieren um so nochmal ca. 50% rauszuholen, aber bei 1x1 Pixel vergleichen leidet die Genauigkeit extrem, der Trick soll ja sein dass die Teilbilder auch die Form ganz gut wiederspiegeln. Für einen "ersten Vergleich" kann man den 1px Vergleich ggf. heranziehen und wenn man sieht, dass das Teil sowieso nicht passt direkt zum nächsten wandern als einen "richtigen" Vergleich zu starten.


    Edit 24.10.2018:

    Sehr viel Bastelei später und sehr viele Erklärungen (die im Code stehen) später hat sich ergeben, dass man über soetwas wie "Qualitätsschalter" nicht drum herumkommt. Man muss irgendwo einstellen können was man haben will. Dafür gibt es jetzt eine ganze Palette verschiedene Sachen:

    - iPixelsize - Kennt man, in diese Stückchen wird das Bild zerlegt. Zukünftig soll das noch in W und H geändert werden damit es nicht immer gleichseitige Vierecke sein müssen

    - bMultipleds- False/True - Man kann nun erlauben Teile doppelt zu verwenden. Bei den meisten Bildern ist das Sinnvoll

    - iShuffleCount - Intern wird sehr viel gewürfelt. Was das bringt genau zu erklären sprengt den Rahmen, daher iShufflecount ist die Obergrenze für erlaubte Mehrfachvorkommen, falls bMultiples = true, und auch ansonsten bedeutet "ab und zu mal Würfeln" bessere Ergebnisse. Zu viel würfeln ist aber sinnlos, es sollte sich so im Rahmen 4 bis 64 bewegen, je nach Anzahl Teilbilder.

    - fExponent - Hier ist der Hauptgeschwindigkeitsschalter, er bestimmt wie viele Vergleiche durchgeführt werden. Bei z.B. e = 0.5 wird in jedem Durchlauf jedes Bild nur mit Sqrt(n) Teilbildern verglichen, sodass man damit von der n² Komplexität herunterkommt. Ist dieser Wert 1 wird Brute Force ALLES durchprobiert.

    - iCorrectionTime - Nachdem das Bild fertig ist werden gezielt Teile mit schlechter Abweichung so vertauscht, dass die Gesamtabweichung sinkt. Leider gibt es dafür kein gutes Maß "wie oft" man das machen muss (oder mir ist keines eingefallen), daher ist das ein Multiplikator. Bei Time = 1 wird die gleiche Zeit die der Zusammensetzalgo gebraucht hat erneut für Korrekturen aufgewendet. Hier kann sicherlich noch viel optimiert werden, aber es funktioniert erstmal.


    Kurz zusammengefasst gibt es Qualitätsprofile: low (Ergebnis ist besser als das best mögliche Ergebnis des vorherigen Algo und ca. 7x schneller), mid (ca. 3x schneller als vorher), high (vergleichbar schnell wie der vorherige, aber wesentlich besseres Ergebnis), max (Brute Force, langsam, wählt ÜBERALL das best passende Teil)


    Mal schauen wann ich Lust habe weiterzubasteln, have fun :)

    (wer läd eigentlich immer die alten Dateien herunter, die sind eigentlich nur zum Vergleich da damit man sieht was sich verändert hat^^)


    lg

    M

  • Hi,

    ich finde die Laufzeit sooo schlecht nicht einmal, und auch das Ergebnis ist imho völlig ok, aber ggf kann ich dir hier weiterhelfen:

    und aus irgendwelchen Gründen gibt mein ASM manchmal nichts aus, wenn man zu schnell auf den Speicher zugreift, daher das Sleep(0) vor jedem Aufruf)

    initialisiere "ganz oben" im Code das xmm0, bevor du es erstmalig ausliest!

    Ich vermute, du gehst davon aus, dass der Wert 0 ist?!

    Die Inhalte der XMM-Register enthalten, genau wie die meisten anderen Register auch, beim Einsprung in eine ASM-Funktion irgendwelche "übriggebliebenen" Werte!

    Kann gut sein, dass die Sleep()-Funktion von AutoIt "zufällig" auch XMM-Register beeinflusst!

    Und ohne das Sleep() steht dann in XMM0 irgendein Wert, der dir deine gesamte Berechnung durcheinanderhaut....


    //EDIT

    Habe jetzt mal deinen Code analysiert und einige Bilder "berechnet". Im ursprünglichen Algorithmus wird, bedingt durch das "shuffle" der Teilbilder, bei der Verwendung der "letzten" (nicht passenden) Teilbilder auch das ansonsten SEHR ansehnliche Ergebnisbild durch mehr oder wenige "unpassende" Pixel verschandelt.

    Ich habe den Code jetzt so abgewandelt, dass

    - die Abfrage If IsDllStruct($aIMG_Dst[$aPosDst[1]][$aPosDst[0]]) And IsDllStruct($aIMG_Src[$y][$x]) Thenkomplett entfernt werden kann, indem die Teilbilder nicht mehr gelöscht werden.

    Somit entfallen die "unpassenden" Pixel völlig und es wird für jedes Pixel das "passende" Gegenstück gefunden. Doppelte kann und muss es da natürlich geben, sieht aber Welten besser aus!

    Die Laufzeit wird um Äonen schneller, wenn du die "Differenz" der Pixel nicht jedes mal neu berechnest, sondern einfach einen "Mittelwert" der Farben RGB für jedes Teilbild (durch ASM-Code ermittelt) in einem Array (Struct) abspeicherst, und dann einfach das "nächste passende" suchst. Da würde sich auch sicher noch mehr optimieren lassen, ggf durch Indizierung.

    Jedenfalls ist nicht der ASM-Code die Begrenzung der Laufzeit, sondern wie üblich in diesen Fällen die vielen ineinander verschachtelten Schleifen, die der arme AutoIt-Interpreter durchnudeln muss....


    //EDIT2

    Wenn man dein Script mit dem Ansatz lässt, alle Pixel nur ein mal zu verwenden, dann bietet es sich an spiralförmig von der Mitte aus das Bild (R) zu füllen. Somit werden die "unpassendsten" Pixel immer am Rand verarbeitet und stören weniger. Bei völlig unterschiedlichen Q und Z bildet sich dann ein "Rahmen" der ggf. völlig neue Ansichten bietet^^

  • Auch wenn es nur ein kurzer Kommentar zu //EDIT2 ist:

    Hatte schon eine gute Idee um besonders störende Rechtecke zu entfernen.

    - Finde das Teilbild mit der größten Abweichung

    - Probiere vertauschungen aus bis eine gefunden wird die die Gesamtabweichung minimiert

    - Führe die Vertauschung aus

    - Solange bis z.B. Wurzel(Gesamtzahl Teilbilder) Vertauschungen durchgeführt wurden, oder keine Vertauschung mehr gefunden werden kann.


    Klingt wiedermal super Rechenaufwändig (bruteForce ftw) aber mit den vielen Optimierungen die ich mir ausgedacht, aber noch nicht programmiert habe (ich bin heute insg. DREI STUNDEN an Bahnhöfen gewesen weil wiedermal jeder Zug entweder nicht fährt oder so viel Verspätung hat, dass man den Anschluss verpasst und hatte daher viel Zeit nachzudenken) sollte das kein Problem mehr sein. Ich schätze allein durch ein paar Umstellungen hat man bei gleicher Funktionalität ca. 10-100x mehr Geschwindigkeit (sodass man auch ein FullHD Bild in einigen Sekunden verarbeiten kann).


    Die Sache mit "sollte man doppelte verwenden oder nicht" habe ich mir auch überlegt. In manchen Situationen wird man durch geschicktes Vertauschen das Resultat auch nicht mehr "retten" können, weil z.B. einfach andere Farben in Quelle und Ziel vorliegen. In dem Fall würde ich bis zu einem Abweichungs Grenzwert (den man empirisch ausprobieren und finden muss) trotzdem alle Teile nur 1x verwenden. Wird dieser Grenzwert überschritten wird das Quellbild resettet und es stehen wieder alle Teile genau 1x zur Verfügung, solange bis wieder der Grenzwert überschritten wird, und so weiter und so weiter. Dadurch sollte man (zusammen mit der Zufallswahl der Auszufüllenden Stellen) keine allzu auffälligen Wiederholungen haben. Was ich nämlich unter allen Umständen vermeiden möchte ist sowas wie dass das gleiche Teilbild 50x verwendet wird, nur weil es gut passt. Das mag zwar rechnerisch ein besseres Ergebnis liefern (und vllt auch auf den ERSTEN Blick optisch, aber sobald man näher hinsieht springt einem das ins Auge und man bekommt sofort Krebs).


    Den ASM Code habe ich hier:

    Und TATSACHE, ich speichere in xmm0 die Gesamtabweichung über alle Pixel und gehe davon aus, dass es 0 initialisiert ist. Bist du Hellseher? Woher wusstest du das? (Der Code war nicht beigelegt. Da war wohl Dr. Decompile am Werk, oder deine Glaskugel ist meiner weit überlegen)


    PS Der Code kommt eigentlich komplett ohne SSE aus, xmm wird nur zum hochzählen verwendet weil ein Register gefehlt hat. 3 Schläge auf den Hinterkopf für mich... Ich bin schon auf dem Level eines handelsüblichen Compilers angekommen :( (Wollte aber nicht zu viel Arbeit reinstecken, weil ich darin keinen Flaschenhals sehe, vorallem wenn ein AutoIt Befehl länger dauert als die Abweichung zwischen 2 Vollbildern zu berechnen... übertrieben dargestellt, so schnell ist das natürlich nicht :) )


    Oh wurde wohl doch ein langer Kommentar^^


  • Und TATSACHE, ich speichere in xmm0 die Gesamtabweichung über alle Pixel und gehe davon aus, dass es 0 initialisiert ist. Bist du Hellseher? Woher wusstest du das? (Der Code war nicht beigelegt. Da war wohl Dr. Decompile am Werk, oder deine Glaskugel ist meiner weit überlegen)

    Auf meinem Rechner benutze ich diverse Werkzeuge fürs Disassembling/Debugging (gut ist imho die letzte "freie" Version von IDA, solltest du unter IDA PRO FREE finden), aber um sich mal einen schnellen Überblich zu verschaffen schaue ich HIER https://onlinedisassembler.com/static/home/index.html

    IDA nehme ich gerne, um mir "dubiose" DLL´s und auch die Ergüsse von diversen Compilern anzuschauen....

    PS Der Code kommt eigentlich komplett ohne SSE aus, xmm wird nur zum hochzählen verwendet weil ein Register gefehlt hat

    So mache ich das idR auch, allerdings bringt das bei den neuen Prozessoren nichts oder nur sehr wenig an Geschwindigkeitsvorteil, da die Speicheranbindung über den Stack/Cache ein PUSH/POP auch in einem Takt abwickelt. ASM ist VIEL entspannter geworden^^

    Und wie gesagt, wenn dein Code funktioniert und du was gelernt hast, um so besser, da machen die Handvoll eingesparter oder "verschwendeter" Takte nichts aus.

    (Wollte aber nicht zu viel Arbeit reinstecken, weil ich darin keinen Flaschenhals sehe,

    Richtig!


    Was ich nämlich unter allen Umständen vermeiden möchte ist sowas wie dass das gleiche Teilbild 50x verwendet wird, nur weil es gut passt. Das mag zwar rechnerisch ein besseres Ergebnis liefern (und vllt auch auf den ERSTEN Blick optisch, aber sobald man näher hinsieht springt einem das ins Auge und man bekommt sofort Krebs).

    Ja, das kann bei "guten" Pixeln und Massen davon in einer Fläche zu unschönen Mustern führen, aber das könnte man bspw. durch die zufällige Auswahl unter den x " am besten passenden" Pixeln kompensieren.

    "Näher hinsehen" darf man sowieso nicht, allerdings habe ich festgestellt, dass man auch bei vermeintlich schlechten Ergebnissen durch zusammenkneifen der Augen und das dadurch "verschwimmende" Sehen erkennen kann, was auf dem Bild dargestellt ist.


    Ich schätze allein durch ein paar Umstellungen hat man bei gleicher Funktionalität ca. 10-100x mehr Geschwindigkeit (sodass man auch ein FullHD Bild in einigen Sekunden verarbeiten kann).

    Davon gehe ich auch aus....

    Ggf. könnte man sogar einen Pool von Bildern/Verzeichnissen vorberechnen, diese "Pixel" indizieren und dann verwenden.

    Die "Farbe" analysieren, diese als Index verwenden und auf das "Pixel" zugreifen wird wohl die schnellste Methode sein.

  • Hallo Andy !

    Auf meinem Rechner benutze ich diverse Werkzeuge fürs Disassembling/Debugging (gut ist imho die letzte "freie" Version von IDA, solltest du unter IDA PRO FREE finden)


    Sucht man nach IDA PRO FREE, findet man u.A. einen Link der Zeitschrift CHIP.

    -> Titel : IDA Pro - Free (Letzte Freeware-Version) - Version 5.0 - vom 15.05.2014

    Allerdings traue ich dem 'sicheren Chip-Installer' nicht über den Weg :/.


    Auf der offiziellen Seite von Hex-Rays wird die Version 5.0 (natürlich) nicht mehr angeboten ;).


    Die Bezugsquelle, die mir noch am seriösesten erscheint, stammt aus dem Beitrag (von 2018) :

    https://reverseengineering.sta…lder-versions-of-ida-free

    Zitat

    You can download IDA free 5.0 from here https://samsclass.info/126/proj/idafree50.exe the file from the website of Sam Bowne (@sambowne) he is Professor at City College San Francisco and teaching computer networking and security classes.

    Kommentar eines Users :

    That file matches what I downloaded from the IDA website years ago.

    SHA256: 8f83ba2b2173bbc3158300fa9e06ac3dc23165e6db6b67f9f0aba704c719eaf4

    Dort kann man tatsächlich die Datei idafree50.exe herunterladen !

    SHA256 : 8F83BA2B2173BBC3158300FA9E06AC3DC23165E6DB6B67F9F0ABA704C719EAF4

    MD5 : 82fe909bad9c1cbbfa65c8ce03188d47


    Meine Bitte/Frage an Dich :

    Verwendest Du die Version 5.0, und stimmen die Hashwerte überein ?


    Danke und Gruß

    Musashi

    "Die Definition von Wahnsinn ist, immer wieder das Gleiche zu tun und andere Ergebnisse zu erwarten." - Albert Einstein

  • Ist zwar OT aber Musashi


    Auf chip.de findest du unter diesem "Installer" immer den irreführenden Punkt "manuelle Installation". Das ist dann das übliche Herunterladen.

    Hi autoiter

    Danke für den Hinweis !

    Das mit der 'manuellen Installation' ist mir bekannt. Obwohl ich die Seite Chip.de selbst aber in meinem NoScript freigegeben habe, poppen trotzdem Werbevideos etc. auf. Ich bin insgesamt mit der Wahl meiner Downloadquellen vorsichtiger geworden;) . Da gehen einige Zeitschriften und Portale doch recht fragwürdige Wege.


    Nebenbei :

    Sooo OT finde ich diesen Dialog gar nicht - es gibt sicher auch andere, die an dem von Andy empfohlenen Programm interessiert sind.


    Danke und Gruß

    Musashi

    "Die Definition von Wahnsinn ist, immer wieder das Gleiche zu tun und andere Ergebnisse zu erwarten." - Albert Einstein

  • Ich finde es immer gut wenn über interessante Sachen diskutiert wird, macht nur, dafür ist ein Forum da :)


    #Update im ersten Post mit ersten Optimierungen.

  • Allerdings traue ich dem 'sicheren Chip-Installer' nicht über den Weg

    Hab jetzt auch mal nachgeschaut, der CHIP-Installer ist brauchbar, wenn man die 2-3 nicht benötigten Programme NICHT installiert^^

    Das impliziert allerdings, NICHT auf jeden sofort erreichbaren Button zu klicken, sondern auch den Text im Fenster zu lesen....

    Ich weiß, gerade für die "Pro´s" die 5x in der Woche ihren Rechner neu aufsetzen (müssen), ist das SEHR viel verlangt!


    Musashi ,

    Ich habe die letzte "Free"-Version seit deren Erscheinen auf meinen Rechnern, daher weiss ich auch nicht, wo die herkam....

  • Hab jetzt auch mal nachgeschaut, der CHIP-Installer ist brauchbar, wenn man die 2-3 nicht benötigten Programme NICHT installiert^^

    Fast immer gibt es rechts von dem Button einen kleinen dickgedruckten Text "Manuelle Installation" mit dem man ohne den Installer auskommt.

    Generell nutze ich chip überhaupt nicht mehr, weil mich dieses Installerzeugs einfach nur ankotzt (Adblock Werbung noch dazu) und man direkt beim Hersteller laden kann.

    Aber das soll ja nicht Thema hier sein.

  • Hallo Andy

    Erst einmal 'Danke' für das Feedback :thumbup:

    Hab jetzt auch mal nachgeschaut, der CHIP-Installer ist brauchbar, wenn man die 2-3 nicht benötigten Programme NICHT installiert^^ . Das impliziert allerdings, NICHT auf jeden sofort erreichbaren Button zu klicken, sondern auch den Text im Fenster zu lesen....

    Natürlich kann man unerwünschte 'Extras' wie Toolbars etc. in der Regel abklicken, und das Lesen der Texte gehört eh zum Pflichtprogramm. Trotzdem habe ich bei diesen 'Setupwrappern' schon erlebt, dass Änderungen vorgenommen wurden ohne dass man großartig gefragt wurde ;).

    Ich möchte diesen Aspekt hier aber nicht überstrapazieren - kann ja jeder halten wie er will.


    Ich habe die letzte "Free"-Version seit deren Erscheinen auf meinen Rechnern, daher weiß ich auch nicht, wo die herkam....

    Kenne ich, aber ggf. hast Du ja noch die Original-Setupdatei (idafree50.exe) auf deinem PC herumliegen.

    Anhand der o.a. Hashes könnte man die Datei aus meinem Link (Beitrag #5) dann verifizieren.

    Handelt es sich bei der von Dir angesprochenen 'letzten echten Freeware' von IDA denn überhaupt um die Version 5.0 ?


    Ich hoffe, ich gehe Dir mit meinen Fragen nicht auf die Nerven. Falls doch, gebe ich jetzt Ruhe ;)


    Edit :

    Generell nutze ich chip überhaupt nicht mehr, weil mich dieses Installerzeugs einfach nur ankotzt (Adblock Werbung noch dazu) und man direkt beim Hersteller laden kann.

    Leider bieten viele Hersteller ältere, insbesondere freie Versionen aber nicht mehr an. Stattdessen werden neue, eingeschränkte Testversionen verlinkt.


    Danke und Gruß

    Musashi

    "Die Definition von Wahnsinn ist, immer wieder das Gleiche zu tun und andere Ergebnisse zu erwarten." - Albert Einstein

    Einmal editiert, zuletzt von Musashi ()

  • Handelt es sich bei der von Dir angesprochenen 'letzten echten Freeware' von IDA denn überhaupt um die Version 5.0 ?

    Ja, 5.0 habe ich. Wobei ich auch noch eine ältere Version habe, die imho auch "einfacher" ist. Die ist aber auf meinem Rechner zuhause, bin zzt. unterwegs, hab daher die Version nicht.

    Aber 5.0 ist schon ok. Was man damit gegenüber der "PRO"-Version nicht machen kann, habe ich zumindest auch noch nicht vermisst^^

    Für die Puristen, man kann auch den KD (KernelDebugger) aus Windows nutzen, damit wühlt man sich durch ALLE Eingeweide an Code, heißt nicht umsonst KernelDebugger, damit kann man auch mal Treibern auf den Pelz rücken und andere eklige Sachen machen. Den KD habe ich auch ab und zu im Einsatz, aber immer weniger...man macht auch weniger, wo man solche Werkzeuge braucht :o)


    Um zu schauen, was Compiler aus Sourcecode machen, nutze ich auch https://godbolt.org

    Die haben etliche Compiler zur Auswahl, u.a. auch den ICC, den sich Otto Normalprogrammer nicht unbedingt leisten muss. Aber sehr fein, was der gegenüber den anderen Compilern aus dem Code rausholt bzw. "optimiert", sehr beeindruckend!


    Ansonsten gibt´s doch auch "AssembleIt64", incl. Debugger, da kann man auch schon recht viel mit machen :D

    AssembleIt V121.zip

  • damit sollten die Resultätbilder weniger störende "offensichtlich falsche" Rechtecke mehr haben.

    Imho ist das Problem nicht das "offensichtlich falsche" Pixel, sondern das "offensichtlich falsche" Pixel mitten im Bild!

    Gerade bei deinem Beispiel hat man reinweiße Pixel MITTEN IM BILD, bzw. mitten in den schwarzen bzw. dunklen Flächen! Das stört nicht nur, sondern vermurkst das komplette Ergebnis!

    Hat man diese "falschen" Pixel am Rand, kann man diesen ggf abschneiden und hat trotzdem noch ein ansehnliches Ergebnis.

    Oder man "erkennt" die "offensichtlich falschen" Pixel und wählt nur für diese noch mal aus den ursprünglichen Pixeln aus. Da kann man ja eine Schwelle festlegen, bspw. die letzten 10% "schlechter" Pixel einfach weglassen. Das würde auch verhindern, dass bei großen einfarbigen Flächen die schon angesprochenen unerwünschten Muster entstehen.

  • So Update im ersten Post. Das Problem mit den "offensichtlich falschen" Pixeln sollte (zumindest mit großer Wahrscheinlichkeit) gelöst sein. Sehr selten tritt es noch auf (wie das halt so ist mit Wahrscheinlichkeitsbasierten Verfahren). Ggf muss noch ein bisschen gebastelt werden.


    Außerdem ist die von Andy herzlich herbeigesehnte Brute Force Methode jetzt auch da :D

  • Gut geworden!:thumbup:


    Bei "Mid" kommen schon sehr gute Ergebnisse raus!


    //EDIT

    ...bei den beiden Beispielbildern^^

    Ich habe das Ganze mal mit "echten" Fotos wie bei meinen bisherigen Tests durchlaufen lassen, da wird auch bei Pixelgrößen von 8 das Ergebnis nur bei "Max" halbwegs brauchbar....

  • Ja irgendwie sind "echte" Bilder weniger Deckungsgleich als ich erwartet habe... Es ist möglich zwei Bilder geschickt so zu wählen, dass eine Umwandlung klappt, aber bei zufällig ausgewählten Bildern geht da nicht viel...


    (Klar dass ich als Beispielbild etwas gewählt habe bei dem es ausgezeichnet klappt :P)

  • Was wirklich gut klappt sind Portraits. Die würde ich aber auch nicht aus einer Landschaftsaufnahme erstellen lassen.


    Ähnlich funktionieren übrigens die gängigen Kompressionsverfahren bei Bildern. Dort werden auch "ähnliche" Strukturen bzw. Bildbereiche gesucht und ersetzt .


    Btw., ich hab deinen Assemblercode nur überflogen, ist es so, dass du die durchschnittliche "Farbe" von zwei zu vergleichenden Pixeln verwendest?

    Ggf. könnte man die "Pixel" zum Vergleich auch 3x um 90° drehen. ich bin sicher, da ist noch einiges an Potenzial vorhanden.

  • Das ASM berechnet Dif = ABS(R1 - R2) + ABS(G1 - G2) + ABS(B1 - B2) und summiert das über alle Pixel. Daher kann die Maximalabweichung 3*255=765/Pixel auch nicht überschreiten. Auf eine Gewichtung wurde bewusst verzichtet, ansonsten würde man eine Art "Grauwert" vergleichen und die "Farbe" würde zu wenig berücksichtigt.


    Ansich wäre eine vorherige Umwandlung in HSV wesentlich besser, da hier die Abstandsfunktion viel näher an dem liegt was man als Mensch wahrnimmt.


    Komprimieren wäre hiermit auch möglich. Angenommen man hätte z.B. 2^16 indizierte Teilbilder mit je 16x16 Pixel zur Verfügung (die nahezu alles abdecken), könnte man vermutlich mit einem einzigen Layer schon eine gute Approximation erreichen. Wenn man den Spaß dann weiterzieht mit mehreren Layern (also erstmal zieht man das was man approximiert hat von dem was man approximieren will ab und in jedem weiteren Schritt approximiert man die differenz des vorherigen schritts) schätze ich, kann man so ziemlich jedes "natürliche" Bild sehr gut kleinkriegen (angenommen 8 Layer mit je 16Bit/256px = 0.5 Bit/Px). Wenn man die 2^16 Teilbilder jetzt noch statistisch sortiert (die die am häufigsten benutzt werden nach vorne) kann man im 2ten Schritt einen Arithmetischen Encoder drüberjagen und sicherlich nochmal 50% rausholen. Aber das ist alles nur Theorie, so viel Zeit werde ich hier nicht mehr reinstecken :( Schätze mal es wird bei dieser Spielerei bleiben^^


    //OT

    Zur Bildkompression habe ich mir schon was anderes ausgedacht: Ein Convolutional Neural Network das via overfitting dazu gebracht wird, dass es nur ein einziges Bild erzeugen kann. Da es nur einen einzigen Zweck hat muss es nicht so viele Ebenen und so viele Filter haben (braucht also wenig Speicherplatz). Schätze mal das Kodieren dauert dann 2 Wochen und das Decodieren 1/10sek (wenn man es in AutoIt schreibt). Mit nem guten Parallelalgorithmus und einer Sprache die Multithreading gut unterstützt (z.B. Go) müsste das in ein paar Min codiert sein (immernoch viel zu lange und untauglich für echte Anwendungen).

  • Das ASM berechnet Dif = ABS(R1 - R2) + ABS(G1 - G2) + ABS(B1 - B2) und summiert das über alle Pixel. Daher kann die Maximalabweichung 3*255=765/Pixel auch nicht überschreiten. Auf eine Gewichtung wurde bewusst verzichtet, ansonsten würde man eine Art "Grauwert" vergleichen und die "Farbe" würde zu wenig berücksichtigt.

    Ja, genau so hatte ich das auch gemeint. "Mehr Grün" im Pixel sollte auch genau so ersetzt werden.

    Komprimieren wäre hiermit auch möglich

    Damit hatte ich mich schon im Deskstream ausführlich beschäftigt. Das dort beherrschende Limit ist ja die Übertragung der imho lokal schon recht gut und schnell komprimierten Bilder übers Netz.

    Mir persönlich reicht diese Geschwindigkeit aus, für Video in 800x600 mit >20fps um mal schnell auf nem anderen Rechner zu gucken was da vor sich geht ist das i.o.

    Um die zu übertragenden Datenmengen einzustampfen hatte ich mir auch schon einen "Pool" von verwendeten 2x2 (3x3 oder 4x4) großen Pixelblöcken vorgestellt,der dynamisch bei bspw. jedem 10. übertragenen Frame neu berechnet wird. Da sowohl Sender als auch Empfänger als Grundlage die gleichen Bilderverwenden, wäre auch ein Abgleich übers Netz obsolet, lediglich bei einer Übertragungsstörung müssten beide "neu" starten.

    Man würde dann nicht mehr die reinen Pixeldaten übertragen, sondern lediglich die Adressen der Pixelblöcke. Eine Verschlüsselung würde sich somit komplett einsparen lassen.....