
前提知識[H, W]存的是深度信息那這里的HW對應(yīng)的是uv而不是x和y。這里的H, W對應(yīng)的是圖像坐標(biāo)里的v, u不是三維空間坐標(biāo)里的X, Y。更準(zhǔn)確地說depth.shape [H, W] depth[v, u] Z其中H圖像高度對應(yīng)行方向W圖像寬度對應(yīng)列方向v行索引范圍是0 ~ H-1u列索引范圍是0 ~ W-1Z該像素對應(yīng)的深度值。所以[H, W] 是二維圖像網(wǎng)格 (v, u) 是圖像上的像素位置 depth[v, u] 存的是深度 Z而三維空間坐標(biāo)是(X, Y, Z)其中X (u - u0) * Z / fx Y (v - v0) * Z / fy Z depth[v, u]所以u, v和X, Y不是一回事。可以這樣理解u, v圖片上第幾列、第幾行 X, Y真實三維空間里左右、上下方向的位置 Z離相機遠(yuǎn)近舉個例子depth[80, 120] 700表示圖像第 80 行、第 120 列這個像素 對應(yīng)的物體表面點距離相機 700mm。然后再結(jié)合相機內(nèi)參才能算出這個點在三維空間里的X, Y, Z[H, W]存的是深度信息這個深度信息就是ZZ depth(u, v)深度圖[H, W]中每個位置(v, u)存的值就是這個像素對應(yīng)空間點的深度Z。更準(zhǔn)確一點depth[v, u] Z其中u圖像橫坐標(biāo)也就是列索引v圖像縱坐標(biāo)也就是行索引Z該像素對應(yīng)的三維點在相機坐標(biāo)系下的深度通常單位是 mm 或 m。然后根據(jù)相機內(nèi)參可以把它還原成三維點X (u - u0) * Z / fx Y (v - v0) * Z / fy Z depth[v, u]所以深度圖本身不是[X, Y, Z]它只直接存了Z。X和Y是通過像素坐標(biāo)(u, v)加上相機內(nèi)參反算出來的。一句話深度圖像素值 Z 像素位置 (u, v) Z 相機內(nèi)參 三維點 (X, Y, Z)深度圖得到多視角虛擬深度圖你可以把深度圖理解成“一張帶距離信息的灰度圖”。普通灰度圖里每個像素只是亮暗深度圖里每個像素值表示這個位置離相機有多遠(yuǎn)。比如深度圖中某個像素是u 120, v 80, depth 700mm意思是圖像第(120, 80)個像素看到的手部表面點距離相機大約700mm。1. 深度圖為什么能變成點云相機拍到的是二維像素坐標(biāo)(u, v)但深度圖還給了距離z。有了相機內(nèi)參就可以把這個二維點還原成三維點。相機內(nèi)參通常包括fx, fy: 焦距 u0, v0: 圖像中心點反投影公式是X (u - u0) * Z / fx Y (v - v0) * Z / fy Z depth(u, v)所以每個有效深度像素(u, v, Z)都能變成一個三維點(X, Y, Z)。整張深度圖里有很多有效像素把它們都轉(zhuǎn)成三維點就得到一堆三維點。這一堆點就叫點云。深度圖 [H, W] 每個有效像素 - 一個三維點 [X, Y, Z] 所有點合起來 - 點云 [N, 3]N是有效深度像素數(shù)量不一定等于H × W因為背景或無效區(qū)域可能被過濾掉。2. 什么是“以手部中心為旋轉(zhuǎn)中心”如果直接繞相機原點旋轉(zhuǎn)手可能會被甩到圖像外面所以通常會先找一個手部中心點比如手掌中心或裁剪框中心記為C (Cx, Cy, Cz)然后每個點先減去這個中心P_centered P - C這樣就相當(dāng)于把手移動到坐標(biāo)系中心附近。之后對這些點做旋轉(zhuǎn)比如繞 x 軸、y 軸旋轉(zhuǎn)P_rotated R * (P - C) C其中P: 原始三維點 C: 手部中心 R: 旋轉(zhuǎn)矩陣 P_rotated: 旋轉(zhuǎn)后的三維點這一步的直觀意思是不是手真的動了而是我們假裝從另一個方向看這只手。3. 旋轉(zhuǎn)矩陣是什么意思比如你想生成左右不同角度的視圖就繞 y 軸旋轉(zhuǎn)想生成上下不同角度的視圖就繞 x 軸旋轉(zhuǎn)。項目中通常會生成一組角度比如水平角度: -60°, -30°, 0°, 30°, 60° 垂直角度: -60°, -30°, 0°, 30°, 60°組合后就是5 × 5 25 個虛擬視角每個角度組合都會生成一個旋轉(zhuǎn)矩陣R然后對點云里的所有點做同樣的旋轉(zhuǎn)。4. 旋轉(zhuǎn)后的點云怎么重新變回深度圖旋轉(zhuǎn)后每個三維點還是(X, Y, Z)。要重新生成圖像需要把三維點投影回二維像素平面。投影公式和反投影相反u fx * X / Z u0 v fy * Y / Z v0 depth(u, v) Z也就是說每個旋轉(zhuǎn)后的三維點都會落到新圖像上的某個像素位置(u, v)它的深度值就是Z。把所有點都投影回去就得到一張新的深度圖。這張圖相當(dāng)于“從另一個角度看到的手”。5. 為什么要處理遮擋和重疊投影時可能出現(xiàn)多個三維點落到同一個像素。例如點 A - 像素 (100, 80), 深度 650mm 點 B - 像素 (100, 80), 深度 720mm相機只能看到離自己更近的點所以應(yīng)該保留較小的深度值depth(100, 80) 650mm這叫 z-buffer 或深度緩沖思想。你的項目里的 CUDA 操作大概率就是為了高效完成深度圖和點云之間的轉(zhuǎn)換。6. 整個過程直觀理解可以把它想象成這樣原始深度圖 從正面看到的一只手 反投影成點云 把這只手表面的像素恢復(fù)成三維空間里的一堆點 旋轉(zhuǎn)點云 假裝換一個角度看這只手 重新投影成深度圖 把新角度下看到的三維點重新拍成一張深度圖所以最終得到原始深度圖: [H, W] 生成 25 個虛擬視角后: 多視角深度圖: [25, H, W]這就是你項目里“虛擬多視角”的核心。它不是簡單把圖片旋轉(zhuǎn)而是先恢復(fù)三維幾何再從不同角度重新投影。