[英]How to convert a RGB image (3 channel) to grayscale (1 channel) and save it?
Working with a deep learning project and I have a lot of images, that don't need to have colors.使用深度学习项目,我有很多图像,不需要颜色。 I saved them doing:我救了他们做:
import matplotlib.pyplot as plt
plt.imsave('image.png', image, format='png', cmap='gray')
However later when I checked the shape of the image the result is:但是后来当我检查图像的形状时,结果是:
import cv2
img_rgb = cv2.imread('image.png')
print(img_rgb.shape)
(196,256,3)
So even though the image I view is in grayscale, I still have 3 color channels.所以即使我查看的图像是灰度的,我仍然有 3 个颜色通道。 I realized I had to do some algebric operations in order to convert those 3 channels into 1 single channel.我意识到我必须做一些代数运算才能将这 3 个通道转换为 1 个单通道。
I have tried the methods described on the thread " How can I convert an RGB image into grayscale in Python? " but I'm confused.我已经尝试了线程“ 如何在 Python 中将 RGB 图像转换为灰度? ”中描述的方法,但我很困惑。
For example, when to do the conversion using:例如,何时使用以下方法进行转换:
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')
However when I load the new image and check its shape:但是,当我加载新图像并检查其形状时:
img_gr = cv2.imread('image_gray.png')
print(img_gr.shape)
(196,256,3)
I tried the other methods on that thread but the results are the same.我在该线程上尝试了其他方法,但结果相同。 My goal is to have images with a (196,256,1) shape, given how much less computationally intensive it will be for a Convolutional Neural Network.我的目标是获得具有 (196,256,1) 形状的图像,考虑到卷积神经网络的计算强度会降低多少。
Any help would be appreciated.任何帮助,将不胜感激。
Your first code block:你的第一个代码块:
import matplotlib.pyplot as plt
plt.imsave('image.png', image, format='png', cmap='gray')
This is saving the image as RGB, because cmap='gray'
is ignored when supplying RGB data to imsave (see pyplot docs ).这是将图像保存为 RGB,因为在向 imsave 提供 RGB 数据时会忽略cmap='gray'
(请参阅pyplot 文档)。
You can convert your data into grayscale by taking the average of the three bands, either using color.rgb2gray
as you have, or I tend to use numpy:您可以通过取三个波段的平均值将数据转换为灰度,或者使用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)
Output:输出:
RGB image shape: (196, 256, 3)
Grayscale image shape: (196, 256)
img_gray
is now the correct shape, however if you save it using plt.imsave
, it will still write three bands, with R == G == B for each pixel. img_gray
现在是正确的形状,但是如果您使用plt.imsave
保存它,它仍然会写入三个波段,每个像素的 R == G == B。 This is because, I believe, a PNG file requires three (or four) bands.这是因为,我相信,一个 PNG 文件需要三个(或四个)波段。 Warning: I am not sure about this: I expect to be corrected.警告:我不确定这一点:我希望得到纠正。
plt.imsave('image_gray.png', img_gray, format='png')
new_img = cv2.imread('image_gray.png')
print('Loaded image shape:', new_img.shape)
Output:输出:
Loaded image shape: (196, 256, 3)
One way to avoid this is to save the images as numpy files, or indeed to save a batch of images as numpy files:避免这种情况的一种方法是将图像保存为 numpy 文件,或者确实将一批图像保存为 numpy 文件:
np.save('np_image.npy', img_gray)
new_np = np.load('np_image.npy')
print('new_np shape:', new_np.shape)
Output:输出:
new_np shape: (196, 256)
The other thing you could do is save the grayscale png (using imsave
) but then only read in the first band:您可以做的另一件事是保存灰度 png(使用imsave
),然后只在第一个波段中读取:
finalimg = cv2.imread('image_gray.png',0)
print('finalimg image shape:', finalimg.shape)
Output:输出:
finalimg image shape: (196, 256)
As it turns out, Keras, the deep-learning library I'm using has its own method of converting images to a single color channel (grayscale) in its image pre-processing step.事实证明,我使用的深度学习库 Keras 有自己的方法,可以在其图像预处理步骤中将图像转换为单一颜色通道(灰度)。
When using the ImageDataGenerator
class the flow_from_directory
method takes the color_mode
argument.使用ImageDataGenerator
类时, flow_from_directory
方法采用color_mode
参数。 Setting color_mode = "grayscale"
will automatically convert the PNG into a single color channel!设置color_mode = "grayscale"
将自动将 PNG 转换为单个颜色通道!
https://keras.io/preprocessing/image/#imagedatagenerator-methods https://keras.io/preprocessing/image/#imagedatagenerator-methods
Hope this helps someone in the future.希望这对未来的人有所帮助。
if you want to just add extra channels that have the same value as the graysacale , maybe to use a specific model that requires 3 channel input_shape .如果您只想添加与 graysacale 具有相同值的额外通道,则可能使用需要 3 通道 input_shape 的特定模型。
lets say your pictures are 28 X 28 and so you have a shape of (28 , 28 , 1) def add_extra_channels_to_pic(pic):假设您的图片是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
Try this method试试这个方法
import imageio
new_data = imageio.imread("file_path", as_gray =True)
imageio.imsave("file_path", new_data)
The optional argument "as_gray = True" in line 2 of the code does the actual conversion.代码第 2 行中的可选参数“as_gray = True”进行实际转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.