@
一、深度圖像的獲取方法
目前深度圖像的獲取方法有激光雷達深度成像法,計算機立體視覺成像,坐標測量機法,莫爾條紋法,結構光法等等,針對深度圖像的研究重點主要集中在以下幾個方面,深度圖像的分割技術 ,深度圖像的邊緣檢測技術 ,基於不同視點的多幅深度圖像的配准技術,基於深度數據的三維重建技術,基於三維深度圖像的三維目標識別技術,深度圖像的多分辨率建模和幾何壓縮技術等等,在PCL 中深度圖像與點雲最主要的區別在於 其近鄰的檢索方式的不同,並且可以互相轉換。
二、深度圖像簡介
深度圖像(Depth Images)也被稱為距離影像(Range Image),是指將從圖像采集器到場景中各點的距離值作為像素值的圖像,它直接反應了景物可見表面的幾何形狀,利用它可以很方便的解決3D目標描述中的許多問題,深度圖像經過點雲變換可以計算為點雲數據,有規則及有必要信息的點雲數據可以反算為深度圖像數據。
不同視角獲得深度圖像的過程:

三、PCL中的模塊RangeImage相關類的介紹
pcl_range_image庫中包含兩個表達深度圖像和對深度圖像進行操作的類,其依賴於pcl::common模塊,深度圖像(距離圖像)的像素值代表從傳感器到物體的距離以及深度, 深度圖像是物體的三維表示形式,一般通過立體照相機或者ToF照相機獲取,如果具備照相機的內標定參數,就可以將深度圖像轉換為點雲。
3.1 class pcl::RangeImage
RangeImage類繼承於PointCloud,主要功能是實現一個特定視點得到一個三維場景的深度圖像。其繼承關系如下:

類RangeImage的成員有:



3.2 class pcl::RangeImagePlanner
RangeImagePlanner 來源於最原始的深度圖像,但又區別於原始的深度圖像,因為該類不使用球類投影方式,而是通過一個平面投影方式進行投影(相機一一般采用這種投影方式),因此對於已有的利用深度傳感器獲取的深度圖像來說比較實用,類的繼承關系如下:


3.3 從點雲數據生成深度圖像
下面的例子從點雲和給定的傳感器的位置來創建深度圖像,此程序是生成一個矩形的點雲,然后基於該點雲創建深度圖像
#include <pcl/range_image/range_image.h> //深度圖像的頭文件
int main (int argc, char** argv) {
pcl::PointCloud<pcl::PointXYZ> pointCloud; //定義點雲的對象
// 循環產生點雲的數據
for (float y=-0.5f; y<=0.5f; y+=0.01f) {
for (float z=-0.5f; z<=0.5f; z+=0.01f) {
pcl::PointXYZ point;
point.x = 2.0f - y;
point.y = y;
point.z = z;
pointCloud.points.push_back(point); //循環添加點數據到點雲對象
}
}
pointCloud.width = (uint32_t) pointCloud.points.size();
pointCloud.height = 1; //設置點雲對象的頭信息
//實現一個呈矩形形狀的點雲
// We now want to create a range image from the above point cloud, with a 1deg angular resolution
//angular_resolution為模擬的深度傳感器的角度分辨率,即深度圖像中一個像素對應的角度大小
float angularResolution = (float) ( 1.0f * (M_PI/180.0f)); // 1.0 degree in radians
//max_angle_width為模擬的深度傳感器的水平最大采樣角度,
float maxAngleWidth = (float) (360.0f * (M_PI/180.0f)); // 360.0 degree in radians
//max_angle_height為模擬傳感器的垂直方向最大采樣角度 都轉為弧度
float maxAngleHeight = (float) (180.0f * (M_PI/180.0f)); // 180.0 degree in radians
//傳感器的采集位置
Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);
//深度圖像遵循坐標系統
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
float noiseLevel=0.00; //noise_level獲取深度圖像深度時,近鄰點對查詢點距離值的影響水平
float minRange = 0.0f; //min_range設置最小的獲取距離,小於最小獲取距離的位置為傳感器的盲區
int borderSize = 1; //border_size獲得深度圖像的邊緣的寬度
pcl::RangeImage rangeImage;
rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
std::cout << rangeImage << "\n";
}
