Hallo Leute, mich beschäftigt zur Zeit eine Frage. Angenommen, ich habe 2 Bilder: Ein 32bit PNG-Bild mit Transparenzen Das selbe Bild nochmal, aber zusätzlich mit einem Overlay versehen, das ebenfalls Transparenzen hat. Kann man irgendwie die beiden Bilder so voneinander subtrahieren, dass nur das reine Overlay zurückbleibt? Ein Beispiel: Ein Windows-Programm hat ein Icon, eine Verknüpfung darauf hat links unten noch den Verknüpfungs-Pfeil als Overlay. Jetzt stellt euch das Icon und das Overlay noch mit Transparenzen vor. Ich habe das reine Programmsymbol und das Symbol mit Overlay vorliegen. Das reine Overlay habe ich nicht und möchte es irgendwie "berechnen". Geht das irgendwie? Entweder als fertige Freeware-Lösung, oder als Link auf einen Algorithmus, dann könnte ich es mir selber implementieren wenn ich die passenden Formeln habe...
Photoshop benutzen, es per Hand durchführen und ein Macro aufzeichnen. Das kannst Du dann auch alle Bilder loslassen.
Bin mir ziemlich sicher, dass das mit Imagemagick Compare geht: https://www.imagemagick.org/script/compare.php Ansonsten sagt ein Bild manchmal mehr als Tausend wirre Worte...
steckersammler schrieb: > Kann man irgendwie die beiden Bilder so voneinander subtrahieren, dass > nur das reine Overlay zurückbleibt? Wenn man weiß, wie das Overlay auf das Bild raufgerechnet ist, hat man eine Chance.
Soeren K. schrieb: > Ansonsten sagt ein Bild manchmal mehr als Tausend wirre Worte... Ok, dann hier mal Bilder als Beispiel: "Bild_mit_Overlay.png" und "Bild_ohne_Overlay.png" habe ich, "Overlay.png" will ich als "Differenz" der beiden irgendwie erzeugen. Die Bilder sind paint.net Screenshots auf 1200%, hier kann man die Transparenz der einzelnen Pixel hoffentlich erkennen/erahnen...
steckersammler schrieb: > mal Bilder als Beispiel: Na dann brauchst Du doch nur die Pixel einlesen, und immer dann wenn beide gleich sind gibt du ein transparentes Pixel aus. Du kannst eine Sprache deiner Wahl verwenden. Wenn Deine Sprache nicht direkt PNG einlesen kann, könntest Du das PNG zunächst in https://de.wikipedia.org/wiki/Portable_Anymap wandeln.
1 | convert Bild_mit_Overlay.png Bild_ohne_Overlay.png -compose Change-mask -composite difference.png |
Kann man sicher noch optimieren, aber nur für den Anfang - hab leider gerade nicht so viel Zeit. Siehe hier: http://www.imagemagick.org/Usage/compose/#changemask
Das Problem ist womöglich nicht immer eindeutig lösbar. Angenommen man hat folgende 2 Szenarien: 1) Pixel des Overlay sind entweder Volltransparent oder nicht Transparent 2) Pixel des Overlay sind Teiltransparent Im ersten Szenario ist es simpel, immer wenn das selbe Pixel bei beiden Bildern andere Werte haben ist es teil des Overlays. Aber im zweiten fall hast du ein Problem. Angenommen ein Pixel des Originalbilds war Schwarz ohne Transparenz, und das Overlay war Weiss mit 50% Transparenz. Das resultat wäre Grau ohne Transparenz. Wäre das Overlay jedoch nicht Transparent, sondern Grau, wäre das resultat ebenfalls Grau. In dem Fall könnte man somit nicht zwichen 50% transparentem weissem Overlay oder nicht transparentem Overlay unterscheiden. Wäre das Originalbild aber 100% Transparent, könnte man wieder die Methode von fall 1 anwenden. Somit kann man mit dem Transparentzlevel des Originalbilds einschränken, in welchem Bereich die Werte des Pixels des Overlays je nach Werten der Pixel der Vergleichsbilder Liegen. Jetzt rechne ich das mal nach, ich hoffe ich verrechne mich nicht. Gegeben sind die Vektoren A, B und C, welche ein correspondierendes Pixel von Original, Overlay, und Resultat repräsentieren. Der einfachheit halber verwende ich komponente 0 als Opazität, und den rest für die Farben. Als Wertebereich verwende ich hier 0 bis 1. C wäre also so zu berechnen, glaub ich:
1 | C = [ |
2 | (1-A0) * B0 + A0 |
3 | (1-B0) * A1 + B0 * B1 |
4 | (1-B0) * A2 + B0 * B2 |
5 | (1-B0) * A3 + B0 * B3 |
6 | ] |
Jetzt brauchen wir aber B anhand von A und C. Dazu stellen wir ein Gleichungssystem auf:
1 | B0 = (C0 - A0) / ( 1 - A0) |
2 | B0 = (C1 - A1) / (B1 - A1) |
3 | B0 = (C2 - A2) / (B2 - A2) |
4 | B0 = (C3 - A3) / (B3 - A3) |
Nach Auflösen zu B:
1 | B0 = (C0 - A0) / (1 - A0) |
2 | B1 = (C1 - A1) / B0 + A1 |
3 | B2 = (C2 - A2) / B0 + A2 |
4 | B3 = (C3 - A3) / B0 + A3 |
C0 muss immer grösser oder gleich A0 sein, weil wenn man ein Bild über ein anderes legt kann das Resultierende Bild transparenter sein als dass ursprüngliche Bild. Hier ist zu beachten, dass B0 für A0 = 1 undefiniert ist. Dies macht sinn, denn C0 muss im Wertebereich 0<=A0<=C0<=1 liegen, für A0=1 muss C1 somit ebenfalls 1 sein, und somit ist unbekannt ob das Overlay transparent oder identisch zum Original war, und somit auch wie transparent (B0) es war. Es kommt aber noch schlimmer. Viele Bildformate verwenden Werte zwischen 0 und 128 oder 0 und 256 für Transparenz. Das Verhältnis von C0 zu A0 wird benötigt, um sämtliche Komponenten des Overlays zu berechnen, da es dafür entscheidend ist, wie Transparent es ist. Deshalb wird der Wert von B0 exponentiell ungenauer je grässer A0 ist. C0 kann immer nur R-A0*R+1 werte annehmen, wobei R die anzahl möglicher Werte von A0 minus 1 ist. Beispiel: für R=255 und A0=254/255, kann C0 nur 2 Werte annehmen: 254/255 und 1. B0 ist immernoch im Bereich (254/255-254/255)/(1-254/255)<=B0<=(255/255-254/255)/(1-254/255), oder 0<=B0<=1. (B0 ist immer in dem Bereich). aber B0 kann von seinen 256 möglichen Werten zwischen 0 und 1 nur 0 oder 1 annehmen, weil C0 nur 2 werte haben konnte. Man müsste also für C0=0 raten, welcher wert zwischen 0 und 0.5 es ist, und für C=1 welcher zwischen 0.5 und 1. Bei A0=253/255 wären die berechenbaren Werte für B1 0, 0.5 und 1, usw. Um den richtigen Wert im möglichen Bereich zu erraten könnte man ein KNN verwenden, oder man könnte die änderungsrate benachbarter Pixel verwenden, oder man könnte es manuell zeichnen, etc. Auf jeden fall ist es nicht trivial, da beim kombinieren der Bilder genauigkeit verloren gegangen ist. PS: Eventuell muss man vor den Berechnungen den Colorspace anpassen, und ich habe nicht ausprobiert ob die Formeln stimmen.
Ich kann mir nicht vorstellen, dass mit einer Subtraktion so etwas machbar ist. Das Schlüsselwort hierbei ist die Transparenz, also ein völlig unbekannter Faktor. Als prozentualer Wert: Irgendwas zwischen 0 und 100%. In der Praxis kommt es nämlich zu "Mischungen" im Bereich der Überlappung. Somit ist aber das Original nicht mehr restaurierbar, bzw nicht mehr vorhanden. Du musst also den genauen Faktor kennen plus den verwendeten Algorithmus.
Ich habe den in meinem, ersten Post beschriebenen Algorithmus nun implementiert, es gibt sicher noch verbesserungspotential, aber es funktioniert bereits erstaunlich gut. Hier der Code: https://github.com/Daniel-Abrecht/tradiff Und eine online Demo: https://dpa.li/tradiff/ Einfach per drag & drop die Bilder ins canvas ziehen, und dann mit dem alpha gauss wert etwas herumspielen. Das Bild mit overlay muss ins 2te canvas.
Funktioniert wirklich schon recht gut! Im Ergebnis wäre es evtl. noch praktisch das Objekt einzufärben und auf ein leicht transparentes Anfangsbild zu setzen. Ich habe eben mal ein fehlendes Bauteil damit gesucht. Wurde auch gut gefunden, aber die Zuordnung wo es nun fehlt ist schwierig. Grüße, Björn
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.