iT邦幫忙

1

如何從深度圖取得真實的距離

  • 分享至 

  • xImage

目前的研究領域:
單目深度估計,用深度學習的方式預測出深度圖。

我目前了解的情報:
深度圖是儲存深度資訊的圖片,通常以灰階的png檔形式儲存,有的會根據不同距離範圍去染色,讓他比較具有可讀性,正常的深度圖越遠顏色越亮,越近越暗,但是有的則相反,似乎是為了更好的評估準確率所做的調整(實際狀況不確定)。

參考#2
拿RGB圖片、深度圖及相機參數可以轉成點雲圖(Point Cloud),
這個時候每個點的Z軸值應該就是實際距離。

參考#3
或許可以不用轉點雲圖,直接使用scale factor就可以去將深度值還原成實際距離。
不清楚是限定於kitti dataset的圖片或是沒限制(?),拿自己手機拍的照片去估測感覺就會出事...
另外發現讀入 16 bit png的時候需要特別處理,不然會被轉成8bit 參考#4

問題:

  1. scale_factor如何取得,#2的解釋我看不太懂。

  2. kitti dataset(depth prediction的部分)那些相機參數(camera intrinsics(3×3 matrix)究竟放在哪? 裡面的東西下載下來沒有發現類似的東西。

  3. 正常來講這種單張圖測距的方法應該是已經有人可以做到了,甚至應該已經蠻成熟的了,但是卻一直找不到資源,我搜尋depth map to distance 之類的語句都沒發現,有沒有人有線索?

((網路上的資訊實在過於零散,又不一定可信,找資料找到心累,所以跑來這邊發文,尋找大大們的幫忙。

#1 kitti dataset
http://www.cvlibs.net/datasets/kitti/eval_depth.php?benchmark=depth_prediction

#2 depth map to point cloud:
https://github.com/vitalemonate/depth2Cloud

#3 Get Absolute distances value from the Kitti GT Depth map
https://github.com/JiawangBian/sc_depth_pl/issues/6

#4 Read 16-bit PNG file
https://stackoverflow.com/questions/32622658/read-16-bit-png-image-file-using-python

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

3
haward79
iT邦研究生 2 級 ‧ 2022-03-02 09:12:05
最佳解答

先說,我自己沒用過 kitti dataset,但我有用過 Intel RealSense D435i 做過 SLAM 等應用,所以對深度攝影機、深度影像等略懂,以下簡單分享一些淺見。

(1) 回應問題1

其實我覺得你所找到的參考資料已說的很清楚了,當中有提到:

depth_map_value / real_depth = scale_factor

就如同你所知道的:深度圖是個三維的圖片,其中前兩維是圖片的大小,第三維是代表深度。圖片中儲存的深度並不代表實際的深度(或說距離)。舉例來說:如果你知道圖片上的某一點其值為 22,並不代表在那一點的距離為 22 公分或公尺,請參考下面深度圖的繪製方法的說明。

深度圖如何繪製?
(i) 由深度攝影機發射紅外線等來測量攝影機與物體的距離,單位可能為公分、公尺之類的,要依照你用的裝置來決定。

(ii) 為了繪製深度圖,會將實際的深度對應到圖片的灰階值域中。例如:假設我的攝影機能夠測量最近 0 公尺、最遠 100 公尺的深度,而我採用的圖片格式使用 8 bit 來表示深度,也就是說可表示的深度範圍為 0 ~ 255,若要依此繪製深度圖,我就必須將 0 公尺 ~ 100 公尺的深度,對應到 0 ~ 255 的數值範圍內,因此若是實際影像中某個點的距離為 0 公尺,則在圖片中的數值就會被設為 0 ,若是實際影像中某個點的距離為 100 公尺,則在圖片中的數值就會被設為 255 ,若是實際影像中某個點的距離為 50 公尺,則在圖片中的數值就會被設為 128 (估算) 。

計算公式如下:
圖片中的數值 = 255 / 100 * 實際距離

而上述公式中的 255 / 100 就是所謂的 scale factor。
當然如果是以 圖片中的數值 轉換成 實際距離 的話,scale factor 就會變成 100 / 255 。

所以再看回到參考資料的公式:

depth_map_value / real_depth = scale_factor

這樣應該會比較好理解了!depth_map_value 就是例子中的 圖片中的數值,real_depth 就是 實際距離,scale_factor 就是 255 / 100 。

不過要注意的是,我剛剛的例子中有兩個假設:
(i) 假設我的攝影機能夠測量最近 0 公尺、最遠 100 公尺的深度
(ii) 我採用的圖片格式使用 8 bit 來表示深度

如果 kitti dataset 所採用的規格與上述不同,則數值上需要再做調整。

(2) 回應問題2

如同我一開始提到的,我自己沒用過 kitti dataset 所以暫時無法提供協助。

(3) 回應問題3

首先,你已經有找到相關的資料了,只是你似乎沒有看懂,就如同上面舉的例子。我想會造成這樣的問題可能有幾個原因:
(i) 你的資訊或數學基礎不足:畢竟你也沒有描述你的自身背景,學過哪些東西、不懂的部份在哪,因此只能先下此結論。

(ii) 你缺乏資料統整的能力:網路上資料很多,只是很多時候這些資料是零碎的。很多時候網友可能只是順手寫個筆記,所以通常會針對寫作者本人的需求或正在製作的東西來撰寫內文,導致創作出來的內文跟你所要找尋的東西並不是 100% 相同,此時你需要從中擷取你覺得有用的資訊,東拼西湊來得出你所期待的結果。

以上僅供參考。

以下是我最新的理解,不確定對不對:

首先我手上有一份NYUV2的訓練集,儲存格式是8bit的jpg檔,值域是0~255
NYUv2 dataset的測量範圍是0~10m
scale_factor = 255/10=25.5
假設有一點深度值是255,255/25.5=10m,剛好可以還原

補充:
我在github查到kitti的scale factor是256,NYUv2是1000,雖然找不到官方數據但是有幾篇討論的回應都是這個數值。
https://github.com/vinvino02/GLPDepth/issues/6

我要發表回答

立即登入回答