C++ OpenCV:如何可视化深度图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13840013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV: How to visualize a depth image
提问by Aly
I am using a dataset in which it has images where each pixel is a 16 bit unsigned int storing the depth value of that pixel in mm. I am trying to visualize this as a greyscale depth image by doing the following:
我正在使用一个数据集,其中包含图像,其中每个像素都是一个 16 位无符号整数,以毫米为单位存储该像素的深度值。我试图通过执行以下操作将其可视化为灰度深度图像:
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);
However, it is only showing two colours this is because all of the values are close together i.e. in the range of 150-175 + the small values which show up black (see below).
但是,它只显示两种颜色,这是因为所有值都靠得很近,即在 150-175 的范围内 + 显示为黑色的小值(见下文)。
Is there a way to normalize this data such that it will show various grey levels to highlight these small depth differences?
有没有办法对这些数据进行归一化,使其显示各种灰度以突出这些小的深度差异?
采纳答案by samota
According to the documentation, the function imshow can be used with a variety of image types. It support 16-bit unsigned images, so you can display your image using
根据文档,函数 imshow 可用于多种图像类型。它支持 16 位无符号图像,因此您可以使用
cv::Mat map = cv::imread("image", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
cv::imshow("window", map);
In this case, the image value range is mapped from the range [0, 255*256] to the range [0, 255].
在这种情况下,图像值范围从范围[0, 255*256]映射到范围[0, 255]。
If your image only contains values on the low part of this range, you will observe an obscure image. If you want to use the full display range (from black to white), you should adjust the image to cover the expected dynamic range, one way to do it is
如果您的图像仅包含此范围较低部分的值,您将观察到模糊的图像。如果您想使用完整的显示范围(从黑色到白色),您应该调整图像以覆盖预期的动态范围,一种方法是
double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap;
cv::convertScaleAbs(map, adjMap, 255 / max);
cv::imshow("Out", adjMap);
回答by Sam
Adding to samg' answer, you can expand even more the range of your displayed image.
添加到 samg 的答案中,您可以进一步扩展显示图像的范围。
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);
The result should be something like the one below
结果应该是下面这样的
回答by Bud
Adding to Sammy answer, if the original range color is [-min,max] and you want to perform histogram equalization and display the Depth color, the code should be like below:
添加到 Sammy 的答案,如果原始范围颜色是 [-min,max] 并且您想要执行直方图均衡并显示深度颜色,则代码应如下所示:
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);
回答by Andrey Kamaev
Ifimshow
input has floating point data type then the function assumes that pixel values are in [0; 1] range. As result all values higher than 1 are displayed white.
如果imshow
输入具有浮点数据类型,则该函数假定像素值在 [0; 1] 范围。因此,所有大于 1 的值都显示为白色。
So you need not divide your divisor
by 255.
所以你不需要除以divisor
255。