Я пытаюсь использовать пример libmv ba:
https://github.com/ceres-solver/ceres-solver/blob/master/examples/libmv_bundle_adjuster.cc
Однако у меня есть три камеры, одна из которых имеет другое разрешение, и все из которых матрицы c отличаются от других.
Функция:
void EuclideanBundleCommonIntrinsics(const vector<DataTypes::Marker> &all_markers,
const int bundle_intrinsics,
const int bundle_constraints,
double *camera_intrinsics,
vector<DataTypes::EuclideanCamera> *all_cameras,
vector<DataTypes::EuclideanPoint> *all_points) {
PrintCameraIntrinsics("Original intrinsics: ", camera_intrinsics);
ceres::Problem::Options problem_options;
ceres::Problem problem(problem_options);
// Convert cameras rotations to angle axis and merge with translation
// into single parameter block for maximal minimization speed
//
// Block for minimization has got the following structure:
// <3 elements for angle-axis> <3 elements for translation>
vector<Vec6> all_cameras_R_t =
PackCamerasRotationAndTranslation(all_markers, *all_cameras);
// Parameterization used to restrict camera motion for modal solvers.
ceres::SubsetParameterization *constant_transform_parameterization = NULL;
if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
std::vector<int> constant_translation;
// First three elements are rotation, last three are translation.
constant_translation.push_back(3);
constant_translation.push_back(4);
constant_translation.push_back(5);
constant_transform_parameterization =
new ceres::SubsetParameterization(6, constant_translation);
}
int num_residuals = 0;
bool have_locked_camera = false;
for (int i = 0; i < all_markers.size(); ++i) {
const DataTypes::Marker &marker = all_markers[i];
DataTypes::EuclideanCamera *camera = CameraForImage(all_cameras, marker.image);
DataTypes::EuclideanPoint *point = PointForTrack(all_points, marker.track);
if (camera == NULL || point == NULL) {
continue;
}
// Rotation of camera denoted in angle axis followed with
// camera translaiton.
double *current_camera_R_t = &all_cameras_R_t[camera->image](0);
//Can I add the different intrinsics here?
problem.AddResidualBlock(new ceres::AutoDiffCostFunction<
OpenCVReprojectionError, 2, 8, 6, 3>(
new OpenCVReprojectionError(
marker.x,
marker.y)),
NULL,
camera_intrinsics,
current_camera_R_t,
&point->X(0));
// We lock the first camera to better deal with scene orientation ambiguity.
if (!have_locked_camera) {
problem.SetParameterBlockConstant(current_camera_R_t);
have_locked_camera = true;
}
if (bundle_constraints & BUNDLE_NO_TRANSLATION) {
problem.SetParameterization(current_camera_R_t,
constant_transform_parameterization);
}
num_residuals++;
}
LOG(INFO) << "Number of residuals: " << num_residuals;
if (!num_residuals) {
LOG(INFO) << "Skipping running minimizer with zero residuals";
return;
}
BundleIntrinsicsLogMessage(bundle_intrinsics);
if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) {
// No camera intrinsics are being refined,
// set the whole parameter block as constant for best performance.
problem.SetParameterBlockConstant(camera_intrinsics);
}
else {
// Set the camera intrinsics that are not to be bundled as
// constant using some macro trickery.
std::vector<int> constant_intrinsics;
#define MAYBE_SET_CONSTANT(bundle_enum, offset) \
if (!(bundle_intrinsics & bundle_enum)) { \
constant_intrinsics.push_back(offset); \
}
MAYBE_SET_CONSTANT(BUNDLE_FOCAL_LENGTH, OFFSET_FOCAL_LENGTH);
MAYBE_SET_CONSTANT(BUNDLE_PRINCIPAL_POINT, OFFSET_PRINCIPAL_POINT_X);
MAYBE_SET_CONSTANT(BUNDLE_PRINCIPAL_POINT, OFFSET_PRINCIPAL_POINT_Y);
MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K1, OFFSET_K1);
MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K2, OFFSET_K2);
MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P1, OFFSET_P1);
MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P2, OFFSET_P2);
#undef MAYBE_SET_CONSTANT
// Always set K3 constant, it's not used at the moment.
constant_intrinsics.push_back(OFFSET_K3);
ceres::SubsetParameterization *subset_parameterization =
new ceres::SubsetParameterization(8, constant_intrinsics);
problem.SetParameterization(camera_intrinsics, subset_parameterization);
}
// Configure the solver.
ceres::Solver::Options options;
options.use_nonmonotonic_steps = true;
options.preconditioner_type = ceres::SCHUR_JACOBI;
options.linear_solver_type = ceres::ITERATIVE_SCHUR;
options.use_inner_iterations = true;
options.max_num_iterations = 100;
options.minimizer_progress_to_stdout = true;
// Solve!
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
std::cout << "Final report:\n" << summary.FullReport();
// Copy rotations and translations back.
UnpackCamerasRotationAndTranslation(all_markers,
all_cameras_R_t,
all_cameras);
PrintCameraIntrinsics("Final intrinsics: ", camera_intrinsics);
}
Предполагается, что для всех видов используется одна и та же встроенная функция / камера.
Есть Есть ли пример Ceres для настройки комплекта нескольких камер, в котором используются разные характеристики?
Если нет, что мне нужно изменить, чтобы использовать три разные камеры для настройки комплекта в Ceres?