OpenCV: comment visualiser une image de profondeur

j'utilise un ensemble de données dans lequel il y a des images où chaque pixel est un int 16 bits non signé stockant la valeur de profondeur de ce pixel en mm. I am trying to visualize this as a greyscale depth image by doing the following:

cv::Mat depthImage; 
depthImage = cv::imread("coffee_mug_1_1_1_depthcrop.png", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR ); // Read the file 
depthImage.convertTo(depthImage, CV_32F); // convert the image data to float type   
namedWindow("window");
float max = 0;
for(int i = 0; i < depthImage.rows; i++){
    for(int j = 0; j < depthImage.cols; j++){
        if(depthImage.at<float>(i,j) > max){
            max = depthImage.at<float>(i,j);
        }
    }   
}
cout << max << endl;


float divisor = max / 255.0;
cout << divisor << endl;
for(int i = 0; i < depthImage.rows; i++){
    for(int j = 0; j < depthImage.cols; j++){
        cout << depthImage.at<float>(i,j) << ", ";
        max = depthImage.at<float>(i,j) /= divisor;
        cout << depthImage.at<float>(i,j) << endl;
    }   
}


imshow("window", depthImage);
waitKey(0);

Toutefois, c'est seulement en montrant deux couleurs c'est parce que toutes les valeurs sont proches c'est à dire dans la gamme de 150-175 + les petites valeurs qui affichent noir (voir ci-dessous).

rgb imagegreyscale image

Est-il une façon de normaliser ces données de sorte qu'elles montrent divers niveaux de gris pour mettre en évidence ces petites différences de profondeur?

19
demandé sur Aly 2012-12-12 16:40:09

4 réponses

Selon documentation, la fonction imshow peut être utilisé avec une variété de types d'images. Il prend en charge les images non signées 16 bits, de sorte que vous pouvez afficher votre image en utilisant

cv::Mat map = cv::imread("image", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
cv::imshow("window", map);

dans ce cas, la plage de valeurs de l'image est mappée de la plage [0, 255*256] à la plage [0, 255].

si votre image ne contient que des valeurs sur la partie basse de cette plage, vous observerez une image obscure. Si vous souhaitez utiliser la gamme complète d'affichage (du noir au blanc)), vous devez ajuster l'image pour couvrir la plage dynamique attendue, une façon de le faire est

double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap;
cv::convertScaleAbs(map, adjMap, 255 / max);
cv::imshow("Out", adjMap);
20
répondu samota 2012-12-12 15:02:20

en ajoutant à la réponse de samg, vous pouvez étendre encore plus la portée de votre image affichée.

double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap;
// expand your range to 0..255. Similar to histEq();
map.convertTo(adjMap,CV_8UC1, 255 / (max-min), -min); 

// this is great. It converts your grayscale image into a tone-mapped one, 
// much more pleasing for the eye
// function is found in contrib module, so include contrib.hpp 
// and link accordingly
cv::Mat falseColorsMap;
applyColorMap(adjMap, falseColorsMap, cv::COLORMAP_AUTUMN);

cv::imshow("Out", falseColorsMap);

Le résultat devrait être quelque chose comme celui-ci,

enter image description here

19
répondu Sam 2013-03-26 13:54:47

Siimshow l'entrée a le type de données à virgule flottante alors la fonction suppose que les valeurs de pixel sont dans la gamme [0; 1]. En conséquence, toutes les valeurs supérieures à 1 sont affichées en blanc.

Si vous n'avez pas besoin de diviser votre divisor par 255.

2
répondu Andrey Kamaev 2012-12-12 12:48:41

en ajoutant à la réponse de Sammy, si la couleur de gamme originale est [- min, max] et que vous voulez effectuer l'égalisation de l'histogramme et afficher la couleur de profondeur, le code devrait être comme ci-dessous:

double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap;
// Histogram Equalization
float scale = 255 / (max-min);
map.convertTo(adjMap,CV_8UC1, scale, -min*scale); 

// this is great. It converts your grayscale image into a tone-mapped one, 
// much more pleasing for the eye
// function is found in contrib module, so include contrib.hpp 
// and link accordingly
cv::Mat falseColorsMap;
applyColorMap(adjMap, falseColorsMap, cv::COLORMAP_AUTUMN);

cv::imshow("Out", falseColorsMap);
2
répondu Bud 2013-05-25 03:25:49