web-dev-qa-db-ja.com

16ビット深度のCvMat *を8ビット深度に変換します

私はKinectとOpenCVを使用しています。私はすでにこのフォーラムで検索していますが、私の問題のようなものは見つかりませんでした。 Kinect(16ビット)からの生の深度データを保持し、それをCvMat *に保存してから、それをcvGetImageに渡して、そこからIplImage *を作成します。

CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );
[...]
cvGetImage(depthMetersMat,temp);

しかし今、cvThreshdoldを実行して輪郭を見つけるために、この画像で作業する必要があります。これらの2つの関数は、入力に8ビット深度の画像を必要とします。 CvMat * depthMetersMatを8ビット深度-CvMat *に変換するにはどうすればよいですか?

11
Sirnino

@SSteveが出した答えはほとんど私にとってはうまくいきましたが、convertToの呼び出しは、実際に値を8ビット範囲にスケーリングするのではなく、上位バイトを切り落とすように見えました。 @Sirninoはどの動作が必要かを指定していなかったので、他の誰かがそれをしたい場合に備えて、(線形)スケーリングを行うコードを投稿すると思いました。

SSteveの元のコード:

 CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );  
 cv::Mat m2(depthMetersMat, true);  
 m2.convertTo(m2, CV_8U);

値をスケーリングするには、convertToの呼び出しの3番目のパラメーター(アルファ)としてスケール係数(1/256、または16ビットから8ビットのスケーリングの場合は0.00390625)を追加する必要があります。

m2.convertTo(m2, CV_8U, 0.00390625);

アルファを掛けた後に各値に追加される4番目のパラメーター(デルタ)を追加することもできます。詳細については、 docs を参照してください。

20
Gillfish

これは機能するはずです:

CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );
cv::Mat m2(depthMetersMat, true);
m2.convertTo(m2, CV_8U);

しかし OpenCVのドキュメントによると 、CvMatは廃止されました。代わりにマットを使用する必要があります。

2
SSteve