如何将RGB图像(3通道)转换为灰度(1通道)并保存?

时间:2018-10-10 18:30:58

标签: python python-3.x image rgb grayscale

使用一个深度学习项目,我有很多图像,不需要颜色。我救了他们:

import matplotlib.pyplot as plt

plt.imsave('image.png', image, format='png', cmap='gray')

但是后来当我检查图像的形状时,结果是:

import cv2
img_rgb = cv2.imread('image.png')
print(img_rgb.shape)
(196,256,3)

因此,即使我查看的图像是灰度图像,我仍然具有3个颜色通道。我意识到我必须做一些代数运算才能将这3个通道转换为1个单通道。

我尝试了在线程“ How can I convert an RGB image into grayscale in Python?”中描述的方法,但感到困惑。

例如,何时使用以下方法进行转换:

from skimage import color
from skimage import io
img_gray = color.rgb2gray(io.imread('image.png'))
plt.imsave('image_gray.png', img_gray, format='png')

但是,当我加载新图像并检查其形状时:

img_gr = cv2.imread('image_gray.png')
print(img_gr.shape)
(196,256,3)

我在该线程上尝试了其他方法,但结果相同。考虑到卷积神经网络的计算强度将降低多少,我的目标是制作具有(196,256,1)形状的图像。

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:3)

您的第一个代码块:

import matplotlib.pyplot as plt
plt.imsave('image.png', image, format='png', cmap='gray')

这会将图像另存为RGB,因为在提供RGB数据进行保存时,cmap='gray'被忽略了。(见pyplot docs)。

您可以通过取三个波段的平均值来将数据转换为灰度,或者使用color.rgb2gray,或者我倾向于使用numpy:

import numpy as np
from matplotlib import pyplot as plt
import cv2

img_rgb = np.random.rand(196,256,3)
print('RGB image shape:', img_rgb.shape)

img_gray = np.mean(img_rgb, axis=2)
print('Grayscale image shape:', img_gray.shape)

输出:

RGB image shape: (196, 256, 3)
Grayscale image shape: (196, 256)

img_gray现在是正确的形状,但是如果使用plt.imsave保存,它仍将写入三个带,每个像素R == G ==B。我认为这是因为PNG文件需要三个(或四个)频段。警告:我对此不太确定:希望得到纠正。

plt.imsave('image_gray.png', img_gray, format='png')
new_img = cv2.imread('image_gray.png')
print('Loaded image shape:', new_img.shape)

输出:

Loaded image shape: (196, 256, 3)

避免这种情况的一种方法是将图像另存为numpy文件,或者确实将一批图像另存为numpy文件:

np.save('np_image.npy', img_gray)
new_np = np.load('np_image.npy')
print('new_np shape:', new_np.shape)

输出:

new_np shape: (196, 256)

您可以做的另一件事是保存灰度png(使用imsave),但是只能在第一个波段中读取:

finalimg = cv2.imread('image_gray.png',0)
print('finalimg image shape:', finalimg.shape)

输出:

finalimg image shape: (196, 256)

答案 1 :(得分:1)

事实证明,我正在使用的深度学习库Keras在其图像预处理步骤中有自己的将图像转换为单色通道(灰度)的方法。

在使用ImageDataGenerator类时,flow_from_directory方法采用color_mode参数。设置color_mode = "grayscale"将自动将PNG转换为单个颜色通道!

https://keras.io/preprocessing/image/#imagedatagenerator-methods

希望这对以后的人有帮助。

答案 2 :(得分:0)

如果您只想添加与graysacale具有相同值的额外通道,则可以使用需要3个通道input_shape的特定模型。

让我们说您的图片是 28 X 28 ,因此您的形状为(28,28,1)     def add_extra_channels_to_pic(pic):

if pic.shape == (28 , 28 , 1):
    pic = pic.reshape(28,28)
    pic =  np.array([pic , pic , pic])
    # to make the channel axis in the end
    pic = np.moveaxis(pic , 0 , -1) 
    return pic

答案 3 :(得分:0)

尝试此方法

import imageio
new_data = imageio.imread("file_path", as_gray =True)
imageio.imsave("file_path", new_data)

代码第2行中的可选参数“ as_gray = True”进行实际转换。