В OpenCV (Python), почему я получаю 3-канальные изображения из изображения в оттенках серого?
Я использую Python (2.7) и привязки для OpenCV 2.4.6 на Ubuntu 12.04
Загружаю изображение
image = cv2.imread('image.jpg')
Затем я проверяю форму массива изображений
print image.shape
Я получаю (480, 640, 3), что я ожидаю для цветного изображения 640x480. Затем я преобразую изображение в оттенки серого и снова проверю фигуру.
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print gray_image.shape
Я получаю (480, 640, 1), что я ожидаю от изображения с разрешением 640x480 в оттенках серого. Затем я сохраняю изображение:
cv2.imwrite('gray.jpg', gray_image)
Я на linux, поэтому я попытался посмотреть изображение с помощью gThumb, в котором отображаются все цветовые каналы. Когда я возвращаю серое изображение в OpenCV, изображение снова имеет три канала.
Я знаю этот флаг для чтения изображений:
CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one
Но это звучит так, как будто это приведет к изображению как цветному изображению, а затем преобразует его. Я переношу этот проект на RaspberryPi, поэтому я не хочу, чтобы произошли ненужные действия.
EDIT: Я проверил некоторые проверки времени, и я обнаружил, что загрузка изображения с использованием флага CV_LOAD_IMAGE_GRAYSCALE приводит к загрузке изображения в два раза быстрее, независимо от ввода изображения.
Using a 3072 x 4608 x 3 image
0.196774959564 seconds with default loading
0.0931899547577 seconds with CV_LOAD_IMAGE_GRAYSCALE
Проблема заключается в том, что OpenCV создает 3-канальный JPG-вывод, есть ли у меня матрица изображений в оттенках серого или нет!
Какое другое приложение можно использовать, чтобы удостовериться, что я получаю одно изображение в формате 8 бит канала JPG?
(Возможно, gThumb неправильно сообщает каналы).
Если изображение не является единственным каналом, то почему OpenCV сохраняет изображение в градациях серого на 3-канальное изображение на диске?
Спасибо заранее.
Ответы
Ответ 1
Ваш код верен, кажется, что cv2.imread
загружает изображение с тремя каналами, если не установлен CV_LOAD_IMAGE_GRAYSCALE
.
>>> import cv2
>>> image = cv2.imread('foo.jpg')
>>> print image.shape
(184, 300, 3)
>>> gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
>>> print gray_image.shape
(184, 300)
>>> cv2.imwrite('gray.jpg', gray_image)
Теперь, если вы загрузите изображение:
>>> image = cv2.imread('gray.jpg')
>>> print image.shape
(184, 300, 3)
Кажется, что вы сохранили изображение как BGR, однако это не так, это просто opencv, по умолчанию он считывает изображение с 3-мя каналами, а в случае, когда он в оттенках серого, он копирует свой слой три раза. Если вы снова загрузите изображение с помощью scipy, вы увидите, что изображение действительно имеет оттенки серого:
>>> from scipy.ndimage import imread
>>> image2 = imread('gray.jpg')
>>> print image2.shape
(184, 300)
Итак, если вы хотите загрузить изображение в оттенках серого, вам нужно установить флаг CV_LOAD_IMAGE_GRAYSCALE
:
>>> image = cv2.imread('gray.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
>>> print image.shape
(184, 300)
Ответ 2
попробуйте следующее:
img = cv2.imread('gray.jpg',0)
0 для серого и 1 для цвета
Ответ 3
В показаниях openCV jpg изображения по умолчанию отображаются 3-канальные изображения. Поэтому я не уверен, действительно ли вы можете увидеть из jpg файла, что он уже серого цвета, но вы всегда можете загрузить его как оттенок серого. Это принесло бы проблемы только в том случае, если изображение не было выделено в серый цвет заранее, и для вашего случая я считаю, что это не сработает. Короткий ответ: вы не можете сохранить jpg как одноканальное изображение. Таким образом, вам понадобится полутоновое изображение снова после прочтения или определения нового способа, если изображение будет выделено в серый цвет или нет.
Ответ 4
На самом деле,
image = cv2.imread('iumage.jpg',0)
загружает изображение в градациях серого. Поэтому вы должны использовать параметр 0, чтобы указать, что загружаемое изображение является изображением в градациях серого.