采用MAXScript實現3ds Max自動渲染場景並保存雙攝圖片及其深度圖


目標

打開一個3ds Max的場景,設定好雙目相機的位置以及自動關鍵幀(Auto Key),運行本腳本就能自動渲染並保存幀序列(可用於生成VR視頻動畫),當然,我們這里的目的是為了獲取用於神經網絡訓練的數據集。

Talk is cheap, show me the code!

-- path to save rendering ouputs
root_path = "E:/Gits/Datasets/DCN/scene01"
main_path = root_path + "/picMain/"
aux_path = root_path + "/picAux/"
depth_path = root_path + "/depth/"
makeDir main_path all:true
makeDir aux_path all:true
makeDir depth_path all:true

-- set up rendering sequence
N = 16 -- how many frames to render
TIME_UNIT = 5 -- render every X second
START=101 -- the begin id, to keep digits length the same, begin from 101 is suggested

-- the size to save images
b = bitmap 800 600 -- the bitmap buffer to save, without this memory will increase

-- set up rendering timeout to speed up rendering
--RendererClass.classes as string
renderers.current = RendererClass.classes[7]() -- 8
"current render: " +  (renderers.current as string)
vr = renderers.current
vr.max_render_time = 0.5 -- in minutes, 0.5 min ==30 seconds
--showproperties vr

-- setup vray to export depth maps
mgr = maxOps.GetCurRenderElementMgr() -- the cuurent render manager
mgr.removeallrenderelements() -- clean all previous rendering elements
mgr.addrenderelement (VRayZDepth elementname:(VRayZDepth as string)) -- add vraydepth element
zdepth=mgr.getRenderElement 0 -- get the vraydepth render element
zdepth.zdepth_min=0 -- set the nearest depth 
zdepth.zdepth_max=30000 -- set the farest depth
zdepth.enabled = true -- enable this rendering element
zdepth.filterOn = true -- ensure this vraydepth element filter turned on

for fid = START to (START+N-1) do
(
	-- render main camera with vray z-depth
	render camera: $camMain to: b frame: ((fid-START)*TIME_UNIT)
	b.filename = main_path +(fid as string) + "main.png"
	save b
	
	-- save depth map
	--max render last
	filename = depth_path + (fid as string) + "depth.png"
	"current buffer channel numer: " + (vrayVFBGetNumChannels() as string)
	vfbControl #setchannel 2
	vfbControl #saveimage filename
	
	-- render the aux camera
	render camera: $camAux to: b frame: ((fid-START)*TIME_UNIT)
	b.filename = aux_path + (fid as string) + "aux.png"
	save b
)
close b
-- end

由於MAXScript語法高亮其實在Markdown中是不支持的,而恰好Lua腳本的語法和MAXScript很接近,因此我才用了Lua作為高亮提示。

結果




題外

  1. MAXScript確實非常好用,但我估計還是不如blender好,畢竟blender直接支持Python腳本!!!
  2. 對於AI從業者,MAXScript的學習成本比Blender的Python要高很多,主要是MAXScript的教程和資料太少,大多零散,語言類似lua,對於python用戶來說不是很好上手。
  3. 要將深度圖轉化為對應的視差圖還需要自己寫python腳本,代碼如下:
import numpy as np
import cv2
import glob
import os
import platform

def depth2disp(depth_u8:np.ndarray, d_min, d_max, fx, baseline, max_disp):
    assert depth_u8.dtype == np.uint8
    assert len(depth_u8.shape)==3
    assert depth_u8.shape[2]==4
    assert d_max > d_min
    # refine the depth for sky from alpha channel
    mask_alpha = depth_u8[:,:,3]
    depth_32f = np.array(depth_u8[:,:,0], np.float32)
    depth_32f[mask_alpha==0] = 0
    d_min = max(d_min, 1e-6)
    depth_32f = (255.0 - depth_32f)/255.0*(d_max - d_min) + d_min
    disp_32f = (baseline*fx)/depth_32f
    disp_32f = np.minimum(disp_32f, max_disp)
    return np.uint8((disp_32f * 255.0 )/max_disp)


if __name__ == '__main__':
    root_path = 'E:/Gits/Datasets/DCN/scene01'
    if platform.system()=="Windows":
        root_dir_win32 = root_path.replace('/', '\\\\')
        os.system('md ' + root_dir_win32 + '\\\\disp')
        #print('md ' + root_dir_win32 + '\\\\disp')
    else:
        os.system('mkdir -p ' + root_path + '/disp')
    files = glob.glob(root_path + '/depth/*.png')

    for i in range(len(files)):
        im_depth = cv2.imread(files[i], -1)
        im_disp = depth2disp(im_depth, 0, 30000, 355.096, 10.0, 4)
        if platform.system()=="Windows":
            cv2.imwrite(files[i].replace('depth\\', 'disp\\'), im_disp)
        else:
            cv2.imwrite(files[i].replace('depth/', 'disp/'), im_disp)

--- End.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM