Nuke scripting - number of different type trackers in each frame


#1

Hello!

I need to know the number of different types of trackers (green, red, orange) in each frame of 3D camera tracking and I’ve searched through the whole Nuke documentation but they seems irretrievable, I couldn’t find a word about it. Anyone know if it is possible to get that numbers from Nuke? The way doesn’t matter, it could be through Pyton, plugin in C++ or even TCL.


#2

You want to know how many features are tracked which are of each value red/orange/green? or do you just want to know the total number of features?

Also out of curiousity can you tell me what you are trying to do with this information?


#3

I need the number of each value, especially red and orange to know which frames contain the most unsolved tracks. It’s for academic research.


#4

I asked our engineers and they said they didn’t add any python hooks for getting this information. You can send a feature request for this into support@thefoundry.co.uk


#5

Thank you for your effort! I suspected that there might be no such features as I left no stone unturned looking through the available documentation. Thanks for the contact email too, I’ll surely write to them.


#6

You should ask this guy:
http://hagbarth.net/?page_id=96

He have reverse engineered the Camera Tracker node and can get all data out like the error data you are looking for.


#7

Wow! This guy does a really cool stuff!
I’ve been away for some time and now I’m trying to catch up with everything. Thanks for sharing!


#8

Stickit is a really nice use of our tech but it’s just a group/gizmo, he’s not really reverse engineering anything. There is a camera tracker node inside it.


#9

You need to look at the python code in the gizmo itself. He does state that he did it in his code. As you said yourself there is no api for the camera tracker node, yet he is still able to get all data out of it without it. But I am not sure about the definition of the word reverse engineering anyway.

Here is the part of his code:

'''================================================================================
; Function:             ExportCameraTrack(myNode):
; Description:          Extracts all 2D Tracking Featrures from a 3D CameraTracker node (not usertracks).
; Parameter(s):         myNode - A CameraTracker node containing tracking features
; Return:               Output - A list of points formated [ [[Frame,X,Y][...]] [[...][...]] ]
;                           
; Note(s):              N/A
;=================================================================================='''
def ExportCameraTrack(myNode):
    #This code is rather messy and was made as i was reverse engineering the cameratracker node.
    #As this is now fully functional but contains quite alot of redundency it would be good to just rewrite it all
    #If you don't udnerstand it, i don't blame you! =)

    myKnob = myNode.knob("serializeKnob")
    myLines = myKnob.toScript()    
    DataItems = string.split(myLines, '
')
    Output = []
    for index,line in enumerate(DataItems):
        tempSplit = string.split(line, ' ')
        if (len(tempSplit) > 4 and tempSplit[ len(tempSplit)-1] == "10") or (len(tempSplit) > 6 and  tempSplit[len(tempSplit)-1] == "10"): #Header
            #The first object always have 2 unknown ints, lets just fix it the easy way by offsetting by 2
            if len(tempSplit) > 6 and  tempSplit[6] == "10":
                offsetKey = 2
                offsetItem = 0
            else:
                offsetKey = 0
                offsetItem = 0
            #For some wierd reason the header is located at the first index after the first item. So we go one step down and look for the header data.
            itemHeader = string.split(myLines, '
')[index+1]
            itemHeadersplit = string.split(itemHeader, ' ')
            itemHeader_UniqueID = itemHeadersplit[1]

            #So this one is rather wierd but after a certain ammount of items the structure will change again.
            firstOffset = 0
            secondOffset = 0
            secondItem = string.split(myLines, '
')[index+2]
            secondSplit = string.split(secondItem, ' ')
            if len(secondSplit) == 7:
                 firstOffset = 0
            if len(itemHeadersplit) == 3:
                itemHeader = string.split(myLines, '
')[index+2]
                itemHeadersplit = string.split(itemHeader, ' ')
                offsetKey = 2
                offsetItem = 2
                if len(secondSplit) == 11:
                  firstOffset = 1 #In this case the 2nd item will be +1                
                elif len(secondSplit) == 7:
                  firstOffset = 1
                else:
                  firstOffset = 0 #In this case the 2nd item will be +0
            itemHeader_FirstItem = itemHeadersplit[3+offsetItem]
            itemHeader_NumberOfKeys = itemHeadersplit[4+offsetKey]
            #Here we extract the individual XY coordinates
            PositionList =[]
            PositionList.append([int(LastFrame)+(0),string.split(DataItems[index+0], ' ')[2]  ,string.split(DataItems[index+0], ' ')[3]])
            for x in range(2,int(itemHeader_NumberOfKeys)):
                if len(string.split(DataItems[index+x+firstOffset-1], ' '))>7 and len(string.split(DataItems[index+x+firstOffset-1], ' '))<10 and int(string.split(DataItems[index+x+firstOffset-1], ' ')[5]) > 0:
                  #print "SHIT!!! VIRUZ!!!"
                  Offset = int(string.split(DataItems[index+x+firstOffset-1], ' ')[7])
                  PositionList.append([int(LastFrame)+(x-1),string.split(DataItems[Offset+1], ' ')[2]  ,string.split(DataItems[Offset+1], ' ')[3]]) 
                  secondOffset = 1
                else:
                  PositionList.append([int(LastFrame)+(x-1),string.split(DataItems[index+x+firstOffset-secondOffset], ' ')[2]  ,string.split(DataItems[index+x+firstOffset-secondOffset], ' ')[3]])         
            Output.append(PositionList)
        elif (len(tempSplit) > 8 and tempSplit[1] == "0" and tempSplit[2] == "1"):
            LastFrame = tempSplit[3]
        else:  #Content
            pass
    return Output

I don’t know what half of this code is doing but it sure looks like some nasty hack stuff.


#10

I know this code as I came across it during my research. I analysed it once line by line. It retrieves data from CameraTracker node but the data I need are inside CameraTrackerPointCloud node. I tried “reverse engineering” method from this code to get the structure of the node but get the more or less random numbers wth no meanig to me. Another dead end.


#11

Response I got from Nuke support team:

“Unfortunately you can’t get access to that granularity of track detail from the Python / TCL interface.
You might be able to query the “trackCurve” knob, but remember that it is averaged data.”

Great…