Frage

Wie berechnet ich die Ähnlichkeit zwischen zwei Farben im RGBA -Farbton? (wo die Hintergrundfarbe natürlich unbekannt ist)

Ich muss ein RGBA -Image in eine Palette von RGBA -Farben umgestalten, indem ich das finde Beste Paletteneintrag für jedes Pixel im Bild*.

Im RGB -Farbraum kann angenommen werden, dass die am kleinste euklidische Entfernung derjenige ist. Dieser Ansatz funktioniert jedoch nicht in RGBA, z. B. euklidischer Entfernung von rgba(0,0,0,0) zu rgba(0,0,0,50%) ist kleiner als zu rgba(100%,100%,100%,1%), aber letzteres sieht viel besser aus.

Ich benutze vornüchterte RGBA -Farbfläche:

r = r×a
g = g×a
b = b×a

Und ich habe diese Formel ausprobiert (bearbeiten: Weitere Informationen finden Sie in der Antwort unten, um eine bessere Formel zu erhalten):

Δr² + Δg² + Δb² + 3 × Δa²

Aber es tut es nicht sehen Optimal - In Bildern mit semitransparenten Gradienten findet es falsche Farben, die Diskontinuitäten/scharfe Kanten verursachen. Lineare Proportionen zwischen undurchsichtigen Farben und Alpha scheinen fischig zu sein.

Was ist die optimale Formel?


*) Für die Einfachheit dieser Frage ignoriere ich Fehlerdiffusion, Gamma und psychovisuelle Farbräume.


Etwas verwandt: Wenn Sie in diesem nichteuklidischen RGBA-Raum die nächste Farbe finden möchten, VP-Bäume sind die besten.

War es hilfreich?

Lösung

Endlich habe ich es gefunden! Nach gründlichem Test und Experimentieren sind meine Schlussfolgerungen:

  • Der richtige Weg ist zu berechnen maximal Möglicher Unterschied zwischen den beiden Farben.
    Formeln mit einer geschätzten durchschnittlichen/typischen Differenz hatten Raum für Diskontinuitäten.

  • Ich konnte keine Arbeitsformel finden, die die Entfernung berechnet, ohne RGBA -Farben mit einigen Hintergründen zu mischen.

  • Es ist nicht erforderlich, jede mögliche Hintergrundfarbe zu berücksichtigen. Es kann vereinfacht werden, maximal und minimal für jede der R/G/B -Kanäle separat zu mischen:

    1. Mischen Sie den Kanal in beiden Farben mit Kanal= 0 als Hintergrund, messen Sie den quadratischen Unterschied
    2. Mischen Sie den Kanal in beiden Farben mit Kanal= Max als Hintergrund, messen Sie den quadratischen Unterschied
    3. Nehmen Sie höhere der beiden.

Glücklicherweise ist es trivial, mit "White" und "Black" zu mischen, wenn Sie Premultiplied Alpha verwenden (r = r×a).

Die vollständige Formel lautet:

max((r₁-r₂)², (r₁-r₂ - a₁+a₂)²) +
max((g₁-g₂)², (g₁-g₂ - a₁+a₂)²) +
max((b₁-b₂)², (b₁-b₂ - a₁+a₂)²)

C Quelle einschließlich SSE2 -Implementierung.

Andere Tipps

Mehrere Prinzipien:

  1. Wenn zwei Farben das gleiche Alpha haben, ist rgbadistance = rgbdistance * (alpha / 255). Kompatibel mit RGB -Farbabstandalgorithmus, wenn beide Alpha 255 sind.
  2. Alle Farben mit sehr niedrigem Alpha sind ähnlich.
  3. Der RGBadistance zwischen zwei Farben mit demselben RGB ist linear von Delta Alpha abhängig.
double DistanceSquared(Color a, Color b)
{
    int deltaR = a.R - b.R;
    int deltaG = a.G - b.G;
    int deltaB = a.B - b.B;
    int deltaAlpha = a.A - B.A;
    double rgbDistanceSquared = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB) / 3;
    return deltaAlpha * deltaAlpha / 2.0 + rgbDistanceSquared * a.A * b.A / (255 * 255);
}

Meine Idee ist es, alle möglichen Hintergrundfarben zu integrieren und den quadratischen Fehler zu messen.

IE für jede Komponente berechnen (mit dem roten Kanal wie Beispiel hier)

Integral von 0 bis 1 ((r1*a1+rb*(1-a1))-(r2*a2+rb*(1-a2)))^2*drb

Was, wenn ich korrekt berechnet habe, bewertet:

dA=a1-a2
dRA=r1*a1-r2*a2
errorR=dRA^2+dA*dRA+dA^2/3

Und dann diese über R, G und B. summe

Erstens ein sehr interessantes Problem :)
Ich habe keine vollständige Lösung (zumindest noch nicht), aber es gibt zwei offensichtliche Extremfälle, die wir in Betracht ziehen sollten:
Wann Δa==0 Das Problem ähnelt dem RGB -Raum
Wann Δa==1 Das Problem liegt nur auf dem Alpha-1-DIM-Raum
Die Formel (die dem, die Sie angegeben haben, ist also sehr ähnlich), das das erfüllt, ist:
(Δr² + Δg² + Δb²) × (1-(1-Δa)²) + Δa² oder (Δr² + Δg² + Δb²) × (1-Δa²) + Δa²

In jedem Fall wäre es wahrscheinlich so etwas wie (Δr² + Δg² + Δb²) × f(Δa) + Δa²

Wenn ich Sie wäre, würde ich versuchen, es mit verschiedenen RGBA -Paaren und verschiedenen Hintergrundfarben zu simulieren, um das Beste zu finden f(Δa) Funktion. Nicht sehr mathematisch, aber Ihnen eine genau genug Antwort geben

Ich habe es noch nie getan, aber Theorie und Praxis sagen, dass die Konvertierung der RGB Luminanz -Chrominanz Helfen Sie dabei, die besten Übereinstimmungen zu finden. Ich würde den Alpha -Kanal in Ruhe lassen, da Transparenz wenig bis nichts mit dem „besseren“ Teil zu tun hat.

Diese Xmasse habe ich einige Photomosaik für Geschenke mit Open-Source-Software gemacht, die Fragmente des Originalbildes mit einer Sammlung von Bildern entspricht. Das scheint ein schwierigeres Problem zu sein, als das, das Sie lösen möchten. Eines von ihnen war Programme war Metapixel.

Zuletzt sollte die beste Option sein, eine vorhandene Bibliothek zu verwenden, um das Bild in ein Format wie PNG umzuwandeln, in dem Sie die Palette steuern können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top