從零開始一起學習SLAM | 你好,點雲
本文提綱
先熱熱身
點雲是啥
你知道點雲優缺點嗎?
點雲庫PCL:開發者的福音
PCL安裝指北
炒雞簡單的PCL實踐
留個作業再走
先熱熱身
小白:hi,師兄,好久不見
師兄:師妹好,上週單應矩陣作業做了嗎?
小白:嗯,做了,這個單應矩陣真的挺有意思的。作業之外,我發現了一個新技能。。。
師兄:什麼技能?
小白:我發現很多網上流傳的圖片都可以用上次我學過的單應矩陣實現,你看這張圖,我第一次看到還以為是真的

現在知道這不就是我們上節課講的單應矩陣的變換嗎?
果然我在網上找到了原圖
現在我也會用OpenCV裡的單應函式做這樣的圖了~
師兄:哈哈,厲害了,會學以致用了。話說回來,今天有啥想問的?
小白:嗯,最近在看點雲相關的,師兄要不給我掃掃盲吧?
師兄:這個我也有些瞭解,就把我知道的給你說說吧
小白:yeah,師兄最棒!
點雲是啥
師兄:那我就當你是個小白吧,從點雲的定義說起。點雲的英文是“point cloud”,點雲的意思和它的名字一樣,就是一堆點的集合,看起來像是一坨“雲”。
小白:一坨。。。
師兄:哦,一坨不太文雅,應該是像一片“雲”一樣。上面只是一種形象的說法,其實點雲在程式設計實現的時候是一種資料結構,用來表達多維空間中點的集合,這個多維空間一般對我們來說是三維空間。
小白:哦,原來如此,也就是我們所在的 XYZ 空間咯
師兄:對,因此點雲在三維相關的領域內用的很多,比如三維掃描,三維重建、三維感知等方面。
小白:那點雲是怎麼得到的啊?
師兄:一般是通過三維成像感測器得到的,比如雙目相機、三維掃描器、RGB-D相機等,除了可以用這種特殊的硬體得到,也可以用計算機合成。
小白:嗯嗯,師兄說了這麼多,還是沒有一個直觀的印象,這個點雲到底長什麼樣?
師兄:想要直觀一點的話,我直接給你看點雲圖吧,你看下面就是室外一個街道的點雲圖,遠看能看清房子,樹木的輪廓啊
小白:嗯嗯,確實能看出輪廓出來,不過不像是我們平時拍的照片,這個點雲好像看著不是很清楚哎!
你知道點雲優缺點嗎?
師兄:確實是這樣的,這也是點雲的一個缺點吧
小白:那師兄能否順便說說,這個點雲的表達有啥優缺點呢?
師兄:這個問題問的有水平,額,我想想,我先說說優點吧。
第一個優點就是可以表達物體的空間輪廓和具體位置,比如上面這個圖,我們能看出來街道的樣子,房屋的形狀,距離攝像機的距離也是知道的。
第二個優點我覺得就是,點雲本身和視角無關,也就是你可以任意旋轉,可以從不同角度和方向觀察一個點雲,而且不同的點雲只要在同一個座標系下就可以直接融合,還是很方便的。
至於缺點嘛,我們先來放大一下點雲看看。如下圖所示,如果拉近一直放大最後看到的就是一個個的點。也就是空間中成千上萬的點組成了一個點的集合,他們構成了上面的街道房屋等。

小白:這個點雲放大了啥都看不出來啊
師兄:對,這個是點雲的其中一個缺點,那我想想點雲還有哪些缺點哈!
第一個缺點就是點雲並不是稠密的表達,一般比較稀疏,你放大了看,會看到一個個孤立的點。它的周圍是黑的,也就是沒有資訊。所以在空間很多位置其實沒有點雲,這部分的資訊是缺失的。
第二個缺點嘛,就是點雲的解析度和離相機的距離有關。你離近了看是看不清是個什麼東西的,只能拉的很遠才能看個大概。
點雲庫PCL:開發者的福音
小白:嗯,瞭解了,好像缺點也沒啥影響哈。再問個問題,那這些點雲怎麼顯示和儲存啊,感覺點雲很多的話,好像很複雜的樣子。。。
師兄:的確,比如一張 640 x 480 尺寸的深度圖就可以轉換為擁有三十萬個空間點的點雲,大的點雲可能有百萬千萬以上,不過,不用擔心,有一個開源的點雲庫,英文名為Point Cloud Library ,簡稱PCL ,專門用來進行點雲的讀寫,處理等各種操作。
小白:那太好了,這個PCL是誰做的啊?好用嗎?
師兄:這個PCL是由一大批世界範圍內的名校和科技公司合作開發的,你看下面是他們的名字
小白:哇塞,好多不認識啊!不過我看到了ETH,也就是蘇黎世聯邦理工大學,還有TUM,也就是德國慕尼黑工業大學,我看論文經常看到他們學校的,他們都是SLAM領域非常頂級的研究機構呢
師兄:嗯,看來你論文看了不少啊,哈哈。我們繼續說PCL,PCL真的挺方便,支援跨平臺,可以在Windows,Linux,macOS,iOS,Android上部署,可以說非常全了,而且PCL可以分為很多小的庫檔案,在非常適合於計算資源有限或者記憶體有限的應用場景,非常方便移動端開發。
小白:那可以說很通用了哈!對了師兄,那這個PCL都有啥功能?
師兄:功能很豐富了,基本PCL的操作都有,比如讀寫、濾波、特徵估計、表面重建、配準、分割等等,你看這個圖就是PCL的功能啦

小白:嗯嗯,那是不是平時我們操作點雲,調PCL的函式就行了?
師兄:怎麼說呢,其實PCL類似於OpenCV那樣,有很多功能模組,每個模組裡有封裝好的函式,你可以調這些函式進行基本處理,但是有些功能PCL裡可能沒有,這時候需要自己寫一些程式碼實現。
小白:嗯,師兄,總之就是要多程式設計實踐啦
PCL安裝指北
師兄:對,那我們開始實踐環節吧,帶著你做一些PCL的基礎程式設計實現
小白:太好啦!
師兄:首先,我們先來看看點雲庫,也就是PCL的安裝方法,推薦用Linux環節哈,安裝很方便
小白:嗯,我之前聽師兄說Linux環境配置比較簡單,就開始學Linux了,確實,比Windows方便多啦,就是剛開始用命令列不太習慣,好多命令記不住。。。
師兄:沒事的,命令列不用刻意去記,忘記了就去查一下,用多了自然知道了
小白:知道啦!
師兄:PCL在Linux下安裝有兩種方式,一種是安裝編譯好的庫,一種是從原始碼編譯。你看這個是PCL GitHub/">GitHub上的安裝包,前面幾種是不同環境下的編譯好的庫了,最後的source code就是原始碼安裝

小白:那這兩種方式有什麼不一樣的?
師兄:第一種方式比較簡單,幾行命令就可以搞定,比如如果你用的是Ubuntu 16.04版本的Linux系統的話,只需要開啟一個終端,輸入
sudo apt-get install libpcl-dev pcl-tools
就可以自動安裝啦,優點是安裝的版本都是穩定版本(當然也比較舊一點),不需要處理依賴關係,安裝非常方便,不過這種安裝方式也有一些缺點。一個是一般安裝的都不是最新的,二是安裝的都是別人已經編譯好的通用的二進位制庫,所以不能根據自己的需求進行調整
小白:只要一行程式碼確實方便啊!那第二種從原始碼安裝的優缺點呢?
師兄:第二種從原始碼編譯安裝也沒有麻煩多少,它是把所有的原始碼都下載了下來,所以會佔用較多的儲存空間。但好處很多,比如可以下載最新的版本或者指定的版本,可以根據自己的需求在編譯時進行選擇,可以檢視甚至修改某個函式的原始碼等等
小白:感覺都挺好,選擇恐懼症了,不知道該選哪個了。。。
師兄:推薦用第二種吧,從原始碼自己編譯安裝,更方便一些
小白:好,具體如何操作呢?
師兄:首先開啟PCL GitHub的網址: ofollow,noindex">https://github.com/PointCloudLibrary/pcl
然後選擇你需要的版本號,如下圖所示
如果沒什麼特殊需要可以不選擇,我們開啟一個終端,輸入下面一行程式碼
git clone https://github.com/PointCloudLibrary/pcl pcl-trunk
然後PCL 原始碼就 clone 到你的電腦上了
下一步就是Ubuntu下安裝的老一套了,進入目錄,新建一個build資料夾存放編譯的檔案,然後進入build資料夾,cmake一下,然後make,最後install,這一系列流程就是下面這段程式碼了
cd pcl-trunk && mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. make -j2 sudo make -j2 install
靜靜的等待編譯結束就好啦!
炒雞簡單的PCL實踐
小白:嗯嗯,我照著做一下。。。嗯,編譯好啦,我們開始用PCL寫程式碼吧
師兄:那我們來寫一個讀取RGB-D相機的一幀影象並用PCL轉化為點雲的程式碼吧
首先,我們需要定義點雲的結構,我們這裡使用typedef來定義兩個常用的型別
typedef pcl::PointXYZRGB PointT; typedef pcl::PointCloud<PointT> PointCloud;
這裡的 pcl::PointXYZRGB 就是我們定義的空間點,它包括空間座標XYZ以及顏色資訊RGB,此外常用的點的 型別還有
pcl::PointXYZRGBA ( 多了一個alpha通道), pcl::PointXYZ (只有空間位置,不包含顏色資訊),pcl::PointXYZHSV (空間位置 + HSV顏色空間表示的顏色)等,總之,我們這裡輸入的 RGB-D 影象就定義為pcl::PointXYZRGB。
小白:師兄,為什麼這裡要用typedef 啊?我看好多地方都這樣寫的
師兄:這樣是為了把那麼長的一個型別用一個簡單的別名 PointT 來代替,不至於程式碼顯得特別冗長
小白:這樣啊,懂了,那麼 pcl::PointCloud就是點雲了吧?它裡面可以包含許多型別為PointT的點
師兄:對,我們繼續。其實RGB-D影象轉換為點雲的方式也簡單,程式碼如下
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.scale; p.x = (n - camera.cx) * p.z / camera.fx; p.y = (m - camera.cy) * p.z / camera.fy; // 從rgb影象中獲取它的顏色 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); } --------------------- 作者:electech6 來源:CSDN 原文:https://blog.csdn.net/electech6/article/details/84566319 版權宣告:本文為博主原創文章,轉載請附上博文連結!
之所以能這樣寫,前提是 RGB 和 depth圖已經對齊了,也就是 depth 圖中某個位置的深度值在 RGB圖中同樣的位置處就是它對應的顏色。
小白:中間那個計算點的空間座標好像就是用《 從零開始一起學習SLAM | 相機成像模型 》的相機成像模型公式的?
師兄:對,所以這裡需要相機內參。然後需要注意的就是OpenCV裡 RGB 影象裡儲存顏色順序其實是BGR,所以從 RGB中獲取顏色時順序也是 BGR而不是RGB,這裡容易錯。如果沒 問題的話,輸出結果如下,可以在終端裡用pcl_viewer 檢視,用滑鼠可以縮放和翻轉檢視,如果你放大了就發現是一個個的點。下圖是離的比較遠的結果

小白:嗯,這個看起來挺不錯的,那下一步呢?
師兄:下一步就是多個點雲融合了,這部分我給你變成了作業的形式,你可以自己去程式設計練習一下,可以利用前面影象生成點雲的程式碼。
小白:額,好。。師兄猝不及防啊。。。
留個作業再走
題目:點雲融合實驗。已經給定3幀(不連續)RGB-D相機拍攝的 RGB + depth 影象,以及他們之間的變換矩陣(以第一幀為參考幀),請將上述3幀RGB-D影象分別生成點雲並融合出最終的點雲輸出。
練習目的:熟悉PCL的使用,熟悉RGB-D影象到點雲的轉換過程,掌握簡單的點雲融合方法。
如果不出意外,最終點雲融合結果如下:
本文內容部分參考:PCL官網、半閒居士部落格。
師兄提醒:關注“計算機視覺life”微信公眾號,選單欄回覆“點雲”,就能下載程式碼框架和資料啦!
原文連結: 從零開始一起學習SLAM | 你好,點雲
相關推薦
1git clone https://github.com/PointCloudLibrary/pcl pcl-trunk
歡迎關注公眾號:計算機視覺life,一起探索計算機視覺新世界~
---------------------
作者:electech6
來源:CSDN
原文:https://blog.csdn.net/electech6/article/details/84566319
版權宣告:本文為博主原創文章,轉載請附上博文連結!