Utiliser python PIL pour transformer une image RGB en une image en noir et blanc pur
j'utilise la bibliothèque D'imagerie Python pour une manipulation d'image très simple, mais j'ai de la difficulté à convertir une image à l'échelle de gris en une image monochrome (en noir et blanc). Si je sauve après avoir changé l'image en greyscale (convert ('L')), alors l'image rend ce que vous attendez. Cependant, si je convertis l'image en une image monochrome à bande simple, cela me donne juste du bruit comme vous pouvez le voir dans les images ci-dessous. Existe-t-il un moyen simple de transformer une image png en une image en noir et blanc pur? utiliser PIL / python?
from PIL import Image
import ImageEnhance
import ImageFilter
from scipy.misc import imsave
image_file = Image.open("convert_image.png") # open colour image
image_file= image_file.convert('L') # convert image to monochrome - this works
image_file= image_file.convert('1') # convert image to black and white
imsave('result_col.png', image_file)
6 réponses
from PIL import Image
image_file = Image.open("convert_image.png") # open colour image
image_file = image_file.convert('1') # convert image to black and white
image_file.save('result.png')
les rendements
une autre option (qui est utile par exemple à des fins scientifiques lorsque vous devez travailler avec des masques de segmentation) est simplement d'appliquer un seuil:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Binarize (make it black and white) an image with Python."""
from PIL import Image
from scipy.misc import imsave
import numpy
def binarize_image(img_path, target_path, threshold):
"""Binarize an image."""
image_file = Image.open(img_path)
image = image_file.convert('L') # convert image to monochrome
image = numpy.array(image)
image = binarize_array(image, threshold)
imsave(target_path, image)
def binarize_array(numpy_array, threshold=200):
"""Binarize a numpy array."""
for i in range(len(numpy_array)):
for j in range(len(numpy_array[0])):
if numpy_array[i][j] > threshold:
numpy_array[i][j] = 255
else:
numpy_array[i][j] = 0
return numpy_array
def get_parser():
"""Get parser object for script xy.py."""
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
parser = ArgumentParser(description=__doc__,
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument("-i", "--input",
dest="input",
help="read this file",
metavar="FILE",
required=True)
parser.add_argument("-o", "--output",
dest="output",
help="write binarized file hre",
metavar="FILE",
required=True)
parser.add_argument("--threshold",
dest="threshold",
default=200,
type=int,
help="Threshold when to show white")
return parser
if __name__ == "__main__":
args = get_parser().parse_args()
binarize_image(args.input, args.output, args.threshold)
ça ressemble à Ça pour ./binarize.py -i convert_image.png -o result_bin.png --threshold 200
:
comme Martin Thoma l'a dit, vous devez normalement appliquer le seuil. Mais vous pouvez le faire en utilisant la vectorisation simple qui fonctionnera beaucoup plus vite que la boucle for qui est utilisée dans cette réponse.
Le code ci-dessous convertit les pixels d'une image en 0 (noir) et 1 (blanc).
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
#Pixels higher than this will be 1. Otherwise 0.
THRESHOLD_VALUE = 200
#Load image and convert to greyscale
img = Image.open("photo.png")
img = img.convert("L")
imgData = np.asarray(img)
thresholdedData = (imgData > THRESHOLD_VALUE) * 1.0
plt.imshow(thresholdedData)
plt.show()
en Juger par les résultats obtenus par unutbu je conclus que scipy est imsave
ne comprend pas les images monochromes (mode 1).
une solution PIL only pour créer une image bi-niveau (en noir et blanc) avec un seuil personnalisé:
from PIL import Image
img = Image.open('mB96s.png')
thresh = 200
fn = lambda x : 255 if x > thresh else 0
r = img.convert('L').point(fn, mode='1')
r.save('foo.png')
Avec
r = img.convert('1')
r.save('foo.png')
vous obtenez une image tramée.
parce que de PIL convert("1")
retourner la valeur "True" ou "False". Essayez d'imprimer, sera afficher: [False, False, True]
avec un seul support.
alors que le tableau nummpy utilise un double bracket comme ceci [[False, False, True]]
ou [[0, 0, 1]]
, droit?