HSV (Saettigung) eines Bildes veraendern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
HappyMonk
User
Beiträge: 5
Registriert: Freitag 7. April 2006, 18:44

Hallo erstmal,

ich experimentiere z. Zt. mit Pil herum und versuche die Saettigung eines Bildes zu veraendern, kann aber dazu nichts genaueres finden. Ich hab schon danach gegoogled und hier im forum gesucht aber ich kann dazu nichts finden. Das Ziel ist es die Saettigung eines Bildes um 200% zu erhoehen. Bin fuer jede Antwort dankbar...

HappyMonk
BlackJack

Ich weiss nicht, ob's im HSV Farbmodell operiert, aber es macht Bilder "doppelt so bunt":

Code: Alles auswählen

import Image, ImageEnhance

image = Image.open('test.jpg')
enhancer = ImageEnhance.Color(image)
enhanced_image = enhancer.enhance(2)
enhanced_image.show()
HappyMonk
User
Beiträge: 5
Registriert: Freitag 7. April 2006, 18:44

@ Black_Jack: Ist zwar nicht genau das was ich gesucht habe aber das sieht schon recht vielversprechend aus. Vielen Dank...
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Man müsste die RGB-Werte nach HSV und zurück rechnen können.
Ich bin uach sicher irgendwo schonmal Python-Code dafür gesehen zu haben, weiß aber nicht mehr wo. Entweder wars tatsächlich die PIL selbst oder es war soya.

Mathematisch suchst du ja "nur" nach bestimmten Basisvektoren für den "Farbvektorraum" der mit den Vektoren R, G und B aufgespannt wird 8)

Ansonsten einfach mal googlen, da findet man bestimmt ein bisschen pseudocode zu dem thema
BlackJack

Komplett braucht man die Umrechnung gar nicht machen, wenn man nur die Sättigung ändern möchte. Hier ist ein wenig Quelltext um die Sättigung eines RGB-Bildes zu verändern.

Einmal eine reine Python-Variante, die natürlich nicht so besonders schnell ist. Mit psyco lief's bei mir ca. 50% schneller. Und dann gibt's weiter unten noch eine Pyrex-Variante, die sehr flott ist.

Code: Alles auswählen

from __future__ import division
import Image
# import _test

# import psyco
# psyco.full()

def change_saturation(rgb, factor):
    """Change the saturation of a RGB pixel.
    
    This function takes an RGB pixel as tuple and returns an RGB pixel with its
    saturation changed by a given `factor`.  Saturation means saturation in the
    HSV color model.  A factor of ``0.0`` results in a grey pixel and a factor
    of ``1.0`` returns the values unchanged.  For higher factors the new pixels
    saturation value is clipped to ``1.0``.
    """
    max_value = max(rgb)
    if max_value:
        min_value = min(rgb)
        length = max_value - min_value
        new_saturation = (length / max_value) * factor
        if new_saturation > 1:
            new_saturation = 1
        new_min_value = int(max_value * (1 - new_saturation))
        new_rgb = list()
        for component in rgb:
            if component == min_value:
                component = new_min_value
            elif component != max_value:
                component = int(((component - min_value) / length)
                                * (max_value - new_min_value) + new_min_value)
            new_rgb.append(component)
        return tuple(new_rgb)
    else:
        return rgb


def double_saturation():
    image = Image.open('gfx/test.jpg')
    image.putdata([change_saturation(pixel, 2) for pixel in image.getdata()])
    # _test.change_saturation(image, 2)
    image.show()


if __name__ == '__main__':
    double_saturation()
Und hier der Pyrex-Quelltext:

Code: Alles auswählen

import array


cdef void _change_saturation(unsigned char *image_data,
                             unsigned int pixel_count,
                             double factor):
    cdef unsigned char *new_rgb
    cdef unsigned char max_value, min_value, new_min_value
    cdef unsigned char component
    cdef unsigned int dummy, i
    cdef double length, new_saturation

    new_rgb = image_data
    for dummy from 0 <= dummy < pixel_count:
        min_value = max_value = new_rgb[0]
        for i from 1 <= i < 3:
            if new_rgb[i] < min_value:
                min_value = new_rgb[i]
            elif new_rgb[i] > max_value:
                max_value = new_rgb[i]
        
        if max_value:
            length = max_value - min_value
            new_saturation = (length / max_value) * factor
            if new_saturation > 1:
                new_saturation = 1
            new_min_value = max_value * (1 - new_saturation)
            for i from 0 <= i < 3:
                component = new_rgb[i]
                if component == min_value:
                    component = new_min_value
                elif component != max_value:
                    component = (((component - min_value) / length)
                                 * (max_value - new_min_value) + new_min_value)
                new_rgb[i] = component
        new_rgb = new_rgb + 3


def change_saturation(object image, double factor):
    """Change the saturation of `image` by `factor`.
    
    The `image` has to be in RGB mode.  Otherwise the result is undefined and
    may look funny.
    
    :TODO: Handle other modes than RGB.  At least RGBA, RGBX, BGR and P.
    """
    cdef unsigned int data_ptr, size
    
    data = array.array('c', image.tostring())
    data_ptr, size = data.buffer_info()
    _change_saturation(<unsigned char*> data_ptr, size / 3, factor)
    image.fromstring(data.tostring())
Übersetzt habe ich den mit:

Code: Alles auswählen

pyrexc _test.pyx
gcc -O6 -shared -fPIC -I/usr/include/python2.4/ -o _test.so _test.c
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

gcc -O6
-O3 hätte es auch getan, alle -Oi für i > 3 wird vom gcc als -O3 behandelt...
--- Heiko.
HappyMonk
User
Beiträge: 5
Registriert: Freitag 7. April 2006, 18:44

Danke fuer die vielen Antworten : )
Antworten