使用 PIL 将 RGB 图像转换为纯黑白图像

我正在使用 Python Image Library 进行一些非常简单的图像操作,但是我在将灰度图像转换为单色(黑白)图像时遇到了麻烦。如果我保存后,改变图像灰度(转换(’L’)) ,然后图像呈现为您所期望的。然而,如果我把图像转换成单色,单波段的图像,它只是给我噪音,因为你可以看到在下面的图像。有没有一种简单的方法可以使用 PIL/python 将彩色 png 图像转换为纯黑白图像?

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)

Original Image Converted Image

230040 次浏览
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')

yields

enter image description here

Another option (which is useful e.g. for scientific purposes when you need to work with segmentation masks) is simply apply a threshold:

#!/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)

It looks like this for ./binarize.py -i convert_image.png -o result_bin.png --threshold 200:

enter image description here

As Martin Thoma has said, you need to normally apply thresholding. But you can do this using simple vectorization which will run much faster than the for loop that is used in that answer.

The code below converts the pixels of an image into 0 (black) and 1 (white).

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()

A PIL only solution for creating a bi-level (black and white) image with a custom threshold:

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')

With just

r = img.convert('1')
r.save('foo.png')

you get a dithered image.

From left to right the input image, the black and white conversion result and the dithered result:

Input Image Black and White Result Dithered Result

You can click on the images to view the unscaled versions.

A simple way to do it using python :

Python
import numpy as np
import imageio


image = imageio.imread(r'[image-path]', as_gray=True)


# getting the threshold value
thresholdValue = np.mean(image)


# getting the dimensions of the image
xDim, yDim = image.shape


# turn the image into a black and white image
for i in range(xDim):
for j in range(yDim):
if (image[i][j] > thresholdValue):
image[i][j] = 255
else:
image[i][j] = 0


this is how i did it its havd better results like a gray filter

from PIL import Image
img = Image.open("profile.png")
BaW = img.convert("L")
BaW.save("profileBaW.png")
BaW.show()