将16位深度CvMat *转换为8位深度

时间:2011-08-02 08:50:51

标签: c++ opencv input kinect depth

我正在与Kinect和OpenCV合作。我已经在这个论坛上搜索,但我找不到类似我的问题。 我保留了Kinect(16位)的原始深度数据,我将它存储在CvMat *中,然后将其传递给cvGetImage以从中创建IplImage *:

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

但是现在我需要处理这个图像才能做cvThreshdold并找到轮廓。这两个函数在输入中需要8位深度图像。如何在8位深度的CvMat *中转换CvMat * depthMetersMat?

2 个答案:

答案 0 :(得分:20)

@ SSteve给出的答案几乎为我做了诀窍,但对convertTo的调用似乎只是切断了高位字节而不是实际将值缩放到8位范围。由于@Sirnino没有指定需要哪种行为,我认为我会发布将执行(线性)缩放的代码,以防其他人想要这样做。

SSteve的原始代码:

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

要缩放值,您只需要将比例因子(1/256或0.00390625,对于16位到8位缩放)添加为对convertTo的调用的第三个参数(alpha)

m2.convertTo(m2, CV_8U, 0.00390625);

您还可以添加第四个参数(delta),它将在与alpha相乘后添加到每个值中。有关详细信息,请参阅docs

答案 1 :(得分:2)

这应该有效:

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

但是according to the OpenCV docs,CvMat已经过时了。你应该使用Mat。