3

Je veux ajuster les niveaux de couleur d'une image en python. Je peux utiliser n'importe quelle bibliothèque python qui peut facilement être installée sur mon bureau Ubuntu. Je veux faire la même chose que -level de ImageMagick (http://www.imagemagick.org/www/command-line-options.html#level). PIL (Python Image Library) ne semble pas l'avoir. J'ai appelé convert sur l'image, puis relire le fichier, mais cela semble inutile. Y a-t-il un moyen meilleur/plus rapide?Faire la même chose que "-level" de ImageMagick dans python/PIL?

Répondre

6

Si j'ai bien compris l'option -level de ImageMagick, alors la fonction level_image que je fournis devrait faire ce que vous voulez.

Deux choses à noter:

  • la vitesse peut certainement améliorer
  • il fonctionne seulement avec des images RVB
  • l'algorithme passe par le HSV colorspace et affecte uniquement la V (luminosité) composant

Le code:

import colorsys 

class Level(object): 

    def __init__(self, minv, maxv, gamma): 
     self.minv= minv/255.0 
     self.maxv= maxv/255.0 
     self._interval= self.maxv - self.minv 
     self._invgamma= 1.0/gamma 

    def new_level(self, value): 
     if value <= self.minv: return 0.0 
     if value >= self.maxv: return 1.0 
     return ((value - self.minv)/self._interval)**self._invgamma 

    def convert_and_level(self, band_values): 
     h, s, v= colorsys.rgb_to_hsv(*(i/255.0 for i in band_values)) 
     new_v= self.new_level(v) 
     return tuple(int(255*i) 
       for i 
       in colorsys.hsv_to_rgb(h, s, new_v)) 

def level_image(image, minv=0, maxv=255, gamma=1.0): 
    """Level the brightness of image (a PIL.Image instance) 
    All values ≤ minv will become 0 
    All values ≥ maxv will become 255 
    gamma controls the curve for all values between minv and maxv""" 

    if image.mode != "RGB": 
     raise ValueError("this works with RGB images only") 

    new_image= image.copy() 

    leveller= Level(minv, maxv, gamma) 
    levelled_data= [ 
     leveller.convert_and_level(data) 
     for data in image.getdata()] 
    new_image.putdata(levelled_data) 
    return new_image 

S'il y a un moyen de faire la conversion RVB → HSV (et vice versa) en utilisant PIL, alors on peut diviser en bandes H, S, V, utiliser la méthode .point de la bande V et la reconvertir en RGB, accélérer le processus par beaucoup; Cependant, je n'ai pas trouvé un tel moyen.

3

Pourquoi ne pas utiliser PythonMagick? C'est une interface Python pour Image Magick.