2010-12-29 5 views
8

Ich versuche, die Verbesserung einiger Bilder zu automatisieren, die zu einem digitalen Rahmen übertragen werden sollen. Ich habe einen Code an Ort und Stelle, der die Größe ändert, ein Datum/eine Zeit zu der am wenigsten signifikanten Ecke des Bildes hinzufügt und Paare von Portraitbildern aneinanderfügt, um zu vermeiden, dass ein einzelnes Portrait auf dem 41:20 Bildschirm mit niedriger Auflösung angezeigt wird.RGB zu HSV Konvertierung mit PIL

Ich habe einen Helligkeits-Stretching-Filter für jene Bilder implementiert, bei denen die Beleuchtung nicht so gut war, mit der colorsys.rgb_to_hsv-Funktion, um H-, S-, V-Bänder zu berechnen, die auf der V-Eins arbeiten und dann wieder zurück in RGB konvertieren Speichern eines JPEG im digitalen Rahmen. Offensichtlich dauert die Konvertierung viel Zeit, selbst mit itertools Tricks; Ich habe es geschafft, Dinge mit psyco zu verbessern.

Allerdings habe ich ein Beispiel für die PIL Image.convert wo RGB zu XYZ color space umgewandelt werden kann eine 4 × 4-Matrix als zweites Argument an die convert Methode, und ich habe zu fragen:

Wie kann ich konvertieren RGB zu HSV (und dann HSV zurück zu RGB) mit einer benutzerdefinierten Matrix in der Methode convert Aufruf? (Kleine Rundungsfehler sind in diesem Fall nicht wichtig, deshalb stört es mich nicht, dass jedes Band als eine Reihe von 0 ... 255 ganzen Zahlen ausgedrückt wird)

Vielen Dank im Voraus.

+0

Hinweis: Es ist möglich, dass das, was ich mache, auch mit der Funktion 'ImageOps.autocontrast' erledigt werden kann; Ich möchte jedoch in der Lage sein, den Filter nach Bedarf zu erweitern (z. B. um die Sättigung etwas aufzupeppen), und deshalb möchte ich eine schnelle Methode für RGB ↔HSV). – tzot

Antwort

1

Obwohl ich Referenzen [1] gesehen habe, die behaupten HSV-Farbraum ist lineare Transformation von RGB, was implizieren würde, dass es mit einer Matrix gemacht werden könnte, war ich nicht in der Lage, für mich selbst zu finden oder zu bestimmen wie eine solche Matrix aussehen würde. Auf eine Art überrascht mich das nicht wirklich, basierend auf all den [ähnlichen] nicht-matrix-prozeduralen Implementierungen, die ich auch gesehen habe - die Art, wie sie es tun, sieht nicht linear aus.

Wie auch immer, ich stieß auf einen [etwas veraltet] Artikel in ehemaligen SGI Forscher Paul Haeberli 's Online-Computergrafik Notebook mit dem Titel Matrix Operations for Image Processing, die beschreibt, wie man eine Reihe von verschiedenen Farbtransformationen mit 4x4 Matrizen, die helfen könnten Sie. Alle angegebenen Beispiele arbeiten direkt mit RGB-Farbbildern und können wie geometrische Matrixtransformationen durch Verkettung zu einer einzigen Matrix kombiniert werden.

Hoffe, das hilft.


[1]: Farbraumkonvertierungen < http://www.poynton.com/PDFs/coloureq.pdf>:

2.7.3 HSL (Hue Sättigung und Helligkeit)

Dies stellt eine Fülle von ähnlichen Farbräume, alternative Namen umfassen HSI (Intensität), HSV (Wert), HCI (Chroma/Farbigkeit), HVC, TSD (Farbton Sättigung und Dunkelheit) usw. Die meisten dieser Farbräume sind linear transformiert von RGB und sind daher gerätespezifisch und nichtlinear. Ihr Vorteil liegt in die äußerst intuitive Art der Angabe von Farbe. Es ist sehr einfach, wählen Sie einen gewünschten Farbton und dann ändern Sie leicht durch Anpassung von seine Sättigung und Intensität.

+0

Danke, ich untersuche es. Wie Sie, der Code, den ich bis jetzt gesehen habe, macht mich nicht optimistisch über eine positive Antwort auf meine Frage ... – tzot

+0

Etwas, das nahe kam (aber keine Zigarre): [Konvertieren zwischen RGB und ...] (http: //local.wasp .uwa.edu.au/~ pbourke/texture_colour/convert /) von Paul Bourke. Leider verzerrt die Umwandlung hin und her YIQ/YUV viel die Farbinformation; vielleicht liegt das an den wenigen Dezimalstellen der Zahlen in den Matrizen. In jedem Fall sind sie nicht so wie sie sind nützlich. – tzot

+0

Die Transformationen sind in der Tat linear, aber sie sind stückweise, daher denke ich, dass es unmöglich ist, mit einer einzigen Matrix zu transformieren (und ich bin mir nicht sicher, ob es sinnvoll oder möglich wäre, "stückweise Matrizen" zu verwenden). – heltonbiker

0

Die Formel zur Umwandlung eines RGB-Werts in einen HSV-Wert finden Sie hier: http://www.rapidtables.com/convert/color/rgb-to-hsv.htm. Ich brauchte es einmal umgekehrt und machte die folgende Funktion dafür.

def hsb2rgb(hsb): 
    ''' 
    Transforms a hsb array to the corresponding rgb tuple 
    In: hsb = array of three ints (h between 0 and 360, s and v between 0 and 100) 
    Out: rgb = array of three ints (between 0 and 255) 
    ''' 
    H = float(hsb[0]/360.0) 
    S = float(hsb[1]/100.0) 
    B = float(hsb[2]/100.0) 

    if (S == 0): 
     R = int(round(B * 255)) 
     G = int(round(B * 255)) 
     B = int(round(B * 255)) 
    else: 
     var_h = H * 6 
     if (var_h == 6): 
      var_h = 0 # H must be < 1 
     var_i = int(var_h) 
     var_1 = B * (1 - S) 
     var_2 = B * (1 - S * (var_h - var_i)) 
     var_3 = B * (1 - S * (1 - (var_h - var_i))) 

     if  (var_i == 0): 
      var_r = B  ; var_g = var_3 ; var_b = var_1 
     elif (var_i == 1): 
      var_r = var_2 ; var_g = B  ; var_b = var_1 
     elif (var_i == 2): 
      var_r = var_1 ; var_g = B  ; var_b = var_3 
     elif (var_i == 3): 
      var_r = var_1 ; var_g = var_2 ; var_b = B 
     elif (var_i == 4): 
      var_r = var_3 ; var_g = var_1 ; var_b = B 
     else: 
      var_r = B  ; var_g = var_1 ; var_b = var_2 

     R = int(round(var_r * 255)) 
     G = int(round(var_g * 255)) 
     B = int(round(var_b * 255)) 

    return [R, G, B] 
+0

Ich verwende bereits das 'colorsys'-Modul. Die Frage wurde nach einer Matrix gestellt, die mit der Funktion 'convert' verwendet werden kann. – tzot