J'ai un programme qui est censé changer le contraste, mais j'ai l'impression qu'il ne change pas vraiment le contraste, il change certaines zones en rouge alors que je ne le veux pas. Si vous pouviez me dire comment les supprimer, merci. Voici le code:
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')
Et voici l'image et son résultat:
S'il s'agit de la méthode de contraste réelle, n'hésitez pas à me le dire
Je n'ai pas pu reproduire votre bug. Sur ma plate-forme (debian), seul le fork Pillow est disponible, donc si vous utilisez l'ancien package PIL, cela pourrait être la cause.
Dans tous les cas, il existe une méthode intégrée Image.point()
pour effectuer ce type d'opération. Il cartographiera chaque pixel de chaque canal, ce qui devrait être plus rapide que de faire trois boucles imbriquées en 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)
Votre sortie semble avoir un débordement dans un seul canal (rouge). Je ne vois aucune raison pour laquelle cela se produirait. Mais si votre level
est supérieur à 259, la sortie est inversée. Quelque chose comme ça est probablement la cause du bogue initial.
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])
Une solution possible consiste à s'assurer que le filtre de contraste ne renvoie que des valeurs dans la plage [0-255], car le bogue semble provenir de débordements de valeurs négatives.
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)
Il y a déjà construit une classe appelée contraste dans le module PIL. Vous pouvez simplement l'utiliser.
from PIL import Image, ImageEnhance
image = Image.open(':\\Users\\omar\\Desktop\\Site\\Images\\obama.png')
scale_value=scale1.get()
image = ImageEnhance.Contrast(image).enhance(scale_value)
image.show()