2015-09-11 141 views

回答

6

你可以做到這一點,如:

pcl::PointCloud<pcl::PointXYZ>::Ptr SimpleOpenNIViewer::MatToPoinXYZ(cv::Mat OpencVPointCloud) 
     { 
      /* 
      * Function: Get from a Mat to pcl pointcloud datatype 
      * In: cv::Mat 
      * Out: pcl::PointCloud 
      */ 

      //char pr=100, pg=100, pb=100; 
      pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);//(new pcl::pointcloud<pcl::pointXYZ>); 

      for(int i=0;i<OpencVPointCloud.cols;i++) 
      { 
       //std::cout<<i<<endl; 

       pcl::PointXYZ point; 
       point.x = OpencVPointCloud.at<float>(0,i); 
       point.y = OpencVPointCloud.at<float>(1,i); 
       point.z = OpencVPointCloud.at<float>(2,i); 

       // when color needs to be added: 
       //uint32_t rgb = (static_cast<uint32_t>(pr) << 16 | static_cast<uint32_t>(pg) << 8 | static_cast<uint32_t>(pb)); 
       //point.rgb = *reinterpret_cast<float*>(&rgb); 

       point_cloud_ptr -> points.push_back(point); 


      } 
      point_cloud_ptr->width = (int)point_cloud_ptr->points.size(); 
      point_cloud_ptr->height = 1; 

      return point_cloud_ptr; 

     } 

同時,也是otherway

cv::Mat MVW_ICP::PoinXYZToMat(pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr){ 

    cv::Mat OpenCVPointCloud(3, point_cloud_ptr->points.size(), CV_64FC1); 
    for(int i=0; i < point_cloud_ptr->points.size();i++){ 
     OpenCVPointCloud.at<double>(0,i) = point_cloud_ptr->points.at(i).x; 
     OpenCVPointCloud.at<double>(1,i) = point_cloud_ptr->points.at(i).y; 
     OpenCVPointCloud.at<double>(2,i) = point_cloud_ptr->points.at(i).z; 
    } 

    return OpenCVPointCloud; 
} 
+0

這是**無組織**雲只。 – zhangxaochen

+1

是的,否則爲你的自己組織雲...... –

4

要通過Kinect的傳感器捕捉並代表通過depthMat到PCL一系列圖像轉換:: PointCloud你可以試試這個功能。校準參數是使用的那些參數here

{ 
    pcl::PointCloud<pcl::PointXYZ>::Ptr MatToPoinXYZ(cv::Mat depthMat) 
{ 
    pcl::PointCloud<pcl::PointXYZ>::Ptr ptCloud (new pcl::PointCloud<pcl::PointXYZ>); 

// calibration parameters 
    float const fx_d = 5.9421434211923247e+02; 
    float const fy_d = 5.9104053696870778e+02; 
    float const cx_d = 3.3930780975300314e+02; 
    float const cy_d = 2.4273913761751615e+02; 

    unsigned char* p = depthMat.data; 
    for (int i = 0; i<depthMat.rows; i++) 
    { 
     for (int j = 0; j < depthMat.cols; j++) 
     { 
      float z = static_cast<float>(*p); 
      pcl::PointXYZ point; 
      point.z = 0.001 * z; 
      point.x = point.z*(j - cx_d)/fx_d; 
      point.y = point.z *(cy_d - i)/fy_d; 
      ptCloud->points.push_back(point); 
      ++p; 
     } 
    } 
    ptCloud->width = (int)depthMat.cols; 
    ptCloud->height = (int)depthMat.rows; 

    return ptCloud; 

} 
} 
+0

這是一個慢速功能,可以加速更少的乘法和更多的for循環之外。在函數1/fx_d和1/fy_d之前執行fx_d和fy_d,然後將其相乘。嘗試一下 ! –

+0

@MartijnvanWezel感謝您的評論。我編輯了答案。 –

+0

'points.push_back'也許我們可以根據圖像大小定義具有預定義大小的點雲以便不重新分配內存? – mrgloom