Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating custom intrinsic matrices for use in error_fn in AutoDiffCostFunction #644

Open
Unturned3 opened this issue May 14, 2024 · 1 comment

Comments

@Unturned3
Copy link

Unturned3 commented May 14, 2024

❓ Questions and Help

Thanks for this amazing piece of software, first of all!

I am trying to create an error function for use with th.AutoDiffCostFunction to measure the reprojection error from one camera to another, which involves computing a homography matrix in the form of Kj * Rj * Ri.inverse() * Ki.inverse(), where Ki and Ri are the intrinsic matrix and (rotation) pose of a camera respectively.

Ki is parameterized by a single variable: the camera's focal length f, and take the following form (due to some unfortunate coordinate system conventions):

[[-f, 0, 320],
 [ 0, f, 240],
 [ 0, 0,   1]]

I tried the following code for creating the custom Ki:

...

f0 = th.Vector(tensor=torch.tensor([[640]]).float(), name='f0')
f1 = th.Vector(tensor=torch.tensor([[640]]).float(), name='f1')
...

def error_fn(optim_vars: list[th.Variable],
             aux_vars: list[th.Variable]):

    logR0, f0, logR1, f1 = [v.tensor for v in optim_vars]
    src_pts, dst_pts = [v.tensor for v in aux_vars]

    R0 = kornia.geometry.axis_angle_to_rotation_matrix(logR0)
    K0 = torch.zeros(1, 3, 3)
    K0[:, 0, 0] = -f0[:, 0]
    K0[:, 1, 1] = f0[:, 0]
    K0[:, 0, 2] = 320
    K0[:, 1, 2] = 240
    K0[:, 2, 2] = 1

    R1 = ...
    K1 = ...

    H = K1 @ R1 @ R0.inverse() @ K0.inverse()
    return reprojection_error(H, src_pts, dst_pts)

...

cost = th.AutoDiffCostFunction(
    optim_vars=(logR0, f0, logR1, f1),
    err_fn=error_fn,
    dim=N,
    aux_vars=(src_pts, dst_pts),
)

But when I tried to run the optimizer, Theseus gave the following error for the assignment K0[:, 0, 0] = -f0[:, 0]:

vmap: inplace arithmetic(self, *extra_args) is not possible because there exists a 
Tensor `other` in extra_args that has more elements than `self`. This happened 
due to `other` being vmapped over but `self` not being vmapped over in a vmap. 
Please try to use out-of-place operators instead of inplace arithmetic.

It seems that I cannot do in-place operations like assignments. May I ask what is the proper/recommended way to create these custom matrices for use with an error function intended for th.AutoDiffCostFunction?

Thanks!

@Unturned3 Unturned3 changed the title Creating custom intrinsic matrices Creating custom intrinsic matrices for use in error_fn in AutoDiffCostFunction May 14, 2024
@luisenp
Copy link
Contributor

luisenp commented May 28, 2024

Hi @Unturned3. Thanks for your interest in Theseus, and my sincere apologies for the long response time.

I'm not 100% sure, but it's possible that this error is the results of using torch.zeros(1, 3, 3) when creating K0. Inside functions being vmaped, usually the right thing to use is torch.new_zeros(), which vmap knows how to batch with the right dimensions. Does the error happen if you do K0 = torch.new_zeros(3, 3)?

You could also try without vmap, by setting autograd_mode="dense" when creating the autodiff cost function, although I suspect this would be too slow for your use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants