cv::Mat和XnDepthPixel之间的转换*
Convertion Between cv::Mat and XnDepthPixel*
我正在使用OpenNI 1.5.4.0和OpenCV 2.4.5,以及用于可视化目的的Qt(仅RGB图像)。基本上,我是从Kinect中检索深度和rgb帧并将它们存储在硬盘驱动器上,使用转换:
/* Depth conversion */
cv::Mat depth = cv::Mat(2, sizes, CV_16UC1, (void*) pDepthMap); //XnDepthPixel *pDepthMap
/* RGB conversion */
///image is a QImage* , pImageMap is a XnUInt8*
for(int i = 0; i < height; ++i)
{
for (unsigned y = 0; y < height; ++y)
{
uchar *imagePtr = (*image).scanLine(y);
for (unsigned x=0; x < width; ++x)
{
imagePtr[0] = pImageMap[2];
imagePtr[1] = pImageMap[1];
imagePtr[2] = pImageMap[0];
imagePtr[3] = 0xff;
imagePtr+=4;
pImageMap+=3;
}
}
}
现在,我想从硬盘驱动器加载这些图像,以便计算3D点云作为后处理计算。我加载深度图为:
depth_image = cv::imread(m_rgb_files.at(w).toStdString(), CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR );
,但应用公式:
depth = depth_image.at<int>(j,i); //depth_image is stored as 16bit
p.z = (float)depth * 0.001f; //converting from millimeters to meters
p.x = (float)(i - m_params.center_x) * depth * m_params.focal_length; //focal_length read using OpenNI function
p.y = (float)(j - m_params.center_y) * depth * m_params.focal_length;
得到的点云是一团糟。
如果我做"在线"处理,直接使用本机XnDepthPixel*数据,结果是完美的,使用之前编写的公式。谁能给我一个"提示"我的错误?
thanks in advance
编辑:我也遵循这个资源,但它不适合我,因为XnDepthPixel包含真实世界的数据在毫米
我觉得这里可能有问题:
depth = depth_image.at<int>(j,i); //depth_image is stored as 16bit
如果深度图像真的是 16位,它真的应该是:
depth = depth_image.at<short>(j,i); //depth_image is stored as 16bit
因为int
是32位,而不是16位。
只是作为一个补充,如果你已经用OpenNI支持构建了OpenCV,你可以检索深度图像作为cv::Mat
,你可以很容易地用cv::imwrite
保存下面是一个简单的例子:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(){
VideoCapture capture;
capture.open(CV_CAP_OPENNI);
if( !capture.isOpened() ){
cout << "Can not open a capture object." << endl;
return -1;
}
cout << "ready" << endl;
for(;;){
Mat depthMap,depthShow;
if( !capture.grab() ){
cout << "Can not grab images." << endl;
return -1;
}else{
if( capture.retrieve( depthMap, CV_CAP_OPENNI_DEPTH_MAP ) ){
const float scaleFactor = 0.05f;
depthMap.convertTo( depthShow, CV_8UC1, scaleFactor );
imshow("depth",depthShow);
if( waitKey( 30 ) == 115) {//s to save
imwrite("your_depth_naming_convention_here.png",depthShow);
}
}
}
if( waitKey( 30 ) == 27 ) break;//esc to exit
}
}
相关文章:
- 构造函数和转换运算符之间的重载解析
- C ++中无符号位长度类型之间的隐式转换,即uint8_t,uint16_t
- 模板转换运算符在 clang 6 和 clang 7 之间的区别
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- Cxx.jl 在 Julia Complex 和 std::complex 之间进行转换
- 如何在 std::string 和 Aws::String 之间进行转换?
- 转换字符时Arduino DUE 和 Arduino UNO 之间的区别
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 指向 POD 类型的指针之间的静态转换与重新解释转换
- 在 Rcpp 中的字符串类型之间转换时出错
- 如何声明不同类型的模板化类之间的转换
- C 和 C++ 中的函数指针转换之间的差异
- 与浮点转换之间的规范化整数
- 重新解释强制转换和 C 样式转换之间的 C++ 区别
- C++ get 和类型转换之间的用法有什么区别?我应该使用哪一个?
- printf函数参数之间的序列点;转换之间的顺序点是否重要
- Clang和GCC中不明确基类转换之间的行为差异
- 转换之间的双和字节数组,为传输ZigBee API
- 隐式转换和显式转换之间的区别
- interpret_cast和C样式强制转换之间的区别是什么