回答

6

如果我正確理解了ImageMagick的-level選項,那麼我提供的level_image函數應該做你想做的。

有兩點需要注意:

  • 速度絕對可以提高
  • 它目前只適用於RGB圖像作品
  • 算法經過了HSV色彩空間,並且隻影響V(亮度)部件

的代碼:

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 

如果有某種方法可以使用PIL進行RGB→HSV轉換(反之亦然),那麼可以將其分割爲H,S,V帶,使用V帶的.point方法並將其轉換回RGB,加速這個過程很多;但是,我還沒有找到這樣的方式。

3

爲什麼不使用PythonMagick?它是Image Magick的Python界面。