Custom Scripts VIII: Depth pass normalization

The depth pass shows the distance between points in 3D space and the camera. That’s why depth passes usually have very high values. However, to work with them is preferable to have them normalized to 0-1 range. That is the objective of this script.

It analyzes the depth pass and normalizes the values in a ‘relative’ (highest and lowest values of that frame) or in an ‘absolute’ (highest and lowest values in the whole footage) way. Sometimes we must be careful with the background though. If we have used a skydome, for example, maybe it’s a good idea to remove the background before executing the script.

def normalizer():
    oNode = nuke.selectedNode()
    oNodeChannels = oNode.channels()
    oNodeLayers = list(set([c.split('.')[0] for c in oNodeChannels]))
    p = nuke.Panel('Depth Map Normalizer')
    p.addEnumerationPulldown('depth', ' '.join(oNodeLayers))
    p.addEnumerationPulldown('normalize', 'relative absolute')
    if not p.show():
        return
    depthLayer = p.value('depth')
    nType = p.value('normalize')
    if nType == 'absolute':
        timeNode = nuke.createNode('TimeClip', inpanel=True)
        calcFirst = int(timeNode['first'].getValue())
        calcLast = int(timeNode['last'].getValue())
        nuke.delete(timeNode)
    shuffle = nuke.nodes.Shuffle(label='[python {nuke.thisNode().knob("in").value().upper()}] to [python {nuke.thisNode().knob("in2").value().upper()}]', inputs=[oNode])
    shuffle['in'].setValue(depthLayer)
    shuffle['in2'].setValue('rgba')
    shuffle['ypos'].setValue(shuffle.ypos()+25)
    dot2 = nuke.nodes.Dot(inputs=[shuffle])
    dot2['ypos'].setValue(dot2.ypos()+40)
    grade = nuke.nodes.Grade(inputs=[dot2])
    grade['ypos'].setValue(grade.ypos()+100)
    grade['label'].setValue('NORMALIZE')
    grade['channels'].setValue('rgba')
    dot3 = nuke.nodes.Dot(inputs=[dot2])
    dot3['ypos'].setValue(dot2.ypos())
    dot3['xpos'].setValue(dot2.xpos()+150)
    ctNode = nuke.nodes.CurveTool(inputs=[dot3])
    ctNodeW = ctNode.width()
    ctNodeH = ctNode.height()
    ctNode['ROI'].setValue(ctNodeW, 2)
    ctNode['ROI'].setValue(ctNodeH, 3)
    ctNode['ypos'].setValue(ctNode.ypos()+25)
    ctNode['label'].setValue('MAX')
    ctNode['operation'].setValue(3)
    if nType == 'relative':
        nuke.execute(ctNode, nuke.frame(), nuke.frame())
    else:
        nuke.execute(ctNode, calcFirst, calcLast)
    maxValue = ctNode.name() + '.maxlumapixvalue'
    dot4 = nuke.nodes.Dot(inputs=[dot3])
    dot4['ypos'].setValue(dot3.ypos())
    dot4['xpos'].setValue(dot3.xpos()+150)
    minNode = nuke.nodes.MinColor(inputs=[dot4])
    minNode['ypos'].setValue(minNode.ypos()+25)
    minNode['label'].setValue('MIN')
    minNode['target'].setValue(0)
    if nType == 'relative':
        nuke.execute(minNode, nuke.frame(), nuke.frame())
    else:
        nuke.execute(minNode, calcFirst, calcLast)
    minValue = 'abs(' + minNode.name() + '.pixeldelta'+ ')'
    grade['blackpoint'].setExpression(maxValue)
    grade['whitepoint'].setExpression(minValue)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.