Изменение контрастности изображения в PIL
У меня есть программа, которая должна изменить контраст, но я чувствую, что она на самом деле не меняет контраст.Он меняет некоторые области на красные, тогда как я этого не хочу. Если бы вы могли сказать мне, как их удалить, спасибо. Вот код:
from PIL import Image
def change_contrast(img, level):
img = Image.open("C:UsersomarDesktopSiteImagesobama.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:UsersomarDesktopSiteImagestest_image1.jpg', 100)
result.save('C:UsersomarDesktopSiteImagestest_image1_output.jpg')
print('done')
и вот изображение и его результат:
Если это фактический метод контраста, не стесняйтесь говорить мне
2 ответов
Я не смог воспроизвести вашу ошибку. На моей платформе (debian) доступна только вилка подушки, поэтому, если вы используете более старый пакет 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)
ваш выход выглядит так, как будто у вас есть переполнение в одноканальный (красный). Я не вижу причин, по которым это могло бы произойти. Но если ваш 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])
возможное исправление - убедиться, что фильтр контрастности возвращает только значения в диапазоне [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)
уже построен класс под названием контраст в модуле PIL. Вы можете просто использовать его.
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()