2
$\begingroup$

I'm trying to convert calibration matrix to Blender's camera as the reference document in here: http://ksimek.github.io/2012/08/14/decompose/

It looks Blender camera uses bot-left corner as origin in image space.

Is there a good way to convert this?


Here is my solution.

CAMERA K

    scene = bpy.context.scene
render = bpy.context.scene.render

#----------------------------------------------- 
# view port 

render.engine = 'CYCLES'
render.filepath = '//'
render.resolution_x = imgWidth
render.resolution_y = imgHeight
render.resolution_percentage = 100

scene.cycles.device = 'GPU'

#----------------------------------------------- 
# K 
camdata = bpy.data.cameras.new('cameraData')
camdata.lens_unit = 'FOV'

f = float(K[0,0])
fx = float(K[0,0])
fy = float(K[1,1])
ppx = float(K[0,2])
ppy = float(K[1,2])


maxdim = max(render.resolution_x,render.resolution_y) 

#camdata.angle = 2*math.atan(0.5*maxdim/f)
camdata.angle_x=2*math.atan(0.5*render.resolution_x/fx);
camdata.angle_y=2*math.atan(0.5*render.resolution_y/fy);

# the unit of shiftXY is FOV unit (Lens Shift)
camdata.shift_x = (ppx - render.resolution_x/2.0)/maxdim
camdata.shift_y = (ppy- render.resolution_y/2.0)/maxdim

camdata.dof_distance = 0.0
camdata.clip_end = 1000.0

#-----------------------------------------
# OBJECT TYPE
cam = bpy.data.objects.new('camera', camdata)
#
# flip axis to top-left
cam.scale=(1,-1,-1); 

Extrinsic R|t

Assume all your frame shares using same camera and I add object axis to handle camera rotation. It seems difficult to directly insert R|t matrix into camera object. Also, please note that the initial order of the rotation and location parameter does matter.

    # extrinsic matrix
    all_wrtx,all_fid = top.loadALLWxyzRt(camDIR);


S=bpy.data.scenes['Scene'];
S.frame_start=1;
S.frame_end=len(all_fid);

D = bpy.data

for o in D.objects:
    o.select=False;

D.objects['objRoot'].select=True

for i in range(0,len(all_fid)):

    fid = all_fid[i];

    wxyz=all_wrtx[i][0];
    rt=all_wrtx[i][1];

    S.frame_current=fid;

    # set R
    root.rotation_mode='AXIS_ANGLE';
    root.rotation_axis_angle=(wxyz[0],wxyz[1],wxyz[2],wxyz[3]);

    # set Rt
    root.location=(rt[0],rt[1],rt[2]);

    bpy.ops.anim.keyframe_insert_menu(type='LocRotScale');
$\endgroup$
5
  • $\begingroup$ At the end of the second paragraph there is a link to an article which describes how to convert the camera coordinates to be used with OpenGL. I haven't read it completely, but Blender's camera coordinates are pretty much the same. Have you had a look at that article? $\endgroup$
    – maddin45
    Commented Jun 14, 2014 at 9:29
  • $\begingroup$ Embed camera matrix into OpenGL is easy, because it allows you to directly touch projection matrix. However, this not allowed in the Blender. Also, if you touch the camera data, such as bpy.object.data.matrix_world, Blender would do some underly updating which make this coordinate turning become complicated. $\endgroup$
    – ZXco
    Commented Jun 14, 2014 at 12:07
  • $\begingroup$ @tirth Could you also add your code (including parameters) I'm really curious. $\endgroup$
    – stacker
    Commented Jun 14, 2014 at 18:31
  • $\begingroup$ @stacker the difficulty of this problem as I aware is doing coordinate turning on camera would interfere the extrinsic setting of camera object in Blender. The one solution I found is adding another axis object to simulate camera moving. $\endgroup$
    – ZXco
    Commented Jun 16, 2014 at 0:35
  • 1
    $\begingroup$ @tirth Thanks for sharing your solution, it's perfectly ok to post it as an answer and accept it. $\endgroup$
    – stacker
    Commented Jun 16, 2014 at 5:32

1 Answer 1

1
$\begingroup$

I've only one time used singular value decomposition with OpenCV

As I understand your question manipulating x0, y0 of the camera's intrinsic parameters (as interactivly possible in the 2nd page of your link) is similar to

import bpy

cam = bpy.data.cameras['Camera']
cam.shift_x += .5
cam.shift_y += .5

If this doesn't help you could try to offset the cameras position:

cam = bpy.data.objects['Camera']
cam.location.x = 0.0
cam.location.y = ...
cam.location.z = ...
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .