Как преобразовать изображение RGB (3 канала) в оттенки серого (1 канал) и сохранить его? - PullRequest
0 голосов
/ 10 октября 2018

Работа с проектом глубокого обучения, и у меня есть много изображений, которые не должны иметь цвета.Я сохранил их, выполнив:

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 единственный канал.

Я попробовал методы, описанные в теме " Как преобразовать изображение RGB в градации серого в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) формой, учитывая, насколько менее сложными в вычислительном отношении это будет для сверточной нейронной сети.

Буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Как оказалось, Keras, библиотека глубокого обучения, которую я использую, имеет свой собственный метод преобразования изображений в один цветной канал (в оттенках серого) на этапе предварительной обработки изображения.

При использованиикласс ImageDataGenerator метод flow_from_directory принимает аргумент color_mode.Настройка color_mode = "grayscale" автоматически преобразует PNG в один цветной канал!

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

Надеюсь, это поможет кому-то в будущем.

0 голосов
/ 10 октября 2018

Ваш первый блок кода:

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

Это сохраняет изображение как RGB, потому что cmap='gray' игнорируется при подаче данных RGB в imsave (см. документы pyplot ).

Вы можете преобразовать данные в оттенки серого, взяв среднее значение по трем полосам, либо используя 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)

Один из способов избежать этого - сохранить изображения в виде файлов илидействительно, чтобы сохранить пакет изображений в виде пустых файлов:

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)
...