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