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

Sir*_*ino 10 c++ opencv input depth kinect

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

CvMat* depthMetersMat = cvCreateMat( 480, 640, CV_16UC1 );
[...]
cvGetImage(depthMetersMat,temp);
Run Code Online (Sandbox Code Playgroud)

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

Gil*_*ish 20

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

SSteve的原始代码:

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

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

m2.convertTo(m2, CV_8U, 0.00390625);
Run Code Online (Sandbox Code Playgroud)

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

  • @Maystro,一个无符号的16位数可以有0到65,535之间的值,但是我们需要将这些值拟合成一个8位数,它只能保存0到255的值.所以我们应用一个比例因子,这意味着您将每个值乘以常数,在本例中为0.00390625.原始矩阵中值为0到255的任何数字都将获得0的新值,256到511变为1,512到767变为2,等等. (3认同)
  • 什么意思是"扩大价值"? (2认同)

SSt*_*eve 2

这应该有效:

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

根据 OpenCV 文档,CvMat 已经过时了。你应该使用 Mat 来代替。