J'ai essayé d'afficher une image de type CV_32F en utilisant la fonction imshow mais elle a montré une image BLANCHE . Dans le Documentation son étant donné que les images en virgule flottante seront mappées à 0-255 et affichées, mais cela montrait juste une image blanche. J'ai essayé de la convertir en CV_8U en utilisant
Mat A = Mat :: ones (300,300, CV_32FC1) * 1000;
faire un peu de traitement - attribuer des valeurs flottantes aux pixels dans A
......
Mat B;
A.convertTo (B, CV_8U)
Lorsque je montre "B", j'obtiens une image en noir et blanc, il n'y a aucune nuance de gris . Les pixels flottants de A sont-ils correctement mappés sur 0-255? Suis-je en train de faire quelque chose de mal?
Peu de valeurs dans A sont 1000 comme initialisées et reste sont des nombres à virgule flottante qui sont attribués pendant le traitement.
Dans OpenCV, si l'image est de type virgule flottante, seuls ces pixels peuvent être visualisés à l'aide de imshow
, qui ont une valeur de 0,0 à 1,0, si la valeur est supérieure à 1,0, elle sera affichée en blanc pixel et si moins de 0,0, il sera affiché comme pixel noir. Pour visualiser une image à virgule flottante, mettez ses valeurs à l'échelle dans la plage 0.0 - 1.0
.
Quant à la partie de conversion .... Lorsqu'elle est utilisée avec des arguments par défaut, la fonction cv::Mat::convertTo
Crée simplement une matrice du type spécifié, puis copie les valeurs de la matrice source et les arrondit à la valeur la plus proche possible du type de données de destination. Si la valeur est hors plage, elle est fixée aux valeurs minimale ou maximale.
Dans la documentation de imshow
, il est écrit que:
Si l'image est en virgule flottante 32 bits, les valeurs des pixels sont multipliées par 255. En d'autres termes, la plage de valeurs [0,1] est mappée sur [0,255].
Cela signifie que seules les valeurs comprises entre 0,0 et 1,0 seront mappées entre 0 et 255. Si une valeur est supérieure à 1,0 et multipliée par 255, elle deviendra supérieure à 255. Elle sera ensuite limitée à la plage de CV_8U
Et finalement il deviendra également 255.
Dans votre exemple, toutes les valeurs qui sont 1000 deviendront 255 dans la matrice de destination car le type de destination est CV_8U
Et la valeur maximale possible est 255. Toutes les valeurs à virgule flottante seront floor
ed . Aucun mappage automatique n'est effectué.
Pour mapper correctement les valeurs à la plage de CV_8U
, Utilisez les 3e et 4e paramètres de la fonction cv::Mat::convertTo
, De sorte que les valeurs soient mises à l'échelle avant la conversion.
Supposons que la matrice A
ait des valeurs minimale et maximale Min
et Max
, où Min!=Max
.
Pour mettre à l'échelle correctement les valeurs de 0 à 255, vous pouvez procéder comme suit:
if (Min!=Max){
A -= Min;
A.convertTo(B,CV_8U,255.0/(Max-Min));
}
Vous pouvez également le faire directement comme ceci:
if (Min!=Max)
A.convertTo(B,CV_8U,255.0/(Max-Min),-255.0*Min/(Max-Min));
(édité en tenant compte du commentaire de zhangxaochen)