首页 文章

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

提问于
浏览
40

我正在使用Python Imaging 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

6 回答

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

    产量

    enter image description here

  • 7

    另一个选项(当您需要使用分段掩码时,例如用于科学目的非常有用)只是应用一个阈值:

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

    ./binarize.py -i convert_image.png -o result_bin.png --threshold 200 看起来像这样:

    enter image description here

  • 60

    正如Martin Thoma所说,你需要正常应用阈值 . 但是你可以使用简单的矢量化来实现这一点,它的运行速度比该答案中使用的for循环要快得多 .

    下面的代码将图像的像素转换为0(黑色)和1(白色) .

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

    unutbu获得的结果判断,我得出结论,scipy的 imsave 不理解单色(模式1)图像 .

  • 19

    仅限PIL解决方案,用于创建具有自定义阈值的双层(黑白)图像:

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

    只是

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

    你得到一个抖动的图像 .

  • -2

    因为从PIL convert("1") 返回值"True"或"False" . 尝试打印它,将显示: [False, False, True] 单支架 .

    而numpy数组使用双括号,如 [[False, False, True]][[0, 0, 1]] ,对吗?

相关问题