简体   繁体   English

使用python PIL将RGB图像变成纯黑白图像

[英]Using python PIL to turn a RGB image into a pure black and white image

I'm using the Python Imaging Library for some very simple image manipulation, however I'm having trouble converting a greyscale image to a monochrome (black and white) image.我正在使用 Python Imaging Library 进行一些非常简单的图像处理,但是我在将灰度图像转换为单色(黑白)图像时遇到了问题。 If I save after changing the image to greyscale (convert('L')) then the image renders as you would expect.如果我在将图像更改为灰度 (convert('L')) 后保存,则图像会按照您的预期呈现。 However, if I convert the image to a monochrome, single-band image it just gives me noise as you can see in the images below.但是,如果我将图像转换为单色单波段图像,它只会给我带来噪音,如下图所示。 Is there a simple way to take a colour png image to a pure black and white image using PIL / python?有没有一种简单的方法可以使用 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 ImageConverted Image

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产量

在此处输入图片说明

A PIL only solution for creating a bi-level (black and white) image with a custom threshold:用于创建具有自定义阈值的双层(黑白)图像的 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')

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:从左到右输入图像,黑白转换结果和抖动结果:

输入图像 黑白结果 抖动结果

You can click on the images to view the unscaled versions.您可以单击图像查看未缩放的版本。

Another option (which is useful eg 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 : ./binarize.py -i convert_image.png -o result_bin.png --threshold 200看起来像这样:

在此处输入图片说明

As Martin Thoma has said, you need to normally apply thresholding.正如 Martin Thoma 所说,您通常需要应用阈值。 But you can do this using simple vectorization which will run much faster than the for loop that is used in that answer.但是您可以使用简单的矢量化来做到这一点,它的运行速度比该答案中使用的 for 循环快得多。

The code below converts the pixels of an image into 0 (black) and 1 (white).下面的代码将图像的像素转换为 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()

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

A simple way to do it using python :一种使用 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()

Because from PIL convert("1") return the value "True" or "False". 因为从PIL convert("1")返回值“True”或“False”。 Try to print it, will be show: [False, False, True] with single bracket. 尝试打印它,将显示: [False, False, True]单支架。

Whereas the numpy array use double bracket like this [[False, False, True]] or [[0, 0, 1]] , right? numpy数组使用双括号,如[[False, False, True]][[0, 0, 1]] ,对吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM