web-dev-qa-db-fra.com

Conversion d'image OpenCV de RVB à niveaux de gris en utilisant imread donnant des résultats médiocres

Je charge une image RVB 24 bits à partir d'un fichier PNG dans mon application OpenCV.

Cependant, le chargement de l'image en niveaux de gris directement à l'aide de imread donne un résultat très médiocre.

Mat src1 = imread(inputImageFilename1.c_str(), 0);

Charger l'image RVB en tant que RVB et la convertir en niveaux de gris donne un résultat bien meilleur.

Mat src1 = imread(inputImageFilename1.c_str(), 1);
cvtColor(src1, src1Gray, CV_RGB2GRAY);

Je me demande si j'utilise correctement imread pour mon type d'image. Quelqu'un a-t-il connu un comportement similaire?

L'image convertie en niveaux de gris à l'aide de imread est affichée ici: Bad result

L'image convertie en niveaux de gris à l'aide de cvtColor est affichée ici: Good result

16
tisch

J'avais le même problème aujourd'hui. Au final, j'ai comparé trois méthodes:

//method 1
cv::Mat gs = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE);

//method 2
cv::Mat color = cv::imread(filename, 1); //loads color if it is available
cv::Mat gs_rgb(color.size(), CV_8UC1);
cv::cvtColor(color, gs_rgb, CV_RGB2GRAY);

//method 3
cv::Mat gs_bgr(color.size(), CV_8UC1);
cv::cvtColor(color, gs_bgr, CV_BGR2GRAY);

Les méthodes 1 (chargement des niveaux de gris) et 3 (CV_BGR2GRAY) produisent des résultats identiques, tandis que la méthode 2 produit un résultat différent. Pour mes propres fins, j'ai commencé à utiliser CV_BGR2GRAY.

Mes fichiers d'entrée sont des jpgs, il peut donc y avoir des problèmes liés à votre format d'image particulier.

19
StaringFrog

La réponse simple est que les fonctions openCV utilisent le format BGR. Si vous lisez dans une image avec imread ou VideoCapture, ce sera toujours BGR. Si vous utilisez RGB2GRAY, vous échangez le canal bleu avec le vert. La formule pour obtenir la luminosité est

y = 0.587*green + 0.299*red + 0.114*blue

donc si vous changez le vert et le bleu, cela provoquera une énorme erreur de calcul.

Salue

10
Christian

J'ai eu un problème similaire une fois, en travaillant avec des shaders OpenGL. Il semble que le premier conteneur avec lequel OpenCV lit votre image ne prend pas en charge toutes les gammes de couleurs et vous voyez donc que l'image est une mauvaise transformation en niveaux de gris. Cependant, une fois que vous avez converti l'image d'origine en niveaux de gris à l'aide de cvtColor, le conteneur est différent du premier et prend en charge toutes les plages. À mon avis, le premier utilise moins de 8 bits pour les niveaux de gris ou le passage à l'échelle de gris utilise une mauvaise méthode. Mais le second donne une image fluide en raison de plus de bits dans le canal gris.

1
Amir Zadeh