no valid solution and big cost error

585 views
Skip to first unread message

qt next

unread,
Oct 30, 2017, 5:22:25 PM10/30/17
to Ceres Solver
Hi,

I want to find the position and orientation of a Pan Tilt camera when I know several x,y,z target point  (center of the camera) and the corresponding pan,tilt of the camera. We do this with around 10 points. We create a cost function that calculate the two residual error for pan and tilt (calculate from translation, orientation matrix and x,y,z point to estimate the difference of the calculated pan to the readed pan and equivalent for tilt).

We create a LossfunctionWrapper (new Ceres::huberLoss(lossfunctionvalue), ceres::TakeOwnership).

for (int i;countcorrespondancepoint)
{
  ceres::CostFunction *costfunction=new Ceres::AutoDiffCostFunction(....;
problem.addResidualBlock(costfunction,....
problem.setParameterBlockConstant(coord3D);
}

then solve the with Dense_QR solver type, Jacobi preconditionner...

We don't find a good solution at this end and  I have  the following report:
Parameter Blocks : original 17.    reduced 2
Parameters 51.   6
ResidualBlocks (with 15 points).   15.   15
Residual. 30 30 

the initial cost is equal to the final cost 7.8e+03 
I have one iteration  that is successfull and the termination is Convergence (fucntion tolerance reached )
I guess we have a correct lossfunction but it seems something is wrong.

1)- Is it normal to have the initial and final cost ?
2)- is it normal to have parameters blocks that go from 17 to 2 ?
3)- because the coord3 is the original parametre, does it makes senses to make it constant to indicate that this parameter is not to changed and is not the one to evaluate (In fact I need to evaluate 3 translation values and 3 rotation values ?
4)- Is Ceres the good lib to do this ?

thanks 


Keir Mierle

unread,
Oct 31, 2017, 3:36:40 AM10/31/17
to ceres-...@googlegroups.com
Hi,

Can you please paste the FullReport() in its entirety?

What happens when you do not have a loss function? If you only have 10 points, they better be good ones! I suggest trying without the huber loss. Also, the huber loss parameter is quite sensitive since it determines the size of the quadratic bowl. Please make sure it is reasonable.

My suggestion
1. Make Ceres work without the huber loss first. If this means you have to manually pick the residual points to include so they are all inliers, do that.
2. Once that works, you can then consider the huber loss, but to be honest it should be a last resort. Unless you have a huge amount of data and no way to control outlier detection, try to avoid it.
3. For Huber loss, spend time examining the size of the noise for your problem, and make sure the huber parameter is set accordingly.

Another point.
1. If your 3D points are known constant, you do not need to use Ceres to pass them into your cost function. You can just pass them as side data. Then your residual only takes 1 parameter block of size 2 (the pan and tilt). See the simple_bundle_adjuster to see how the (x,y) points are stored in the object. You can do the same for the 3D points.

Thoughts inline:

On Mon, Oct 30, 2017 at 10:22 PM, qt next <qtn...@gmail.com> wrote:
Hi,

I want to find the position and orientation of a Pan Tilt camera when I know several x,y,z target point  (center of the camera) and the corresponding pan,tilt of the camera. We do this with around 10 points. We create a cost function that calculate the two residual error for pan and tilt (calculate from translation, orientation matrix and x,y,z point to estimate the difference of the calculated pan to the readed pan and equivalent for tilt).

We create a LossfunctionWrapper (new Ceres::huberLoss(lossfunctionvalue), ceres::TakeOwnership).

for (int i;countcorrespondancepoint)
{
  ceres::CostFunction *costfunction=new Ceres::AutoDiffCostFunction(....;
problem.addResidualBlock(costfunction,....
problem.setParameterBlockConstant(coord3D);
}

then solve the with Dense_QR solver type, Jacobi preconditionner...

We don't find a good solution at this end and  I have  the following report:
Parameter Blocks : original 17.    reduced 2
Parameters 51.   6
ResidualBlocks (with 15 points).   15.   15
Residual. 30 30 

the initial cost is equal to the final cost 7.8e+03 
I have one iteration  that is successfull and the termination is Convergence (fucntion tolerance reached )
I guess we have a correct lossfunction but it seems something is wrong.

1)- Is it normal to have the initial and final cost ?

I'm not sure what this question is. Yes, the initial and final cost should be reported. Please include a FullReport().
 
2)- is it normal to have parameters blocks that go from 17 to 2 ?

Yes, since you are running SetConstant(). Ceres will remove any parameters that are constant from the optimization. They are passed to the function for evaluation of the cost, but not for the derivatives. Evaluating the derivatives is expensive, so Ceres goes to some lengths to avoid computing them if they are not needed.
 
3)- because the coord3 is the original parametre, does it makes senses to make it constant to indicate that this parameter is not to changed and is not the one to evaluate (In fact I need to evaluate 3 translation values and 3 rotation values ?

Yes. However, another approach (as I mentioned earlier) is to stuff the auxiliary data into the cost function on the side similar to the reprojected point location. If you never plan to optimize the 3D points, you may want to consider doing that (since the 3D points in your case won't ever participate in the optimization).

If you plan to eventually migrate the 3D point to also be optimized, then your current approach is the right one.
 
4)- Is Ceres the good lib to do this ?

Yes, this is the type of problem Ceres is designed for! Though your problem is very small, so you could use other optimizers, but the Ceres LM loop is quite robust and so is a good choice here.

Happy optimizing,
Keir
 

thanks 


--
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+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/a376c4ee-78dc-482f-bc15-9233c456e5f3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

qt next

unread,
Nov 1, 2017, 9:43:35 AM11/1/17
to Ceres Solver
Hi,

thanks for your answer. I am always figthing to find a solution :( 

I ask for the setConstant for 3D points because 3D point and pan/tilt are the input informations. But I don't know if the concept is to considere them constant (3D point & pan/tilt is the same as calibration a camera with 3D / position in camera correspondance )
We have done a lot of change according to your information but it seems that each time to a position near the initial position :( If I enter  initialposition (0,0,0) result position is around (0,0,0), if I enter initial position(100,2,3) result position is around (100,2,3) 


my question is that is it normam that initial a

thanks 


To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

qt next

unread,
Nov 1, 2017, 9:49:52 AM11/1/17
to Ceres Solver

last message was not full :(

Hi,

thanks for your answer. I am always figthing to find a solution :( 

I ask for the setConstant for 3D points because 3D point and pan/tilt are the input informations. But I don't know if the concept is to considere them constant (3D point & pan/tilt is the same as calibration a camera with 3D / position in camera correspondance )
We have done a lot of change according to your information but it seems that each time to a position near the initial position :( If I enter  initialposition (0,0,0) result position is around (0,0,0), if I enter initial position(100,2,3) result position is around (100,2,3) 


my question is that is it normal that initial and final cost is near identical  ? But I guess not .
I guess my calcul is wrong :(

I enter 3D position of a target point and the corresponding Pan/tilt 
I have done both with 3D as a side data  as the example or as a parameter block constant or not.

camrot is the rotation vector and campos is the position of the camera in the world (same world than the target x,y,z point)
struct ResidualErrorFunctorPanTilt
{
    ResidualErrorFunctorPanTilt(double *p2d, double * p3d)
    {
        points2d = p2d;
        points3d = p3d;
    }
    template <typename T>
    bool operator()(const T* const camPos,const T* const camRot,T* out_residuals) const
    {

        T p[3];
        T position3D[3];
        position3D[0]=(T)points3d[0];
        position3D[1]=(T)points3d[1];
        position3D[2]=(T)points3d[2];
        ceres::AngleAxisRotatePoint(camRot,position3D,p);
        p[0] += camPos[0];
        p[1] += camPos[1];
        p[2] += camPos[2];

        T x = p[0];
        T y = p[1];
        T z = p[2];

        T sph[3] = { T(0.0), T(0.0), T(0.0) };
        sph[1]=(x==T(0.0))?T(90.0):(atan(z/x) * 180.0 / M_PI); // pan
        sph[2]=(y==T(0.0))?T(90.0):(atan(sqrt(x * x + z * z)/y) * 180.0 / M_PI); // tilt

        T pan=sph[1]-points2d[0];
        T tilt=sph[2]-points2d[1];

        while(pan>T(180.0)) pan-=T(360.0);
        while(pan<T(-180.0)) pan+=T(360.0);

        while(tilt>T(180.0)) tilt-=T(360.0);
        while(tilt<T(-180.0)) tilt+=T(360.0);

        out_residuals[0] =pan;
        out_residuals[1] = tilt;

        return true;
    }
    double *points2d;
    double * points3d;
};


I guess I don't understand something :(

qt next

unread,
Nov 6, 2017, 5:25:46 PM11/6/17
to Ceres Solver
Hi,

I have corrected most of the issue and it works well but sometimes I have wrong results. For example we have about 15 correspondances (point3D - pan,tilt) . I can have good result with 6 correspondances  I can add more correspondances and it's ok, but If I add one of these correspondances, my camera is 100meter away with bad error results, I add one more correspondance and it's ok... I add a few and it's totally wrong, then I add another and it's ok ..  It's very strange because I guess that all my correspondances are quite good . Do I need to do several times the same solver adding and removing correspondances to find the best result or does the ceres solver remove less good correspondance automatically ? even if it don't remove bad point, in my case It seems after checking that all correspondance are good. 

Thanks :)
Reply all
Reply to author
Forward
0 new messages