彩色圖和深度圖轉點雲
阿新 • • 發佈:2019-02-02
環境:windows10、VS2013、opencv 2.49、openNi、PCL1.8opencv 環境搭建參考PCL1.8+openNi搭建參考將上面的opencv和pcl的配置儲存到屬性表中,以便下一次快速引用。新建專案,選擇解決方案配置選擇Debug x64,屬性管理器的Debug|x64中新增上面兩個屬性表RGBDtoPC.cpp
即連結器中的附加依賴項中同時新增帶d和不帶d的依賴項會出問題,如果用Debug除錯則只新增後面帶d的即可,將不帶d的刪除。我添加了這些opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_ml249d.lib
opencv_nonfree249d.lib
opencv_objdetect249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_videostab249d.lib顯示點雲圖參考:
執行後可能直接返回,提示pcl::io Exception單步執行發現cv::imread()並沒有讀取到圖片。原因如下opencv有cvLoadImage()和cv::imread()讀圖片的方法而後者的連結庫版本不正確:(debug下對應的庫為xxxd.lib,release的為xxx.lib)#include "stdafx.h" #include <iostream> #include <pcl/io/io.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <opencv2/opencv.hpp> #include <string> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <pcl/visualization/cloud_viewer.h> using namespace std; // 定義點雲型別 typedef pcl::PointXYZRGBA PointT; typedef pcl::PointCloud<PointT> PointCloud; // 相機內參 const double camera_factor = 1000; const double camera_cx = 325.5; const double camera_cy = 253.5; const double camera_fx = 518.0; const double camera_fy = 519.0; // 主函式 int main(int argc, char** argv) { // 讀取./data/rgb.png和./data/depth.png,並轉化為點雲 // 影象矩陣 cv::Mat rgb, depth; // 使用cv::imread()來讀取影象 // API: http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#cv2.imread rgb = cv::imread("color.png"); cout << "read rgb"<<endl; // rgb 影象是8UC3的彩色影象 // depth 是16UC1的單通道影象,注意flags設定-1,表示讀取原始資料不做任何修改 depth = cv::imread("depth.png"); cout << "read depth" << endl; // 點雲變數 // 使用智慧指標,建立一個空點雲。這種指標用完會自動釋放。 PointCloud::Ptr cloud(new PointCloud); // 遍歷深度圖 for (int m = 0; m < depth.rows; m++) for (int n = 0; n < depth.cols; n++) { // 獲取深度圖中(m,n)處的值 ushort d = depth.ptr<ushort>(m)[n]; // d 可能沒有值,若如此,跳過此點 if (d == 0) continue; // d 存在值,則向點雲增加一個點 PointT p; // 計算這個點的空間座標 p.z = double(d) / camera_factor; p.x = (n - camera_cx) * p.z / camera_fx; p.y = (m - camera_cy) * p.z / camera_fy; // 從rgb影象中獲取它的顏色 // rgb是三通道的BGR格式圖,所以按下面的順序獲取顏色 p.b = rgb.ptr<uchar>(m)[n * 3]; p.g = rgb.ptr<uchar>(m)[n * 3 + 1]; p.r = rgb.ptr<uchar>(m)[n * 3 + 2]; // 把p加入到點雲中 cloud->points.push_back(p); //cout << cloud->points.size() << endl; } // 設定並儲存點雲 cloud->height = 1; cloud->width = cloud->points.size(); cout << "point cloud size = " << cloud->points.size() << endl; cloud->is_dense = false; try{ //儲存點雲圖 pcl::io::savePCDFile("E:\\Visual Studio2013\\project\\RGBDtoPC\\data\\pcd.pcd", *cloud); } catch (pcl::IOException &e){ cout << e.what()<< endl; } //顯示點雲圖 pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");//直接創造一個顯示視窗 viewer.showCloud(cloud);//再這個視窗顯示點雲 while (!viewer.wasStopped()) { } //pcl::io::savePCDFileASCII("E:\\Visual Studio2013\\projectpointcloud.pcd", *cloud); // 清除資料並退出 cloud->points.clear(); cout << "Point cloud saved." << endl; return 0; }
即連結器中的附加依賴項中同時新增帶d和不帶d的依賴項會出問題,如果用Debug除錯則只新增後面帶d的即可,將不帶d的刪除。我添加了這些opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_ml249d.lib
opencv_nonfree249d.lib
opencv_objdetect249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_videostab249d.lib顯示點雲圖參考:
color.pngdepth.png執行結果深度圖和彩色圖沒有對準,可能的原因是在程式碼的相機內參設定不匹配。//顯示點雲圖 pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");//直接創造一個顯示視窗 viewer.showCloud(cloud);//再這個視窗顯示點雲