簡體   English   中英

使用python PIL將RGB圖像變成純黑白圖像

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

我正在使用 Python Imaging Library 進行一些非常簡單的圖像處理,但是我在將灰度圖像轉換為單色(黑白)圖像時遇到了問題。 如果我在將圖像更改為灰度 (convert('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 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')

產量

在此處輸入圖片說明

用於創建具有自定義閾值的雙層(黑白)圖像的 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')

你會得到一個抖動的圖像。

從左到右輸入圖像,黑白轉換結果和抖動結果:

輸入圖像 黑白結果 抖動結果

您可以單擊圖像查看未縮放的版本。

另一種選擇(當您需要使用分割掩碼時,這對於科學目的很有用)是簡單地應用閾值:

#!/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看起來像這樣:

在此處輸入圖片說明

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

根據unutbu獲得的結果判斷,我得出結論,scipy的imsave不理解單色(模式1)圖像。

一種使用 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

我就是這樣做的,它有更好的結果,比如灰色過濾器

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

因為從PIL convert("1")返回值“True”或“False”。 嘗試打印它,將顯示: [False, False, True]單支架。

numpy數組使用雙括號,如[[False, False, True]][[0, 0, 1]] ,對嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM