24

各ピクセルが 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);

ただし、2 色しか表示されていません。これは、すべての値が互いに近接しているためです。つまり、150 ~ 175 の範囲 + 黒で表示される小さな値 (以下を参照) にあります。

RGB画像 グレースケール画像

これらの小さな深度の違いを強調するためにさまざまなグレーレベルを表示するように、このデータを正規化する方法はありますか?

4

4 に答える 4

27

ドキュメントによると、関数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]にマップされます。

画像にこの範囲の低い部分の値しか含まれていない場合は、あいまいな画像が観察されます。表示範囲全体(黒から白まで)を使用する場合は、予想されるダイナミックレンジをカバーするように画像を調整する必要があります。これを行う1つの方法は次のとおりです。

double min;
double max;
cv::minMaxIdx(map, &min, &max);
cv::Mat adjMap;
cv::convertScaleAbs(map, adjMap, 255 / max);
cv::imshow("Out", adjMap);
于 2012-12-12T15:02:20.850 に答える
25

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);

結果は次のようになります。

ここに画像の説明を入力

于 2012-12-12T15:43:17.823 に答える
2

サミーの回答に追加すると、元の範囲の色が [-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);
于 2013-05-25T03:25:49.163 に答える
2

入力が浮動小数点データ型の場合imshow、関数はピクセル値が [0; にあると想定します。1] 範囲。その結果、1 より大きい値はすべて白で表示されます。

divisorしたがって、255で割る必要はありません。

于 2012-12-12T12:48:41.890 に答える