Как я могу использовать несколько разных камер в настройках комплекта Ceres? - PullRequest
0 голосов
/ 22 марта 2020

Я пытаюсь использовать пример 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?

...