我正在使用一个数据集,其中包含图像,其中每个像素都是16位无符号int,以mm为单位存储该像素的深度值。我试图通过执行以下操作将其可视化为灰度深度图像:
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);
然而,它只显示两种颜色,因为所有值都很接近,即在150-175 +范围内显示黑色的小值(见下文)。
有没有办法对这些数据进行标准化,以便显示各种灰度级以突出显示这些小的深度差异?
答案 0 :(得分:21)
根据documentation,函数imshow可以与各种图像类型一起使用。它支持16位无符号图像,因此您可以使用
显示图像cv::Mat map = cv::imread("image", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
cv::imshow("window", map);
在这种情况下,图像值范围从范围[0,255 * 256]映射到范围[0,255]。
如果您的图像仅包含此范围较低部分的值,您将看到一个模糊的图像。如果你想使用整个显示范围(从黑色到白色),你应该调整图像以覆盖预期的动态范围,一种方法是
double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap;
cv::convertScaleAbs(map, adjMap, 255 / max);
cv::imshow("Out", adjMap);
答案 1 :(得分:20)
添加到samg&#39;回答,您可以扩展显示图像的范围。
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);
结果应该类似于下面的
答案 2 :(得分:2)
如果imshow
输入具有浮点数据类型,则该函数假定像素值在[0; 1]范围。因此,所有高于1的值都显示为白色。
因此,您无需将divisor
除以255。
答案 3 :(得分:2)
添加到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);