Hello list,
I am new to ceres. I am feeling very happy to work with this wonderful library. I am using ceres-solver to optimize camera pose in my project. I have a 2D image and corresponding 3D CAD model. I know the ground truth of the camera pose when the 2D image was acquired. I want the algorithm to converge to give back ground truth values.
I have single image and single calibrated camera. I am keeping all the parameters of the pose constant and just varying the z component of pose. I use some functions from OpenCV library. Could anyone of you please let me know if this definition is correct?
The error function terminates in the first iteration with gradient = 0 and cost change =0, termination: CONVERGENCE
Thanks in advance
//cost function
/Pose = [x y z alpha beta gamma]
struct MyCostFunctor{
MyCostFunctor(cv::Mat _image, Model _model, cv::Mat _cameraMatrix, Pose _pose){
m_image = _image;//2d image
m_model = _model;//3d model
m_cameraMatrix = _cameraMatrix;//intrinsic camera parameters
m_Pose =_pose;//ground truth pose
}
bool operator()(const double* const z, double* residual) const{
double score{};
cv::Mat _shiftedModel = rigidTransform(m_model.m_vertices, m_Pose, *z);//moves the 3d model in image space
cv::Mat _projectedMat = projectTo2d(_shiftedModel, m_cameraMatrix);//projects 3d model onto image space
cv::Mat _imagePatch = generateImagePatch(_shiftedModel, _projectedMat, m_model, drawing);//function to plot the projected model
score = scoreFunction(m_image, _imagePatch);//compares the pixels in the projected image and 2d ground truth image
residual[0] = 11191 - score;//11191 is the number of pixels belonging to the ground truth image, score is the number of pixels belonging to the projected image
return true;
}
cv::Mat m_image;
Model m_model;
cv::Mat m_cameraMatrix;
Pose m_Pose;
};
//Problem definition
// X0 = Pose = [x y z alpha beta gamma]
ceres::Problem problem;
ceres::CostFunction* costFunction = new NumericDiffCostFunction<MyCostFunctor, ceres::CENTRAL,1,1>(new MyCostFunctor(image, model, cameraMatrix, X0));
double pose_z = 9.0;//9.79241;
problem.AddResidualBlock(costFunction, NULL, &pose_z);