Изменение оттенка изображения с помощью Python PIL

Используя Python PIL, я пытаюсь настроить оттенок данного изображения.

Мне не очень нравится графическое изображение жаргоны, поэтому под «корректировкой оттенка» я делаю операцию Photoshop под названием «Hue / saturation» : это равномерно изменить цвет изображения, как показано ниже:

  • Оригинал: оригинал
  • С оттенком, отрегулированным до +180 (красный): оттенок: -180
  • С оттенком, отрегулированным на -78 (зеленый): оттенок: -78

FYI, Photoshop использует масштаб от -180 до +180 для этой настройки оттенка (где -180 равно +180), что может представлять собой шкалу оттенков HSL (выраженную в 0-360 градусов).

То, что я ищу, – это функция, которая, учитывая изображение PIL и оттенок float внутри [0, 1] (или int внутри [0, 360], это не имеет значения), возвращает изображение с его оттенком, сдвинутым на как в приведенном выше примере.

То, что я сделал до сих пор, смехотворно и явно не дает желаемого результата. Он просто наполовину смешал мое исходное изображение с наполненным цветом слоем.

import Image im = Image.open('tweeter.png') layer = Image.new('RGB', im.size, 'red') # "hue" selection is done by choosing a color... output = Image.blend(im, layer, 0.5) output.save('output.png', 'PNG') 

(Пожалуйста, не смейся) результат: output.png

Заранее спасибо!


Решение : здесь обновлен код unutbu, чтобы он соответствовал тому, что я описал.

 import Image import numpy as np import colorsys rgb_to_hsv = np.vectorize(colorsys.rgb_to_hsv) hsv_to_rgb = np.vectorize(colorsys.hsv_to_rgb) def shift_hue(arr, hout): r, g, b, a = np.rollaxis(arr, axis=-1) h, s, v = rgb_to_hsv(r, g, b) h = hout r, g, b = hsv_to_rgb(h, s, v) arr = np.dstack((r, g, b, a)) return arr def colorize(image, hue): """ Colorize PIL image `original` with the given `hue` (hue within 0-360); returns another PIL image. """ img = image.convert('RGBA') arr = np.array(np.asarray(img).astype('float')) new_img = Image.fromarray(shift_hue(arr, hue/360.).astype('uint8'), 'RGBA') return new_img 

  • ANTIALIAS vs BICUBIC в PIL (Библиотека изображений Python)?
  • Как читать большой файл tif в python?
  • Как добавить все изображения из папки в кнопку (в моем кадре)
  • Marshaling PILON PIL Image с использованием SWIG
  • Поиск пустых областей в изображении
  • Использование Python PIL для превращения RGB-изображения в чистое черно-белое изображение
  • С помощью библиотеки изображений Python (PIL), как создать изображение с альфа-каналом над другим изображением?
  • библиотека декодера python captcha
  • 3 Solutions collect form web for “Изменение оттенка изображения с помощью Python PIL”

    Существует код Python для преобразования RGB в HSV (и наоборот) в модуле colorsys в стандартной библиотеке . Моя первая попытка

     rgb_to_hsv=np.vectorize(colorsys.rgb_to_hsv) hsv_to_rgb=np.vectorize(colorsys.hsv_to_rgb) 

    для векторизации этих функций. К сожалению, использование np.vectorize приводит к довольно медленному коду.

    Я смог получить примерно в 5 раз быстрее, переведя colorsys.rgb_to_hsv и colorsys.hsv_to_rgb в собственные операции numpy.

     import Image import numpy as np def rgb_to_hsv(rgb): # Translated from source of colorsys.rgb_to_hsv # r,g,b should be a numpy arrays with values between 0 and 255 # rgb_to_hsv returns an array of floats between 0.0 and 1.0. rgb = rgb.astype('float') hsv = np.zeros_like(rgb) # in case an RGBA array was passed, just copy the A channel hsv[..., 3:] = rgb[..., 3:] r, g, b = rgb[..., 0], rgb[..., 1], rgb[..., 2] maxc = np.max(rgb[..., :3], axis=-1) minc = np.min(rgb[..., :3], axis=-1) hsv[..., 2] = maxc mask = maxc != minc hsv[mask, 1] = (maxc - minc)[mask] / maxc[mask] rc = np.zeros_like(r) gc = np.zeros_like(g) bc = np.zeros_like(b) rc[mask] = (maxc - r)[mask] / (maxc - minc)[mask] gc[mask] = (maxc - g)[mask] / (maxc - minc)[mask] bc[mask] = (maxc - b)[mask] / (maxc - minc)[mask] hsv[..., 0] = np.select( [r == maxc, g == maxc], [bc - gc, 2.0 + rc - bc], default=4.0 + gc - rc) hsv[..., 0] = (hsv[..., 0] / 6.0) % 1.0 return hsv def hsv_to_rgb(hsv): # Translated from source of colorsys.hsv_to_rgb # h,s should be a numpy arrays with values between 0.0 and 1.0 # v should be a numpy array with values between 0.0 and 255.0 # hsv_to_rgb returns an array of uints between 0 and 255. rgb = np.empty_like(hsv) rgb[..., 3:] = hsv[..., 3:] h, s, v = hsv[..., 0], hsv[..., 1], hsv[..., 2] i = (h * 6.0).astype('uint8') f = (h * 6.0) - i p = v * (1.0 - s) q = v * (1.0 - s * f) t = v * (1.0 - s * (1.0 - f)) i = i % 6 conditions = [s == 0.0, i == 1, i == 2, i == 3, i == 4, i == 5] rgb[..., 0] = np.select(conditions, [v, q, p, p, t, v], default=v) rgb[..., 1] = np.select(conditions, [v, v, v, q, p, p], default=t) rgb[..., 2] = np.select(conditions, [v, p, t, v, v, q], default=p) return rgb.astype('uint8') def shift_hue(arr,hout): hsv=rgb_to_hsv(arr) hsv[...,0]=hout rgb=hsv_to_rgb(hsv) return rgb img = Image.open('tweeter.png').convert('RGBA') arr = np.array(img) if __name__=='__main__': green_hue = (180-78)/360.0 red_hue = (180-180)/360.0 new_img = Image.fromarray(shift_hue(arr,red_hue), 'RGBA') new_img.save('tweeter_red.png') new_img = Image.fromarray(shift_hue(arr,green_hue), 'RGBA') new_img.save('tweeter_green.png') 

    доходность

    введите описание изображения здесь

    а также

    введите описание изображения здесь

    С недавней копией Подушки, вероятно, следует использовать

     def rgb2hsv(image): return image.convert('HSV') 

    Хороший вопрос. PIL не конвертируется в цветовое пространство HSV или HSL, но это преобразование, которое вам нужно сделать, чтобы изменить оттенок без каких-либо изменений в легкости и насыщенности изображения.

    Что вам нужно сделать, это преобразовать в HSV, а затем в некоторой степени увеличить все значения H, а затем преобразовать обратно в RGB.

    Половина работы сделана для вас в ответе (мной) некоторое время назад. Он использует другой модуль python под названием NumPy и преобразует цветовое пространство RGB в HSV. Было бы не слишком сложно написать обратное преобразование.

    Python - лучший язык программирования в мире.