日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

DIB-R 可微分渲染器使用

發(fā)布時(shí)間:2024/3/26 编程问答 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DIB-R 可微分渲染器使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?此篇博客轉(zhuǎn)自本作者在古月居的博客:?https://www.guyuehome.com/34349

前言

? 最近由于一些機(jī)會(huì),接觸到了一系列深度學(xué)習(xí)對(duì)稱(chēng)形狀和紋理和篇文章,并嘗試做了一些實(shí)踐。以Learning to Predict 3D Objects with an Interpolation-based Differentiable Renderer舉例,他的思想主要是通過(guò)相機(jī)視角的RGB圖,用類(lèi)似于Auto Encoder的模型輸出三維點(diǎn)和紋理信息。然后通過(guò)一個(gè)渲染器得到在固定角度下的RGB圖像,與之前的輸入形成主要的損失。當(dāng)然論文還介紹了其他光照什么的,細(xì)節(jié)就不在討論了,我們主要用他這個(gè)可微分渲染器。這里給出這篇文章的開(kāi)源鏈接:https://github.com/nv-tlabs/DIB-R

?

Differentiable Renderer

? 由于自己不是專(zhuān)門(mén)做計(jì)算機(jī)圖形學(xué)的。所以,對(duì)于這篇文章中的可微分渲染的理解將表述的很通俗。

? 在NN輸出空間中的三維點(diǎn)的時(shí)候,我們希望也知道這些點(diǎn)的RGB像素值是多少。經(jīng)常,我們可以看到深度相機(jī)中帶有色彩的點(diǎn)云,它們描述了幾何特征和紋理特征。但是,這不是連續(xù)的。我們可能還希望點(diǎn)能連成面,而色彩則可以也可以連續(xù)過(guò)渡。所以那篇論文中最有價(jià)值的部分莫過(guò)于他的基于CUDA的渲染器。有時(shí),我們想輕量級(jí)的使用一個(gè)渲染器,且希望接口簡(jiǎn)單清晰,速度快,易于集成。DIB-R可以是一個(gè)很好的選擇。或者有小伙伴,也想從事于深度學(xué)習(xí)中渲染于幾何物體的相關(guān)領(lǐng)域,這就是一個(gè)很好的選擇。

? 具體原理的可以看文章中3.2的可微分光柵化。這里主要講述了代碼接口解析,并附上一小段測(cè)試的渲染程序以作參考。

環(huán)境

? 環(huán)境至關(guān)重要。我是在Ubuntu18.04上實(shí)現(xiàn)的,基于python3.6。python包的依賴可以看github中的requirments.txt 。

? 其次就是CUDA環(huán)境,這點(diǎn)我裝可好久,此前我想在Colab上裝合適版本的CUDA(版本為11),然后測(cè)試。但是發(fā)現(xiàn)demo寫(xiě)好后,包一些莫名其妙的錯(cuò)誤。然而,我朋友卻用同樣的demo在極客云上用cuda10.2.89的版本跑了起來(lái)。后面,干脆直接在我本地上裝合適的CUDA好了。

? 由?lspci | grep -i nvidia?可以看到我的顯卡是GeForce GTX 1050 Ti Mobile,在https://zh.wikipedia.org/wiki/CUDA?查的自己顯卡計(jì)算能力為6.1, 架構(gòu)是Pascal) 。查表后可以看到支持的cuda版本很多,為了安全起見(jiàn),我也選擇了10.2.89。

? 由于之前裝了一個(gè)低版本的CUDA,所以要進(jìn)行升級(jí)。首先要卸載原來(lái)的。

sudo apt-get --purge remove cuda nvidia* libnvidia-*
sudo dpkg -l | grep cuda- | awk '{print $2}' | xargs -n1 dpkg --purge
sudo apt-get remove cuda-*
sudo apt autoremove
sudo apt-get update

? 然后進(jìn)行安裝新版本的CUDA。

wget --no-clobber https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.2.89-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804_10.2.89-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo apt-get update
sudo apt-get install cuda-10-2

? 確定自己安裝的版本可以由以下方式

cat /usr/local/cuda-10.2/version.txt

? 在安裝好CUDA之后,便可以編譯和下載(按照github上)

cd dib-render/cuda_dib_render
python build.py install

? 注意,如果你之前用了其他版本的cuda編譯過(guò),那么就需要將編譯后生成的文件全部刪去后,在進(jìn)行編譯。上述編譯會(huì)在 cuda_dib_render 中多幾個(gè)文件夾。

接口及測(cè)試

? 編譯后我們甚至可以不考慮那幾個(gè)文件中所做了什么,只要直接使用他的接口即可。比較坑的是,他這個(gè)代碼沒(méi)有像想象那樣進(jìn)行全部開(kāi)源,而是給出渲染器和一個(gè)小的測(cè)試demo。總的工程在 test-all 中進(jìn)行描述。它總的描述了一個(gè)訓(xùn)練的流程是怎樣的,具有借鑒和學(xué)習(xí)意義。這里我們主要?jiǎng)冸x出渲染的主要成分即可。

? 我寫(xiě)可以一個(gè)渲染測(cè)試文件,并對(duì)一些內(nèi)容進(jìn)行了注釋(原來(lái)的demo文件幾乎沒(méi)有什么注釋)。測(cè)試的效果還行,具體如下

? 從圖中可以看出,顏色以一定的塊(條紋塊)進(jìn)行分布。車(chē)子的幾何特征有點(diǎn)粗糙,這是由于所用的obj文件中的點(diǎn)集是NN訓(xùn)練得到的,點(diǎn)集數(shù)量不多,且與原來(lái)形狀有點(diǎn)小差異。對(duì)于代碼的解釋,已經(jīng)全部放在,下面的代碼中。在配置好環(huán)境后,修改路徑即可運(yùn)行。

# Test file written by JWC
import numpy as np
import os
import sys
sys.path.append('/home/jame/Desktop/deguo/DIB-R-master/utils/')
sys.path.append('/home/jame/Desktop/deguo/DIB-R-master/dib-render/render_cuda')
sys.path.append('/home/jame/Desktop/deguo/DIB-R-master/utils/render')
import torch
import torchvision.utils as vutils
from model.modelcolor import Ecoder
from utils.utils_mesh import loadobj, \
face2edge, edge2face, face2pneimtx, mtx2tfsparse, savemesh, savemeshcolor
from utils.utils_perspective import camera_info_batch, perspectiveprojectionnp
from renderfunc_cluster import rendermeshcolor as rendermesh
from utils_render_color2 import linear
import cv2
# Automatic GPU/CPU device placement
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
# 加載相機(jī)參數(shù)
def load_cam( pkl_path):
rotntxname = pkl_path
rotmtx_4x4 = np.load(rotntxname).astype(np.float32)
rotmx = rotmtx_4x4[:3, :3]
transmtx = rotmtx_4x4[:3, 3:4]
transmtx = -np.matmul(rotmx.T, transmtx)
renderparam = (rotmx, transmtx)
return renderparam
# 得到 obj格式點(diǎn)集的 點(diǎn)和面 描述集
pointnp_px3, facenp_fx3 = loadobj('/home/jame/Desktop/deguo/DIB-R-master/mm/off/car_20.obj')
edge_ex2 = face2edge(facenp_fx3)
# edgef_ex2 = edge2face(facenp_fx3, edge_ex2)
# pneimtx = face2pneimtx(facenp_fx3)
tff_fx3 = torch.from_numpy(facenp_fx3).to(device)
# 獲得 點(diǎn),面和邊的數(shù)量
pnum = pointnp_px3.shape[0]
fnum = facenp_fx3.shape[0]
enum = edge_ex2.shape[0]
# print(pnum, fnum, enum)
# 設(shè)定相機(jī)FOV, 可以由相機(jī)內(nèi)參矩陣獲得
camfovy = np.arctan(2*64/140)
# 這里轉(zhuǎn)化 相機(jī)的FOV向量
camprojmtx = perspectiveprojectionnp(camfovy, 1.0)
tfcamproj = torch.from_numpy(camprojmtx).to(device)
# print(tfcamproj.shape)
# 這里增加一個(gè)維度
tfp_1xpx3 = torch.from_numpy(pointnp_px3).to(device).view(1, pnum, 3)
# print(tfp_1xpx3)
# print(tfcamproj)
# 以下將設(shè)定一個(gè)batch中有兩個(gè) mesh 和 顏色集, 以此來(lái)做測(cè)試
meshes = []
meshcolors = []
# 重復(fù)添加兩個(gè)
meshes.append(tfp_1xpx3)
meshes.append(tfp_1xpx3)
# 設(shè)定顏色
temp = []
cout = 0
# 顏色變化處理
for i in range(pnum):
if cout==0:
temp.append([ 1, 0, 0 ])
elif cout ==1:
temp.append([ 0., 1, 0 ])
elif cout ==2:
temp.append([ 0., 0, 1 ])
if i%300 ==0: # 300 決定顏色分布?jí)K大小
cout+=1
if cout ==3:
cout =0
# mesh color 轉(zhuǎn)化為向量
mc_bxp3 = np.array(temp,dtype=np.float32)
# print(mc_bxp3)
# 轉(zhuǎn)化cuda tensor 后增加一個(gè)維度
mc_bxpx3 = torch.from_numpy(mc_bxp3).to(device).view(1, -1, 3)
# print(mc_bxpx3)
# 和之前mesh一致, 也重復(fù)添加兩個(gè)
meshcolors.append(mc_bxpx3)
meshcolors.append(mc_bxpx3)
# print(meshes.shape,meshcolors.shape )
# 轉(zhuǎn)化為tensor
meshesvv = meshes
mcvv = meshcolors
mesh_vvbxpx3 = torch.cat(meshesvv)
mc_vvbxpx3 = torch.cat(mcvv)
# print(mesh_vvbxpx3.shape, mc_vvbxpx3.shape)
# 加載相機(jī)參數(shù),其次變換矩陣保存在 .npy文件中, 注意,物體和相機(jī)關(guān)系需要轉(zhuǎn)換
rotat, trans = load_cam("/home/jame/Desktop/deguo/DIB-R-master/mm/datasets/camera_settings/cam_npy/cam_RT_004.npy")
# rotat = np.array( [[[1.,0.,0.], [0.,1.,0.], [0.,0.,1.] ]], dtype=np.float32 )
# trans = np.array( [[.0,0.,2]], dtype=np.float32 )
rotat = np.array( [rotat], dtype=np.float32 )
trans = np.array( [trans], dtype=np.float32 )
# print(rotat, trans)
# 相機(jī)坐標(biāo)參數(shù) 轉(zhuǎn)化為 cuda 計(jì)算
tfcamrot = torch.from_numpy(rotat).to(device)
tfcampos = torch.from_numpy(trans).to(device)
# 相機(jī)參數(shù)添加到一個(gè)集合中,可能有點(diǎn)冗余,這是為了和 test-all.py中保持一致
tfcams=[[tfcamrot,tfcampos,tfcamproj]]
tfcamrot_bx3x3, tfcampos_bx3, _ = tfcams[0]
# 由于 前面批量了兩個(gè),所以這里需要重讀添加
tfcamsvv = [[], [], tfcamproj]
tfcamsvv[0].append(tfcamrot_bx3x3)
tfcamsvv[1].append(tfcampos_bx3)
tfcamsvv[0].append(tfcamrot_bx3x3)
tfcamsvv[1].append(tfcampos_bx3)
tfcamsvv[0] = torch.cat(tfcamsvv[0])
tfcamsvv[1] = torch.cat(tfcamsvv[1])
# print(tfcamsvv[0].shape, tfcamsvv[1].shape)
# DIB-R渲染接口,至關(guān)重要
tmp, _ = rendermesh(mesh_vvbxpx3, mc_vvbxpx3, tff_fx3, tfcamsvv, linear)
# 第一個(gè)就是渲染后視野中的圖像
impre_vvbxhxwx3, silpred_vvbxhxwx1 = tmp
# 轉(zhuǎn)化到 RGB 值
img = impre_vvbxhxwx3.cpu().numpy().astype(np.float32) *255.0
# print(np.shape( img ))
\# opencv 圖像顯示
cv2.imshow('image', img[0])
cv2.imwrite("./image.jpg",img[0])
cv2.waitKey(0)
print("OVER")

? 以上是作者做的一個(gè)大項(xiàng)目中的一個(gè)小章節(jié),驗(yàn)證可微分渲染以此來(lái)進(jìn)行后面深度學(xué)習(xí)-學(xué)習(xí)mesh的紋理。此處為今后學(xué)習(xí)這個(gè)小伙伴提供一個(gè)參考。

? 另外,這個(gè)項(xiàng)目在后續(xù)將實(shí)踐一個(gè)pytorch深度學(xué)習(xí)學(xué)習(xí)對(duì)稱(chēng)幾何物體紋理的案例,后面有機(jī)會(huì)將持續(xù)跟進(jìn)。

總結(jié)

以上是生活随笔為你收集整理的DIB-R 可微分渲染器使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。