采用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