web-dev-qa-db-ja.com

MatオブジェクトのタイプをCV_32FからCV_8Uに変更します

Imshow関数を使用してCV_32Fタイプの画像を表示しようとしましたが、WHITE画像が表示されました。 Documentation では、浮動小数点画像が0-255にマッピングされて表示されますが、白い画像が表示されるだけであるため、CV_8Uに変換してみました

マットA = Mat :: ones(300,300、CV_32FC1)* 1000;

何らかの処理を行う-Aのピクセルにfloat値を割り当てる

......

マットB;

A.convertTo(B、CV_8U)

「B」を表示すると、白黒の画像が表示されますが、グレーの陰影がありません。 Aのfloat値のピクセルは0-255に適切にマッピングされていますか?私は何か間違っていますか?

Aの初期化された値は1000で、残りは処理中に割り当てられる浮動小数点数です。

31
Karthik Murugan

OpenCVでは、画像が浮動小数点型の場合、0.0から1.0までの値を持つimshowを使用してそれらのピクセルのみを視覚化できます。値が1.0より大きい場合、白として表示されますピクセルで、0.0未満の場合は黒のピクセルとして表示されます。浮動小数点画像を視覚化するには、その値を0.0 - 1.0の範囲にスケーリングします。

変換部分については...デフォルト引数と一緒に使用すると、cv::Mat::convertTo関数は指定されたタイプのマトリックスを作成し、ソースマトリックスから値をコピーしてから、デスティネーションデータタイプの最も近い値に丸めます。 。値が範囲外の場合、最小値または最大値に固定されます。

imshowのドキュメントには、次のように書かれています。

画像が32ビット浮動小数点の場合、ピクセル値に255が乗算されます。つまり、値の範囲[0,1]は[0,255]にマッピングされます。

これは、0.0〜1.0の範囲の値のみが0〜255にマッピングされることを意味します。値が1.0より大きく、255を掛けると、255を超えます。その後、CV_8Uの範囲に固定されます。そして最終的には255にもなります。

この例では、宛先タイプがCV_8Uであり、最大可能値が255であるため、1000であるすべての値は宛先マトリックスで255になります。すべての浮動小数点値はflooredになります。自動マッピングは行われません。

値をCV_8Uの範囲に適切にマップするには、関数cv::Mat::convertToの3番目と4番目のパラメーターを使用して、変換が行われる前に値がスケーリングされるようにします。

マトリックスAに最小値と最大値MinおよびMaxがあるとします(ここでMin!=Max)。

0から255の値を適切にスケーリングするには、次の操作を実行できます。

if (Min!=Max){ 
    A -= Min;
    A.convertTo(B,CV_8U,255.0/(Max-Min));
}

これを次のように直接行うこともできます。

if (Min!=Max)
    A.convertTo(B,CV_8U,255.0/(Max-Min),-255.0*Min/(Max-Min));

(zhangxaochenのコメントを考慮して編集)

56
sgarizvi