我试图使用matplotlib读取RGB图像并将其转换为灰度。
在matlab中我使用这个:
img = rgb2gray(imread('image.png'));
在matplotlib教程中,没有涉及到它。他们只是阅读图像
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
然后他们将数组切片,但这与我所理解的将RGB转换为灰度不是一回事。
lum_img = img[:,:,0]
我发现很难相信numpy或matplotlib没有内置函数从rgb转换为灰色。这不是图像处理中常见的操作吗?
我写了一个非常简单的函数,使用imread在5分钟内导入图像。它的效率非常低,但这就是为什么我希望内置一个专业的实现。
塞巴斯蒂安改进了我的功能,但我仍然希望找到内置的功能。
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
用Pillow怎么做呢:
from PIL import Image
img = Image.open('image.png').convert('L')
img.save('greyscale.png')
如果在输入图像中存在alpha(透明)通道,并且应该保留,则使用模式LA:
img = Image.open('image.png').convert('LA')
使用matplotlib和公式
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()
The tutorial is cheating because it is starting with a greyscale image encoded in RGB, so they are just slicing a single color channel and treating it as greyscale. The basic steps you need to do are to transform from the RGB colorspace to a colorspace that encodes with something approximating the luma/chroma model, such as YUV/YIQ or HSL/HSV, then slice off the luma-like channel and use that as your greyscale image. matplotlib does not appear to provide a mechanism to convert to YUV/YIQ, but it does let you convert to HSV.
尝试使用matplotlib.colors.rgb_to_hsv(img),然后从数组中切片最后一个值(V)来获取灰度。它与亮度值不完全相同,但它意味着您可以在matplotlib中完成所有操作。
背景:
http://matplotlib.sourceforge.net/api/colors_api.html
http://en.wikipedia.org/wiki/HSL_and_HSV
或者,您可以使用PIL或内置的colorsys.rgb_to_yiq()来转换为具有真正亮度值的色彩空间。你也可以完全投入到你自己的光转换器中,尽管这可能有点过头了。
在Ubuntu 16.04 LTS (Xeon E5 2670 with SSD)上运行Python 3.5,测试了1000个RGBA PNG图像(224 x 256像素)的速度。
平均运行时间
pil: 1.037秒
1040秒
Sk: 2秒120
PIL和SciPy给出了相同的numpy数组(范围从0到255)。SkImage给出了从0到1的数组。此外,颜色转换略有不同,请参阅来自CUB-200数据集的示例。
SkImage:
PIL:
SciPy:
原:
差异:
Code
Performance
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)
for k, v in run_times.items():
print('{:5}: {:0.3f} seconds'.format(k, sum(v) / len(v)))
Output
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))
Comparison
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'))
Imports
import skimage.color
import skimage.io
import random
import time
from PIL import Image
import numpy as np
import scipy.ndimage
import IPython.display
Versions
skimage.version
0.13.0
scipy.version
0.19.1
np.version
1.13.1
使用img.Convert(),支持“L”,“RGB”和“CMYK”。”模式
import numpy as np
from PIL import Image
img = Image.open("IMG/center_2018_02_03_00_34_32_784.jpg")
img.convert('L')
print np.array(img)
输出:
[[135 123 134 ..., 30 3 14]
[137 130 137 ..., 9 20 13]
[170 177 183 ..., 14 10 250]
...,
[112 99 91 ..., 90 88 80]
[ 95 103 111 ..., 102 85 103]
[112 96 86 ..., 182 148 114]]