<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      TSDF Fusion實現

      好久沒看博客了,突然想發點東西,遂詐尸

      想來想去不知道發什么,發個作業報告吧

      Task1: 從深度圖生成點云(4 pts.)

      已知相機內外參和深度圖,可以根據以下公式將深度圖的像素坐標\((u, v)\)變換到世界坐標系下的坐標\((x, y, z)\)得到點云。

      \[\left [ \begin{matrix} x \\ y \\ z \end{matrix} \right ] = z \left [ \begin{matrix} 1 / f_x & 0 & -c_x/f_x \\ 0 & 1 / f_y & -c_y/f_y \\ 0 & 0 & 1 \end{matrix} \right ] \left [ \begin{matrix} u \\ v \\ 1 \end{matrix} \right ] \]

      本步驟需要完成:

      • 實現fusion.cam_to_world函數,將深度圖轉為世界坐標系下的點云
      • 對點云進行可視化(可以用trimesh.PointCloud輸出為.ply文件并使用MeshLab打開)
      • 根據點云坐標的最大最小值,確定TSDF的體素場范圍vol_bnds
      • 每個體素小立方體尺寸為vol_size,按照vol_bnds / vol_size確定體素場的整數坐標,在該體素場內劃分格點,作為TSDF的采樣點。

      Task2: 從深度圖采樣(3 pts. )

      與上一步相反,這一步我們需要把TSDF體素場的采樣點向深度圖上投影,然后從深度圖上采樣深度,為計算TSDF做準備。

      本步驟需要完成:

      • TSDF采樣點的整數坐標依次轉換到世界坐標系、相機坐標系、像素坐標
      • 為每個TSDF采樣點從深度圖上采樣深度

      Task3: 計算單幀TSDF(3 pts.)

      根據每個采樣點的深度,可以近似計算得到該點的TSDF值。

      \[TSDF = \min \{1.0, (depth - z) / t \} \]

      本步驟需要完成:

      • 根據深度計算單幀的TSDF值

      Task4: 融合多幀TSDF(3 pts.)

      已知單幀的TSDF數據,我們需要將其通過加權平均的方式融合得到整體的TSDF場。

      \[D_{i+1}(x) = \frac{W_i(x)D_i(x) + w_{i+1}d_{i+1}(x)}{W_i(x) + w_{i+1}(x)} \]

      \[W_{i+1}(x) = W_i(x) + w_{i+1}(x) \]

      本步驟需要完成:

      • 融合多幀TSDF得到TSDF場
      • 在TSDF場上使用Marching Cubes算法得到mesh(Marching Cubes可以調包)。

      附加分(2 pts.)

      任選一項完成即可:

      • 手動實現Marching Cubes算法
      • 使用RGB圖片數據,實現帶顏色的TSDF Fusion

      第一次作業報告

      Task1

      def cam_to_world(depth_im, cam_intr, cam_pose):
          """Get 3D point cloud from depth image and camera pose
          """
          world_pts = np.zeros((3, depth_im.shape[0] * depth_im.shape[1]))
          cam_coords = np.zeros((depth_im.shape[0], depth_im.shape[1], 3))
          
          # 運用np.arrange函數,得到在每個維度上遞增的下標數組:
          cam_coords[:,:,0] = np.tile(np.arange(depth_im.shape[1]), (depth_im.shape[0], 1))
          cam_coords[:,:,1] = np.tile(np.arange(depth_im.shape[0])[:, np.newaxis], (1, depth_im.shape[1]))
          
          # 運用相機內參和深度圖,把像素坐標轉換為相機坐標系坐標
          cam_coords[:,:,0] = (cam_coords[:,:,0] - cam_intr[0, 2]) * depth_im / cam_intr[0, 0]
          cam_coords[:,:,1] = (cam_coords[:,:,1] - cam_intr[1, 2]) * depth_im / cam_intr[1, 1]
          cam_coords[:,:,2] = depth_im
          cam_coords = cam_coords.reshape(-1, 3).T
          
          # concat一個1后再左乘相機外參矩陣,得到世界坐標系坐標,導出為ply
          world_pts = np.dot(cam_pose, np.vstack((cam_coords, np.ones(cam_coords.shape[1]))))[:3]
          pointcloud = trimesh.PointCloud(world_pts.T)
          pointcloud.export("pointcloud.ply")
          return world_pts
      

      確定邊界,在該體素場內劃分格點,作為TSDF的采樣點

      		# 確定邊界
        	vol_bnds[:,0] = np.minimum(vol_bnds[:,0], np.amin(view_frust_pts, axis=1))
          vol_bnds[:,1] = np.maximum(vol_bnds[:,1], np.amax(view_frust_pts, axis=1))
          
          # 劃分格點
          self.ranges = np.ceil((self.vol_bnds[:, 1] - self.vol_bnds[:, 0]) / self.voxel_size )
          self.ranges = self.ranges.astype(int)
      

      一開始寫的for循環,后改成numpy快很多

      Task2

      TSDF采樣點的整數坐標依次轉換到世界坐標系、相機坐標系、像素坐標:

      		# 用arrange得到下標數組
          vox_coords = np.zeros((self.ranges[0], self.ranges[1], self.ranges[2], 3))
          vox_coords[:,:,:,0] = np.tile(np.arange(self.ranges[0])[:, np.newaxis, np.newaxis], (1, self.ranges[1], self.ranges[2]))
          vox_coords[:,:,:,1] = np.tile(np.arange(self.ranges[1])[np.newaxis, :, np.newaxis], (self.ranges[0], 1, self.ranges[2]))
          vox_coords[:,:,:,2] = np.tile(np.arange(self.ranges[2])[np.newaxis, np.newaxis, :], (self.ranges[0], self.ranges[1], 1))
          vox_coords = vox_coords.reshape(-1, 3)
          
          # 世界坐標系
          vox_coords = (vox_coords * self.voxel_size) + self.vol_bnds[:, 0]
          
          # 相機坐標系
          vox_coords = np.dot(np.linalg.inv(cam_pose), np.vstack((vox_coords.T, np.ones(vox_coords.shape[0]))))[:3]
          
          # 像素坐標,先乘內參矩陣并除以z,再取整
          pix_coords = np.dot(cam_intr, vox_coords)
          pix_coords[0, :] /= pix_coords[2, :]
          pix_coords[1, :] /= pix_coords[2, :]
          pix_coords = np.round(pix_coords[:2, :]).astype(int)
      

      為每個TSDF采樣點從深度圖上采樣深度:

      		# 得到在圖像范圍內的點
        	valid_pix = np.logical_and(pix_coords[0, :] >= 0, np.logical_and(pix_coords[0, :] < depth_im.shape[1], np.logical_and(pix_coords[1, :] >= 0, pix_coords[1, :] < depth_im.shape[0])))
      
          # 采樣,圖片深度減去體素對應的深度,得到深度差
          depth_val = np.zeros(pix_coords.shape[1], dtype=float)
          depth_val[valid_pix] = depth_im[pix_coords[1, valid_pix], pix_coords[0, valid_pix]] - vox_coords[2, valid_pix]
          
          # 截斷
          valid_pix = np.logical_and(valid_pix, depth_val >= -self.trunc_margin)
      

      Task3

      計算TSDF值

      		dist = np.minimum(1., depth_val / self.trunc_margin) 
      

      Task4

      融合得到整體的TSDF場

      		# 加權平均
        	self.tsdf_vol[valid_pix] = (self.tsdf_vol[valid_pix] * self.weight_vol[valid_pix] + dist[valid_pix]) / (self.weight_vol[valid_pix] + 1)
          self.weight_vol[valid_pix] += 1
      

      調用marching cube:

      def get_mesh(self):
          tsdf_vol = self.tsdf_vol
          tsdf_vol = tsdf_vol.reshape(self.ranges[0], self.ranges[1], self.ranges[2])
      
          # Extract a mesh
          verts, faces, norms, vals = measure.marching_cubes(tsdf_vol, level=0)
          verts_val = verts * self.voxel_size + self.vol_bnds[:, 0]
      
          # export to ply
          trimesh.Trimesh(verts_val, faces).export("mesh.ply")
      

      處理的 Average FPS: 1.26

      附加分:帶顏色的TSDF fusion

      我的想法是把圖片的顏色加到距離<0.1的體素上,加權平均得到體素顏色

      		# 判斷體素到表面距離,獲得可以加顏色的體素(valid_pix),后續只對這些體素操作
        	valid_pix = np.logical_and(valid_pix, np.logical_and(depth_val < 0.1 , depth_val > -0.1))
          color_val = np.zeros((pix_coords.shape[1], 3), dtype=float)
          
          # 得到顏色
          color_val[valid_pix] = color_im[pix_coords[1, valid_pix], pix_coords[0, valid_pix]]
          
          # 加權平均
          self.color_vol[valid_pix] = (self.color_vol[valid_pix] * self.color_weight_vol[valid_pix] + color_val[valid_pix]) / (self.color_weight_vol[valid_pix] + 1)
          self.color_weight_vol[valid_pix] += 1
      

      導出的時候對mesh頂點查詢顏色:

      		# Get vertex colors
          colors = self.color_vol.reshape(self.ranges[0], self.ranges[1], self.ranges[2], 3)
          verts = verts.astype(int)
          colors = colors[verts[:, 0], verts[:, 1], verts[:, 2]]
      
          # export to ply
          trimesh.Trimesh(verts_val, faces, vertex_colors=colors).export("mesh.ply")
      

      處理的 Average FPS: 0.93

      因為顏色初值為0,邊緣是黑色的

      end

      最近越來越頹廢了,之前跟著做gnn感覺沒意思,又學了點graphics的東西,現在感覺也可能最后不做科研去打工了,前途無望。。。

      posted @ 2024-04-24 01:29  lcyfrog  閱讀(695)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产剧情91精品蜜臀一区| 国产精品无码av天天爽播放器| 最新国产AV最新国产在钱| 少妇人妻偷人精品无码视频| 国产三级黄色片在线观看| 狠狠色综合网站久久久久久久| 肥西县| 亚洲天堂精品一区二区| 福利一区二区在线播放| 亚洲综合无码一区二区| 免费无码一区无码东京热| 天堂av色综合久久天堂| CAOPORN免费视频国产| 日本深夜福利在线观看| 四虎永久地址www成人| av小次郎网站| 国产男女猛烈无遮挡免费视频网站 | 国厂精品114福利电影免费| 99久久国产宗和精品1上映| av天堂久久精品影音先锋| 亚洲全乱码精品一区二区| 狠狠噜天天噜日日噜| 庄浪县| 亚洲日本欧美日韩中文字幕| 国产久免费热视频在线观看| 国产乱码精品一区二区三区中文| 亚洲免费最大黄页网站| 国产午夜福利视频在线| 巨胸喷奶水视频www免费网站| 亚洲无人区一码二码三码| 亚洲av激情一区二区三区| 极品美女aⅴ在线观看| 亚洲色欲色欱WWW在线| 亚洲国产一区二区三区最新| 大帝AV在线一区二区三区| 午夜成人无码免费看网站| 国产免费高清69式视频在线观看| 精品国产成人三级在线观看 | 中文字幕乱码一区二区免费| 成人午夜视频在线| 韩国V欧美V亚洲V日本V|