如何在Python中将RGB图像转换为灰度?

2024-05-08 19:14:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用matplotlib读取RGB图像并将其转换为灰度。

在matlab中,我使用这个:

img = rgb2gray(imread('image.png'));

matplotlib tutorial中,它们不覆盖它。他们只是在图像中读到

import matplotlib.image as mpimg
img = mpimg.imread('image.png')

然后他们对数组进行切片,但这与根据我的理解将RGB转换为灰度不同。

lum_img = img[:,:,0]

我发现很难相信numpy或matplotlib没有一个内置函数来从rgb转换为gray。这不是图像处理中常见的操作吗?

我编写了一个非常简单的函数,它可以在5分钟内处理使用imread导入的图像。它的效率非常低,但这就是为什么我希望内置一个专业的实现。

塞巴斯蒂安改进了我的功能,但我还是希望能找到内置的。

matlab(NTSC/PAL)实现:

import numpy as np

def rgb2gray(rgb):

    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray

Tags: 图像imageimportimgpngmatplotlibasrgb
3条回答

Pillow怎么样:

from PIL import Image
img = Image.open('image.png').convert('LA')
img.save('greyscale.png')

使用matplotlib和the formula

Y' = 0.2989 R + 0.5870 G + 0.1140 B 

你可以:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])

img = mpimg.imread('image.png')     
gray = rgb2gray(img)    
plt.imshow(gray, cmap=plt.get_cmap('gray'), vmin=0, vmax=1)
plt.show()

在Ubuntu 16.04lts(xeone52670ssd)上用Python 3.5运行1000个RGBA PNG图像(224x 256像素),测试了三种建议的方法的速度。

平均运行时间

pil :1.037秒

scipy:1.040秒

sk :2.120秒

PIL和SciPy给出了相同的numpy数组(范围从0到255)。skipage给出从0到1的数组。此外,颜色的转换略有不同,请参见CUB-200 dataset.中的示例

SkImage:SkImage

PIL :PIL

SciPy :SciPy

Original:Original

Diff :enter image description here

代码

  1. 性能

    run_times = dict(sk=list(), pil=list(), scipy=list())
    for t in range(100):
        start_time = time.time()
        for i in range(1000):
            z = random.choice(filenames_png)
            img = skimage.color.rgb2gray(skimage.io.imread(z))
        run_times['sk'].append(time.time() - start_time)
    
    
    start_time = time.time()
    for i in range(1000):
        z = random.choice(filenames_png)
        img = np.array(Image.open(z).convert('L'))
    run_times['pil'].append(time.time() - start_time)
    
    start_time = time.time()
    for i in range(1000):
        z = random.choice(filenames_png)
        img = scipy.ndimage.imread(z, mode='L')
    run_times['scipy'].append(time.time() - start_time)
    

    对于k,v在run_times.items()中: 打印('{:5}:{:0.3f}秒'。格式(k,sum(v)/len(v)))

  2. 输出
    z = 'Cardinal_0007_3025810472.jpg'
    img1 = skimage.color.rgb2gray(skimage.io.imread(z)) * 255
    IPython.display.display(PIL.Image.fromarray(img1).convert('RGB'))
    img2 = np.array(Image.open(z).convert('L'))
    IPython.display.display(PIL.Image.fromarray(img2))
    img3 = scipy.ndimage.imread(z, mode='L')
    IPython.display.display(PIL.Image.fromarray(img3))
    
  3. 比较
    img_diff = np.ndarray(shape=img1.shape, dtype='float32')
    img_diff.fill(128)
    img_diff += (img1 - img3)
    img_diff -= img_diff.min()
    img_diff *= (255/img_diff.max())
    IPython.display.display(PIL.Image.fromarray(img_diff).convert('RGB'))
    
  4. 进口
    import skimage.color
    import skimage.io
    import random
    import time
    from PIL import Image
    import numpy as np
    import scipy.ndimage
    import IPython.display
    
  5. 版本
    skimage.version
    0.13.0
    scipy.version
    0.19.1
    np.version
    1.13.1
    

您还可以使用scikit-image,它提供了一些函数来转换ndarray中的图像,例如rgb2gray

from skimage import color
from skimage import io

img = color.rgb2gray(io.imread('image.png'))

注意事项:此转换中使用的重量针对当代CRT荧光粉进行校准:Y=0.2125 R+0.7154 G+0.0721 B

或者,可以通过以下方式读取灰度图像:

from skimage import io
img = io.imread('image.png', as_gray=True)

相关问题 更多 >