web-dev-qa-db-fra.com

Dans OpenCV (Python), pourquoi est-ce que j'obtiens des images à 3 canaux à partir d'une image en niveaux de gris?

J'utilise Python (2.7) et les liaisons pour OpenCV 2.4.6 sur Ubuntu 12.04

Je charge une image

    image = cv2.imread('image.jpg')

Je vérifie ensuite la forme du tableau d'images

    print image.shape

J'obtiens (480, 640, 3), ce que j'attends pour une image couleur 640x480. Je convertis ensuite l'image en niveaux de gris et vérifie à nouveau la forme.

    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    print gray_image.shape

J'obtiens (480, 640, 1), ce que j'attends pour une image 640x480 niveaux de gris. Je sauvegarde ensuite l'image:

    cv2.imwrite('gray.jpg', gray_image)

Je suis sous Linux, j'ai donc essayé de regarder l'image avec gThumb, qui montre tous les canaux de couleur. Lorsque je ramène l'image grise dans OpenCV, l'image a à nouveau trois canaux. Je connais ce drapeau pour lire les images:

    CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one

Mais cela donne l'impression que l'image sera importée en tant qu'image couleur, puis convertie. Je porte ce projet sur RaspberryPi donc je ne veux pas que des opérations inutiles se produisent.

EDIT: J'ai effectué quelques vérifications de synchronisation et j'ai découvert que le chargement d'une image à l'aide de l'indicateur CV_LOAD_IMAGE_GRAYSCALE entraîne un chargement de l'image deux fois plus rapide, quelle que soit l'entrée d'image.

     Using a 3072 x 4608 x 3 image
     0.196774959564 seconds with default loading
     0.0931899547577 seconds with CV_LOAD_IMAGE_GRAYSCALE

Le problème semble être qu'OpenCV crée une sortie JPG à 3 canaux, que j'ai une matrice d'image en niveaux de gris ou non!

Quelle autre application puis-je utiliser pour m'assurer d'obtenir une seule image JPG de canal 8 bits ?? (Peut-être que gThumb rapporte les chaînes de manière incorrecte).

Si l'image n'est pas à canal unique, pourquoi OpenCV enregistre-t-elle mon image en niveaux de gris sur une image à 3 canaux lors de l'écriture sur le disque?

Merci d'avance.

32
Steve

Votre code est correct, il semble que cv2.imread charge une image avec trois canaux à moins que CV_LOAD_IMAGE_GRAYSCALE est défini.

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

Maintenant, si vous chargez l'image:

>>> image = cv2.imread('gray.jpg')
>>> print image.shape
 (184, 300, 3)

Il semble que vous ayez enregistré l'image au format BGR, mais ce n'est pas vrai, c'est juste ouvert, par défaut, il lit l'image avec 3 canaux, et dans le cas où il est en niveaux de gris, il copie son calque trois fois. Si vous chargez à nouveau l'image avec scipy, vous pouvez voir que l'image est en effet en niveaux de gris:

>>> from scipy.ndimage import imread
>>> image2 = imread('gray.jpg')
>>> print image2.shape
 (184, 300)

Donc, si vous souhaitez charger une image en niveaux de gris, vous devrez définir CV_LOAD_IMAGE_GRAYSCALE drapeau:

>>> image = cv2.imread('gray.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
>>> print image.shape
 (184, 300)
39
jabaldonedo

essaye ça:

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

pour le gris et 1 pour la couleur

13
Jino

En openCV, la lecture d'images jpg donne par défaut 3 images de canal. Je ne sais donc pas si vous pouvez réellement voir à partir du fichier jpg qu'il est déjà en niveaux de gris, mais vous pouvez toujours le charger en niveaux de gris. Cela ne poserait des problèmes que si l'image n'était pas en niveaux de gris au préalable et pour votre cas, je pense que cela ne fonctionnerait pas. Donc, réponse courte: vous ne pouvez pas enregistrer jpg en tant qu'image canalisée. Il vous faudra donc la redimensionner en niveaux de gris après avoir lu ou trouver une nouvelle façon de déterminer si l'image est en niveaux de gris ou non.

1
Henri Korhonen