Thanks Sameer - very helpful and prompt as always.
Just so I'm clear (as I've never used ProductParametrization)
Currently I do the following for bundle adjustment. The cost blocks are:
4 - Eigen Quaternion
3 - Translation
15 - Camera intrinsics and distortion coefficients
3 - the 3d point
CostFunction* reprojection_cost =
new AutoDiffCostFunction<Camera_Reprojection_Cost, 2, 4, 3, 15, 3>(
new Camera_Reprojection_Cost(left_image_points[j]));
I add each block to fitting_cost_function and then I do :
EigenQuaternionParameterization* quaternion_parameterisation = new EigenQuaternionParameterization;
fitting_cost_function.SetParameterization(&camera_rotation[i][0],
quaternion_parameterisation);
(where i is the ith camera)
I think what you are saying is that I either
i) Combine the 4-block and 3-block into a 7-block (or even a 22-block with the camera coefficients). This has the advantage of being simple, but Ceres loses the information that the 4-block was a quaternion, and so the solution is less constrained, presumably, because it might create quaternions that don't exist.
ii) Use ProductParameterization. In which case I don't know how to locally parameterize the 3-block translation. The docs give the example:
ProductParameterization product_param(new QuaterionionParameterization(), new IdentityParameterization(3));
But I need a 'plain' R^3 for the second term. Is there such a thing? Could you advise as to how I'd produce a ProductParameterization of a quaternion and a 3-vector ?
Finally, even with the simple way I'm currently using (small blocks and no ProductParameterization), do I understand correctly that the runtime might be slower but the final result should be just as good? Or is there a risk of poorer convergence?
Many thanks