2013-09-18 2 views
19

Я использую Python (2.7) и привязок для OpenCV 2.4.6 на Ubuntu 12.04В OpenCV (Python), почему я получаю 3-канальные изображения из изображения в оттенках серого?

Я загрузить изображение

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), что я рассчитывать на 640х480 оттенки серого изображения. Затем я сохранить изображение:

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-канальное изображение на диске?

Заранее спасибо.

ответ

21

Ваш код верен, кажется, что 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) 
+0

Спасибо, похоже, что gThumb также дублирует слои. Я не могу отметить ваш ответ, потому что у меня недостаточно очков повторения. – Steve

+1

Сказав все, каково решение сохранять изображения в одном канальном формате? (предполагается, что нам нужно сохранить изображение в одном канале) – Saman

+10

выглядит как cv2.IMREAD_GRAYSCALE - это путь в эти дни вместо cv2.CV_LOAD_IMAGE_GRAYSCALE –

1

В изображениях с открытыми чтением jpg изображения отображаются по 3 канальным изображениям по умолчанию. Поэтому я не уверен, действительно ли вы можете увидеть из файла jpg, что он уже серого цвета, но вы всегда можете загрузить его как серого. Это принесло бы проблемы только в том случае, если изображение не было выделено в серый цвет заранее, и для вашего случая я считаю, что это не сработает. Короткий ответ: вы не можете сохранить jpg как одноканальное изображение. Таким образом, вам нужно будет полутоновое изображение снова после прочтения или определения нового способа определить, является ли изображение серого или нет.

3

попробовать это:

img = cv2.imread('gray.jpg',0) 

для серого и для цвета

+0

Я предпочитаю этот более простой вариант – crazjo