web-dev-qa-db-fra.com

Opencv - Mode niveaux de gris contre conversion de couleur grise

Je travaille en opencv (2.4.11) python (2.7) et jouais avec des images grises. J'ai trouvé un comportement inhabituel lors du chargement de l'image en mode échelle de gris et de la conversion de l'image de BGR en GRIS. Voici mon code expérimental:

import cv2

path = 'some/path/to/color/image.jpg'

# Load color image (BGR) and convert to gray
img = cv2.imread(path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Load in grayscale mode
img_gray_mode = cv2.imread(path, 0)

# diff = img_gray_mode - img_gray
diff = cv2.bitwise_xor(img_gray,img_gray_mode)

cv2.imshow('diff', diff)
cv2.waitKey()

Lorsque j'ai vu l'image de différence, je peux voir les pixels laissés de côté au lieu de l'image noir de jais. Pouvez-vous suggérer une raison? Quelle est la bonne façon de travailler avec des images grises.

P.S. Lorsque j'utilise les deux images dans SIFT, les points clés sont différents, ce qui peut conduire à des résultats différents spécialement lorsque vous travaillez avec des images de mauvaise qualité.

35
Gagandeep Singh

Remarque: Ce n'est pas un doublon , car l'OP sait que l'image de cv2.imread Est au format BGR (contrairement au doublon suggéré question qui supposait qu'il s'agissait de RVB, donc les réponses fournies ne répondent qu'à ce problème)

Pour illustrer, j'ai ouvert cette même image JPEG couleur:

enter image description here

une fois en utilisant la conversion

img = cv2.imread(path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

et un autre en le chargeant en mode échelle de gris

img_gray_mode = cv2.imread(path, cv2.IMREAD_GRAYSCALE)

Comme vous l'avez documenté, le diff entre les deux images n'est pas parfaitement nul, je peux voir des pixels diff vers la gauche et le bas

enter image description here

J'ai aussi résumé le diff pour voir

import numpy as np
np.sum(diff)
# I got 6143, on a 494 x 750 image

J'ai essayé tous les modes cv2.imread()

Parmi tous les modes IMREAD_ Pour cv2.imread(), seuls IMREAD_COLOR Et IMREAD_ANYCOLOR Peuvent être convertis en utilisant COLOR_BGR2GRAY, Et les deux m'ont donné le même diff par rapport à l'image ouverte dans IMREAD_GRAYSCALE

La différence ne semble pas si grande. Je suppose que cela vient des différences dans les calculs numériques dans les deux méthodes (chargement des niveaux de gris vs conversion en niveaux de gris)

Naturellement, ce que vous voulez éviter, c'est peaufiner votre code sur une version particulière de l'image juste pour découvrir qu'elle était sous-optimale pour les images provenant d'une source différente.

En bref, ne mélangeons pas les versions et les types dans le pipeline de traitement.

Je garderais donc les sources d'images homogènes, par ex. si vous avez capturé l'image d'une caméra vidéo dans BGR, alors j'utiliserais BGR comme source, et ferais la conversion BGR en niveaux de gris cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Inversement, si ma source ultime est en niveaux de gris, j'ouvrirais les fichiers et la capture vidéo en niveaux de gris cv2.imread(path, cv2.IMREAD_GRAYSCALE)

37
bakkal