简体   繁体   中英

Ceres solver number of parameters question

I write a functor like this:

class Functor
{
...
    static CostFunction* create()
    {
        return new AutoDiffCostFunction<Functor, N_RES, N_PARAMS>(new Functor()); 
    }
...
}

I call it like:

std::vector<double> params(N_PARAMS, 0);
CostFunction* costFunc = Functor::create();
problem.AddResidualBlock(costFunc, nullptr, params.data());

It's weird that this does not work when N_PARAMS=236 , but works for other like 6 , 237 (I tried). The error message is Segement Fault. And I used Ceres Solver before, and never met such problem.

Is there any limit for the number of parameters in Ceres Solver?

=========================================update=================== I write like this:

class ReprojError {
public:            
    ReprojError(
        const std::vector<std::vector<Eigen::Vector3d>>& pt2d,
        const std::vector<Eigen::Matrix<double, 3, 4>>& vmProjs) : 
        m_pt2d(pt2d), m_vmProjs(vmProjs) { }
    
    template<typename _Tp>
    bool operator () (const _Tp* const pts, _Tp* aResiduals) const 
    {
        for(int i = 0; i < 24; ++i)
        {
            std::cout << "?" << std::endl;
            if(m_pt2d[i].empty())
            {
                for(int j = 0; j < 276; ++j)
                {
                    aResiduals[i * 276 * 2 + j * 2] = _Tp(0);
                    aResiduals[i * 276 * 2 + j * 2 + 1] = _Tp(0);
                }
            }
            else
            {
                auto proj = m_vmProjs[i];
                 for(int j = 0; j < 276; ++j)
                {
                    auto X = pts[j * 3];
                    auto Y = pts[j * 3 + 1];
                    auto Z = pts[j * 3 + 2];

                    auto newX = (_Tp)proj(0, 0) * X + (_Tp)proj(0, 1) * Y + (_Tp)proj(0, 2) * Z + (_Tp)proj(0, 3);
                    auto newY = (_Tp)proj(1, 0) * X + (_Tp)proj(1, 1) * Y + (_Tp)proj(1, 2) * Z + (_Tp)proj(1, 3);
                    auto newZ = (_Tp)proj(2, 0) * X + (_Tp)proj(2, 1) * Y + (_Tp)proj(2, 2) * Z + (_Tp)proj(2, 3);
                    
                    aResiduals[i * 276 * 2 + j * 2] = newX / newZ - m_pt2d[i][j](0);
                    aResiduals[i * 276 * 2 + j * 2 + 1] = newY / newZ - m_pt2d[i][j](1);
                }               
            }
        }

        return true;
    }

    static ceres::CostFunction* create(
        const std::vector<std::vector<Eigen::Vector3d>>& pt2d,
        const std::vector<Eigen::Matrix<double, 3, 4>>& vmProjs) 
    {
        return (new ceres::AutoDiffCostFunction<ReprojError, 24 * 2 * 276, 276 * 3>(
            new ReprojError(pt2d, vmProjs)));
    }

private:
    const std::vector<std::vector<Eigen::Vector3d>>& m_pt2d;
    const std::vector<Eigen::Matrix<double, 3, 4>>& m_vmProjs;

public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

and has define:

EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector3d)
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix<double, 3, 4>)

And '?' didn't output, which means the operator() wasn't be executed.

There is no such parameter limit. It would be helpful to compile the code in debug mode to see what is going on.

That said, why are you putting all this in a single costfunction, why not have a cost function for each observation?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM