2017-02-04 6 views
4

У меня есть программа, которая должна изменить контрастность, но я чувствую, что она не меняет контраст. Она меняет некоторые области на красный, тогда как я не хочу этого. Если бы вы могли сказать мне, как их удалить, спасибо. Вот код:Изменение контраста изображения в PIL

from PIL import Image 


def change_contrast(img, level): 

    img = Image.open("C:\\Users\\omar\\Desktop\\Site\\Images\\obama.png") 
    img.load() 

    factor = (259 * (level+255))/(255 * (259-level)) 
    for x in range(img.size[0]): 
     for y in range(img.size[1]): 
      color = img.getpixel((x, y)) 
      new_color = tuple(int(factor * (c-128) + 128) for c in color) 
      img.putpixel((x, y), new_color) 

    return img 

result = change_contrast('C:\\Users\\omar\\Desktop\\Site\\Images\\test_image1.jpg', 100) 
result.save('C:\\Users\\omar\\Desktop\\Site\\Images\\test_image1_output.jpg') 
print('done') 

А вот образ и его результат:

obama.png obama modified

Если это фактический метод контраста, не стесняйтесь сказать мне

+0

Я не могу воспроизвести это. Я пробовал ваш код, и выходное изображение выглядит нормально. https://i.stack.imgur.com/QhR3n.jpg –

+0

Ваш код содержит две разные попытки загрузки входного изображения. Вы 'test_image1.jpg' не будут использоваться, поскольку у вас есть' obama.png', жестко закодированный в теле функции. Вы уверены, что используете входной файл, который, как вы думаете, используете? –

ответ

8

Я не смог воспроизвести вашу ошибку. На моей платформе (debian) доступна только вилка Pillow, поэтому, если вы используете старый пакет PIL, это может быть причиной.

В любом случае есть встроенный метод Image.point() для выполнения такого рода операций. Он будет отображать каждый пиксель в каждом канале, который должен быть быстрее, чем три вложенных цикла в python.

def change_contrast(img, level): 
    factor = (259 * (level + 255))/(255 * (259 - level)) 
    def contrast(c): 
     return 128 + factor * (c - 128) 
    return img.point(contrast) 

change_contrast(Image.open('barry.png'), 100) 

output

Ваш вывод выглядит как у вас есть переполнение в одном канале (красный). Я не вижу причин, почему это произойдет. Но если ваш level выше 259, выход инвертируется. Что-то вроде этого, вероятно, является причиной первоначальной ошибки.

def change_contrast_multi(img, steps): 
    width, height = img.size 
    canvas = Image.new('RGB', (width * len(steps), height)) 
    for n, level in enumerate(steps): 
     img_filtered = change_contrast(img, level) 
     canvas.paste(img_filtered, (width * n, 0)) 
    return canvas 

change_contrast_multi(Image.open('barry.png'), [-100, 0, 100, 200, 300]) 

another output

Возможное исправление, чтобы убедиться, контрастный фильтр возвращает только значения в диапазоне [0-255], так как ошибка, кажется, быть вызвана отрицательными значениями перелива каким-то образом.

def change_contrast(img, level): 
    factor = (259 * (level + 255))/(255 * (259 - level)) 
    def contrast(c): 
     value = 128 + factor * (c - 128) 
     return max(0, min(255, value)) 
    return img.point(contrast) 
+0

Хорошо, это именно то, что я искал, я хотел сделать модификатор контраста масштаба. Я собираюсь попробовать и посмотреть, работает ли это.если это произойдет, я приму это в качестве ответа. –

+0

Почему эта же функция не работает, когда я создаю ее в простой Numpy и использую ее на изображении, представленном как массив Numpy? – Alex

+0

Это объясняется в моем ответе. point - это метод класса Image. –

4

В модуле PIL уже создан класс под названием contrast. Вы можете просто использовать его.

from PIL import Image, ImageEnhance 
image = Image.open(':\\Users\\omar\\Desktop\\Site\\Images\\obama.png') 
scale_value=scale1.get() 
contrast = ImageEnhance.Contrast(image) 
contrast_applied=contrast.enhance(scale_value) 
image.show() 
+0

Да, но я не могу выровнять уровень контраста. Я хочу иметь масштаб, который определяет уровень контрастности, применяемый к фотографии, и эта команда не может быть скорректирована, или я не знаю, как это сделать. Если вам нужна другая программа, над которой я работаю, это говорит о том, что я говорю о том, чтобы сказать мне, что я поставлю ее на этот пост. –

+0

Вы хотите повысить уровень контраста? o – orvi

+0

Да в зависимости от уровня, который пользователь выбирает, фотография более контрастирует с исходным. Должен ли я публиковать другую программу? –