non commercial camera tracker

a new non commercial camera tracker since icarus is no more free, we need one.

http://www.digilab.uni-hannover.de/docs/manual.html

hi
this is only for Max or SI, but it work on win and linux
will be really cool for blender too 8)
malefico is in the process (i hope) to make this internal to blender
with python

http://www.blender.org/modules.php?op=modload&name=phpBB2&file=viewtopic&t=2122

anyone want help him?
ciao
kino

hi,

just had a look at the maxscript this prog generates: in case no one is still investigating this, it should be very easy to parse the maxscript…

After some header info, the file starts with three lines for each frame for the camera: rotation, position and field of view. So the python script would need to parse this out, create the camera, and keyframe it…

After the camera info, there’s one line of co-ordinates for each feature point. You’d just need the script to create an empty for each point… And that’s it as far as I can tell!

I’ve only done really really simple python so far, but from what I’ve seen it couldn’t be too difficult. If someone can point me to tutorials for blender python on how to a) open and read files, and b) use 3x3 rotation matrices I’ll give it a go if you want.

cheers

leon

good :slight_smile:
this is the import script maded by eeshlo for icarus you can look at it

https://blenderartists.org/forum/viewtopic.php?t=3694

hope Voodoo dont take the same commercial way of icarus

ciao
kino

edit : oops cannot download from old site anyone have it in his hd?

edit2: i founded on my archive download from here http://kino3d.com/files/ICARUS_import.zip

strange, thought I posted a reply but it’s not appearing!

thanks for the info: I found the script here and I think it will be a great help…

It’s my first real attempt at python (although not programming in general), so please don’t get your hopes up too much for quick good results! There probably won’t be much in the way of a gui, just put the filename and path in the script and press alt-p I think…

btw, voodoo only handles camera rotation at the moment apparently… I think its still be useful though.

cheers

leon

Hi thank’s , will be a great result even without gui
i’m a linux(only) user :wink: , gui is needed only in some case

thank’s for your effort

kino

hi,

ok, made a little progress (well, seeing as I started Python today, quite a lot really!). So far it just imports the reference points into a mesh (one vertex for each point)… but that’s the easy bit I suppose!

To use just change the “max_script” variable to point to your .ms file and press Alt-P… I’ll have a go at doing the camera and assosciated IPO’s tomorrow…

Please let me know if you have a chance to test! Any advice on coding is welcomed too, as I’m probably doing things the wrong/long way in many cases!

Cheers

leon


########################################
#  Importer for maxscript output       #
#  from Voodoo camera tracker          #
########################################
#    Modify the path / filename        #
#    then ALT-P to start.....          #
########################################
# Almost no error checking I'm afraid! #
# It is entirely possible that your    #
# computer could explode if you run    #
# this script!!!!                      #
########################################

import Blender
from Blender import *
from math import *

#Change the filename below to the name of your maxscript exported from Voodoo
max_file = 'c:\	est\	est2.ms'            

sc = Scene.getCurrent()

# Main code
# Open the file specified in max_file
fp = open(max_file)
dt = fp.read()
fp.close()

source = dt.splitlines()
total_lines = len(source)
no_points = 0
ref_points = []

# Now loop through each line in the file
for i in range(total_lines):
    line = source[i]
    if line[:8] == 'at time ':
        pass
    # Will fix camera creation later on    
    #
    # Now check for points
    if line[:12] == '  point pos:':
        # Parse out the three numbers
        part1 = line.split("[")
        part2 = part1[1].split("]")
        part3 = part2[0].split(",")
        points = [float(part3[0]),float(part3[1]),float(part3[2])]
        ref_points.append(points)
        no_points = no_points + 1  

ref_mesh = NMesh.New()

# Now create the mesh of reference points
for i in range(no_points):
    mypoint = NMesh.Vert(ref_points[i][2],ref_points[i][0]*-1,ref_points[i][1]*-1)
    ref_mesh.verts.append(mypoint)

NMesh.PutRaw(ref_mesh, "Reference points")

Blender.Redraw()

i’ll try soon as possible but the current version of voodoo give me a
Segmentation Fault when i try to load an images sequence :frowning:
i think my suse8.2 is too new why it worked before with 7.3
i write to the author to see if there’s a solution or an updated version

thanks
ciao
kino

hi all,

ok, nearly there! I’ve parsed out the camera info, and set the initial camera location, it’s looking like it’s working…

Now I have to set the camera IPO’s: after reading the forum, it seems that the best way to do this is for the user to create an IPO (just I / loc-rot)before running the script, and then let the script modify the IPO… (since creating and linking an IPO via python apparently crashes blender)

I can’t get the IPO though! My camera object is called c

so the following code:

print c.ipo

produces the output: [Ipo “OBIpo.001”]

But then I want to get the IPO itself: I’ve tried

ob = c.ipo

but that just produces an error (string expected): can anyone enlighten me how I move forward?

Thanks for any help!

cheers

Leon

a quick update:

I had the script working ok for the camera rotations: the idea was that you create an IPO for the camera, then run the script and it adds the IPO keys… this was working fine, but I couldn’t find a way to change or delete the first IPO key from Python…

So I modified the script to add a new IPO instead, which you have to link manually to the camera after running the script. However, now the rotations are all wrong!!! I have no idea why!

Will try to fix after work today, then post the script…

A quick question: can anyone tell me how to calculate the lens value for the camera in Blender, given a certain field of view angle and screen x / y resolution?

cheers

leon

ok, here’s a sort of working script: it gets the initial frame fine, but the rotation drifts off during the animation. If anyone can see why, I’d be much obliged!!!

Field of view isn’t done yet, since I don’t know how to calculate from x and y resolution and field of view value, to blender “lens” value. Just play with the lens value of the camera until you line up with the picture…

to use:

  1. Change the filename and path in line 24 to your .ms file from voodoo.
  2. Run the script with Alt-P
  3. Link the new IPO “Voodooanim” to your camera (select “Voodooanim” in the IPO window, select the camera in the 3-d, press ctrl-L and choose object ipo)

Any testing that anyone can do will be appreciated!

Cheers

leon


###########################################
#  Importer for maxscript output          #
#  from Voodoo camera tracker             #
###########################################
#    1. Modify the path / filename        #
#    2. Create a camera with the correct  #
#       resolution to match your sequence #
#    3. ALT-P to start.....               #
###########################################
# Almost no error checking I'm afraid!    #
# It is entirely possible that your       #
# computer could explode if you run       #
# this script!!!!                         #
###########################################

import Blender
from Blender import *
from math import *

#Global variables
pi = 3.141592654

#Change the filename below to the name of your maxscript exported from Voodoo
max_file = 'c:\	est\	est2.txt'            

sc = Scene.getCurrent()

# Rotation matrix function
def mat2euler(mat):
    angle_y = -asin(max(min(mat[0][2], 1.0), -1.0))
    C = cos(angle_y)
    if C!=0.0: C=1.0/C
    angle_x = atan2(mat[1][2] * C, mat[2][2] * C)
    angle_z = atan2(mat[0][1] * C, mat[0][0] * C)
    return (angle_x, angle_y, angle_z)

# Main code
# Open the file specified in max_file
fp = open(max_file)
dt = fp.read()
fp.close()

source = dt.splitlines()
total_lines = len(source)
no_points = 0
no_frames = 0
cam_positions = []
cam_rotations = []
cam_fov = []
ref_points = []


# Now loop through each line in the file
for i in range(total_lines):
    line = source[i]
    # First of all look for camera animation values
    if line[:8] == 'at time ':
        part1 = line.split("f c.")
        part2 = part1[1].split()
        # Check for positions (although with current voodoo version, only 0,0,0 shown)
        if part2[0] == 'position':
             campos = part2[2].strip("[]")
             camloc = campos.split(",")
             cam_point = [float(camloc[0]), float(camloc[1]), float(camloc[2])]
             cam_positions.append(cam_point)
        # Check for rotation values
        if part2[0] == 'rotation':
             part3 = part2[3].split("][")
             row_1t = part3[0].strip("[]")
             row_2t = part3[1].strip("[]")
             row_3t = part2[4].strip("[]")
             row_1 = row_1t.split(",")
             row_2 = row_2t.split(",")
             row_3 = row_3t.split(",")
             row_1n = [float(row_1[0]),float(row_1[1]),float(row_1[2])]
             row_2n = [float(row_2[0]),float(row_2[1]),float(row_2[2])]
             row_3n = [float(row_3[0]),float(row_3[1]),float(row_3[2])]
             rot_points = []
             rot_points.append(row_1n)
             rot_points.append(row_2n)
             rot_points.append(row_3n)
             cam_rotations.append(rot_points)
             no_frames = no_frames + 1
        # Check for field of view values (although I can't be bothered yet!)
        if part2[0] == 'fov':
             pass
    # Now check for points
    if line[:12] == '  point pos:':
        # Parse out the three numbers
        part1 = line.split("[")
        part2 = part1[1].split("]")
        part3 = part2[0].split(",")
        points = [float(part3[0]),float(part3[1]),float(part3[2])]
        ref_points.append(points)
        no_points = no_points + 1  

# End of parsing code

# Now create the objects in blender

# Use the camera already in the scene, using the very first position and rotation values
c = sc.getCurrentCamera()
c2 = Object.Get (c.name)
a = mat2euler(cam_rotations[0])
c2.RotX = - a[2] - pi/2
c2.RotY = a[0]  
c2.RotZ = - a[1] + pi / 2 

cam_ipo = Ipo.New('Object', 'Voodooanim')
locxc = cam_ipo.addCurve('LocX')
locyc = cam_ipo.addCurve('LocY')
loczc = cam_ipo.addCurve('LocZ')
rotxc = cam_ipo.addCurve('RotX')
rotyc = cam_ipo.addCurve('RotY')
rotzc = cam_ipo.addCurve('RotZ')

for curv_point in range(no_frames):
    cam_euler = mat2euler(cam_rotations[curv_point])
    rot_x = -cam_euler[2] - pi / 2
    rot_y = cam_euler[0]
    rot_z = -cam_euler[1] + pi / 2
    rot_x_deg = rot_x * 180 / pi
    rot_y_deg = rot_y * 180 / pi
    rot_z_deg = rot_z * 180 / pi
    locxc.addBezier((curv_point+1,cam_positions[0][0]))
    locyc.addBezier((curv_point+1,cam_positions[0][1]))
    loczc.addBezier((curv_point+1,cam_positions[0][2]))
    rotxc.addBezier((curv_point+1,rot_x_deg/10))
    rotyc.addBezier((curv_point+1,rot_y_deg/10))
    rotzc.addBezier((curv_point+1,rot_z_deg/10))

# Now create the camera IPO's

# Now create the mesh of reference points
ref_mesh = NMesh.New()
for i in range(no_points):
    mypoint = NMesh.Vert(ref_points[i][2],ref_points[i][0]*-1,ref_points[i][1]*-1)
    ref_mesh.verts.append(mypoint)

NMesh.PutRaw(ref_mesh, "Reference points")
# Now redraw et voila!

Blender.Redraw()

Rotation matrix function

def mat2euler(mat):
angle_y = -asin(max(min(mat[0][2], 1.0), -1.0))
C = cos(angle_y)
if C!=0.0: C=1.0/C
angle_x = atan2(mat[1][2] * C, mat[2][2] * C)
angle_z = atan2(mat[0][1] * C, mat[0][0] * C)
return (angle_x, angle_y, angle_z)

does this mean that when C =0.0 it becomes 1/C ?
with C=0, 1/C becomes infinitly big. maybe this screw your script up.

hi
i think you can look in yablex for the function write by eeshlo

i have no reply from voodoo author :frowning: so i cannot test it
if you want you can send me .ms file and images

ciao
kino

edit: oops reply at the same time with koudejongen

Hi!

Here’s the fov portion from one of my scripts:


def getAspect():
  s = Scene.GetCurrent()
  res = s.getWinSize()
  if res[1] > res[0]: return float(res[0]) / float(res[1])
  else: return 1

def lens2angle(lens):
  return 360.0 * atan(getAspect() * 16.0 / lens) / pi

def angle2lens(angle):
  return getAspect() * 16.0 / (tan(angle * pi / 360))

You may use lens2angle() like this:


s = Scene.GetCurrent()
co = s.getCurrentCamera()
c = co.getData()
print lens2angle(c.lens)

I hope these help!

Bye,

hi,

thanks for the quick replies!

I forgot to mention that I took the mat2euler code from a script by eeshlo (thanks eeshlo!). It gets the first frame ok, so I think it’s fine.

The infinity bit is ok I think: since tan produces infinity at 90 degrees (could be way out here, years since I studied maths!), if you want inverse tan to produce 90 degrees, you need to feed it infinity. I think…!

aersoy: fantastic, thanks very much, it’s just what I’m looking for so I will add it to the code.

kino: no problem… I’m testing with the test images from the voodoo package, so you should have those already. Where should I send the .ms file? It’s ~86k, so can’t post here, and I don’t have any webspace unfortunately.

Cheers

Leon

You are welcome!

If you want it to be hosted, you can mail it to me (dirt at gtk dot org).

Later,

hi aersoy,

thanks: when it’s working I will email it you if you don’t mind!

cheers

leon