私は、各ピクセルがmmでそのピクセルの深度値を格納する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);
ただし、2つの色しか表示されていません。これは、すべての値が互いに近い、つまり150〜175の範囲+黒が表示される小さな値であるためです(以下を参照)。
これらの小さな深さの違いを強調するためにさまざまなグレーレベルを表示するように、このデータを正規化する方法はありますか?
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);
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);
結果は以下のようになります
If imshow
入力に浮動小数点データ型がある場合、関数はピクセル値が[0; 1]範囲。結果として、1より大きいすべての値は白で表示されます。
したがって、divisor
を255で割る必要はありません。
サミーの答えに加えて、元の範囲の色が[-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);