What is an efficient way to create the cost functor uses all parameters to compute a residual

454 views
Skip to first unread message

Sonia

unread,
Jun 15, 2016, 8:20:53 AM6/15/16
to Ceres Solver
Hello, I am solving a structure from motion problem with constraints.

One of my objective function is

residuals[i] = weight * (  Z[i] - mean( Z[0 : (NCAM-1)] )  )

The parameter block for my problem is [X0, Y0, Z0, roll0, pitch0, yaw0, X1, Y1, Z1, roll1, pitch1, yaw1, X2, Y2, Z2, roll2, pitch2, yaw2, .....]

For this objective function, what I want to compute is the Z values of all cameras (=NCAM); Z[0..NCAM-1].

As the residual of one cameras is dependent on the mean Z values computing from all the cameras. I found that computing one residuals at a time as AutoDiffCostFunction is inefficient.

Can anyone guide me what is the best wey for me to create my cost functor? Is it better to use DynamicAutoDiffCostFunction and if so, how can I convert to DynamicAutoDiffCostFunction?

Thank you very much for any pointer.



My cost functor:

class CHeightError
{
public:
    CHeightError(double _weight, double _nimages, int _camera_id)
    {
        weight = _weight;
        nimages = _nimages;
        camera_id = _camera_id;
    }
   
    template <typename T>
    bool operator() (const T* const heights, T* residuals) const
    {
        // Compute the sum/mean from all camera heights
        T mean_height = T(0.0);
        for (int i = 0; i < nimages; i++)
            mean_height += heights[i*6]; // // x,y,h,roll,ptich,yaw,x,y,h,roll,pitch,yaw : step = 6
        mean_height = mean_height/T(nimages);

        // Compute residual
        residuals[0] = T(_weight) * (height[camera_id] - mean_height);

        return true;
    }

    static ceres::CostFunction* Create(const double _weight, double _nimages, int _camera_id)
    {
        return (new ceres::AutoDiffCostFunction<CHeightError, 1, NIMAGES>(
                    new CHeightError(_weight, _nimages, _camera_id)));
    }

private:
    double weight;
    double nimages;
    int camera_id;
};

---------------
// Initialize camera parameters
// camera_params[NIMAGES * 6] =
//     [x;y;z;roll;pitch;yaw;x;y;z;roll;pitch;yaw;x;y;z;roll;pitch;yaw;]

ceres::Problem problem;

for (icamera = 0; icamera < NIMAGES; icamera++)
{
    ceres::CostFunction * height_cost_function = CHeightError::Create(weight, NIMAGES, icamera);
    problem.AddResidualBlock( height_cost_function, NULL, camera_params);
}

Sonia

unread,
Jun 15, 2016, 8:32:14 AM6/15/16
to Ceres Solver
On problem is that i don't know the number of images (number of parameters -- NIMAGES) in advance.
What's the better way for this, using DymanicAutoDiffCostFunction?, as I know AutoDiffCostFunction will only accept the static value?


    static ceres::CostFunction* Create(const double _weight, double _nimages, int _camera_id)
    {
        return (new ceres::AutoDiffCostFunction<
CHeightError, 1, NIMAGES>(
                    new CHeightError(_weight, _nimages, _camera_id)));
    }

Thank you very much.

Sameer Agarwal

unread,
Jun 15, 2016, 9:05:16 AM6/15/16
to Ceres Solver
Sonia,
If you do not know the number of parameters blocks at compile time, then you will have to use DynamicAutoDiffCostFunction. And since you will have all the Z values available anyways, you can compute all the residuals in the same CostFunctor.


shows how to use DynamicAutoDiffCostFunction.

Sameer


--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/a206e491-5269-4915-9ccb-c1ef3f66a033%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sonia

unread,
Jun 15, 2016, 6:44:12 PM6/15/16
to Ceres Solver
Dr. Sameer,

Thanks very much for your reply.

Sonia
Reply all
Reply to author
Forward
0 new messages