| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include <fcntl.h> |
|
|
| #include <cstdio> |
| #include <sstream> |
| #include <string> |
| #include <vector> |
|
|
| #ifdef _MSC_VER |
| #include <io.h> |
| #define open _open |
| #define close _close |
| typedef unsigned __int32 uint32_t; |
| #else |
| #include <unistd.h> |
|
|
| #include <cstdint> |
|
|
| |
| |
| #define O_BINARY 0 |
|
|
| #endif |
|
|
| #include "ceres/ceres.h" |
| #include "ceres/rotation.h" |
| #include "gflags/gflags.h" |
| #include "glog/logging.h" |
|
|
| using Mat3 = Eigen::Matrix<double, 3, 3>; |
| using Vec6 = Eigen::Matrix<double, 6, 1>; |
| using Vec3 = Eigen::Vector3d; |
| using Vec4 = Eigen::Vector4d; |
|
|
| using std::vector; |
|
|
| DEFINE_string(input, "", "Input File name"); |
| DEFINE_string(refine_intrinsics, |
| "", |
| "Camera intrinsics to be refined. Options are: none, radial."); |
|
|
| namespace { |
|
|
| |
| |
| |
| |
| |
| |
| struct EuclideanCamera { |
| EuclideanCamera() = default; |
| EuclideanCamera(const EuclideanCamera& c) = default; |
|
|
| int image{-1}; |
| Mat3 R; |
| Vec3 t; |
| }; |
|
|
| |
| |
| |
| |
| struct EuclideanPoint { |
| EuclideanPoint() = default; |
| EuclideanPoint(const EuclideanPoint& p) = default; |
| int track{-1}; |
| Vec3 X; |
| }; |
|
|
| |
| |
| |
| |
| |
| struct Marker { |
| int image; |
| int track; |
| double x, y; |
| }; |
|
|
| |
| |
| |
| |
| enum BundleIntrinsics { |
| BUNDLE_NO_INTRINSICS = 0, |
| BUNDLE_FOCAL_LENGTH = 1, |
| BUNDLE_PRINCIPAL_POINT = 2, |
| BUNDLE_RADIAL_K1 = 4, |
| BUNDLE_RADIAL_K2 = 8, |
| BUNDLE_RADIAL = 12, |
| BUNDLE_TANGENTIAL_P1 = 16, |
| BUNDLE_TANGENTIAL_P2 = 32, |
| BUNDLE_TANGENTIAL = 48, |
| }; |
|
|
| |
| |
| |
| enum BundleConstraints { |
| BUNDLE_NO_CONSTRAINTS = 0, |
| BUNDLE_NO_TRANSLATION = 1, |
| }; |
|
|
| |
| |
| enum { |
| OFFSET_FOCAL_LENGTH, |
| OFFSET_PRINCIPAL_POINT_X, |
| OFFSET_PRINCIPAL_POINT_Y, |
| OFFSET_K1, |
| OFFSET_K2, |
| OFFSET_K3, |
| OFFSET_P1, |
| OFFSET_P2, |
| }; |
|
|
| |
| EuclideanCamera* CameraForImage(vector<EuclideanCamera>* all_cameras, |
| const int image) { |
| if (image < 0 || image >= all_cameras->size()) { |
| return nullptr; |
| } |
| EuclideanCamera* camera = &(*all_cameras)[image]; |
| if (camera->image == -1) { |
| return nullptr; |
| } |
| return camera; |
| } |
|
|
| const EuclideanCamera* CameraForImage( |
| const vector<EuclideanCamera>& all_cameras, const int image) { |
| if (image < 0 || image >= all_cameras.size()) { |
| return nullptr; |
| } |
| const EuclideanCamera* camera = &all_cameras[image]; |
| if (camera->image == -1) { |
| return nullptr; |
| } |
| return camera; |
| } |
|
|
| |
| int MaxImage(const vector<Marker>& all_markers) { |
| if (all_markers.size() == 0) { |
| return -1; |
| } |
|
|
| int max_image = all_markers[0].image; |
| for (int i = 1; i < all_markers.size(); i++) { |
| max_image = std::max(max_image, all_markers[i].image); |
| } |
| return max_image; |
| } |
|
|
| |
| EuclideanPoint* PointForTrack(vector<EuclideanPoint>* all_points, |
| const int track) { |
| if (track < 0 || track >= all_points->size()) { |
| return nullptr; |
| } |
| EuclideanPoint* point = &(*all_points)[track]; |
| if (point->track == -1) { |
| return nullptr; |
| } |
| return point; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| class EndianAwareFileReader { |
| public: |
| EndianAwareFileReader() { |
| |
| union { |
| unsigned char bytes[4]; |
| uint32_t value; |
| } endian_test = {{0, 1, 2, 3}}; |
| host_endian_type_ = endian_test.value; |
| file_endian_type_ = host_endian_type_; |
| } |
|
|
| ~EndianAwareFileReader() { |
| if (file_descriptor_ > 0) { |
| close(file_descriptor_); |
| } |
| } |
|
|
| bool OpenFile(const std::string& file_name) { |
| file_descriptor_ = open(file_name.c_str(), O_RDONLY | O_BINARY); |
| if (file_descriptor_ < 0) { |
| return false; |
| } |
| |
| auto file_endian_type_flag = Read<unsigned char>(); |
| if (file_endian_type_flag == 'V') { |
| file_endian_type_ = kBigEndian; |
| } else if (file_endian_type_flag == 'v') { |
| file_endian_type_ = kLittleEndian; |
| } else { |
| LOG(FATAL) << "Problem file is stored in unknown endian type."; |
| } |
| return true; |
| } |
|
|
| |
| template <typename T> |
| T Read() const { |
| T value; |
| CHECK_GT(read(file_descriptor_, &value, sizeof(value)), 0); |
| |
| |
| if (file_endian_type_ != host_endian_type_) { |
| value = SwitchEndian<T>(value); |
| } |
| return value; |
| } |
|
|
| private: |
| static constexpr long int kLittleEndian = 0x03020100ul; |
| static constexpr long int kBigEndian = 0x00010203ul; |
|
|
| |
| template <typename T> |
| T SwitchEndian(const T value) const { |
| if (sizeof(T) == 4) { |
| auto temp_value = static_cast<unsigned int>(value); |
| |
| return ((temp_value >> 24)) | |
| ((temp_value << 8) & 0x00ff0000) | |
| ((temp_value >> 8) & 0x0000ff00) | |
| ((temp_value << 24)); |
| |
| } else if (sizeof(T) == 1) { |
| return value; |
| } else { |
| LOG(FATAL) << "Entered non-implemented part of endian " |
| "switching function."; |
| } |
| } |
|
|
| int host_endian_type_; |
| int file_endian_type_; |
| int file_descriptor_{-1}; |
| }; |
|
|
| |
| void ReadMatrix3x3(const EndianAwareFileReader& file_reader, Mat3* matrix) { |
| for (int i = 0; i < 9; i++) { |
| (*matrix)(i % 3, i / 3) = file_reader.Read<float>(); |
| } |
| } |
|
|
| |
| void ReadVector3(const EndianAwareFileReader& file_reader, Vec3* vector) { |
| for (int i = 0; i < 3; i++) { |
| (*vector)(i) = file_reader.Read<float>(); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bool ReadProblemFromFile(const std::string& file_name, |
| double camera_intrinsics[8], |
| vector<EuclideanCamera>* all_cameras, |
| vector<EuclideanPoint>* all_points, |
| bool* is_image_space, |
| vector<Marker>* all_markers) { |
| EndianAwareFileReader file_reader; |
| if (!file_reader.OpenFile(file_name)) { |
| return false; |
| } |
|
|
| |
| auto is_image_space_flag = file_reader.Read<unsigned char>(); |
| if (is_image_space_flag == 'P') { |
| *is_image_space = true; |
| } else if (is_image_space_flag == 'N') { |
| *is_image_space = false; |
| } else { |
| LOG(FATAL) << "Problem file contains markers stored in unknown space."; |
| } |
|
|
| |
| for (int i = 0; i < 8; i++) { |
| camera_intrinsics[i] = file_reader.Read<float>(); |
| } |
|
|
| |
| int number_of_cameras = file_reader.Read<int>(); |
| for (int i = 0; i < number_of_cameras; i++) { |
| EuclideanCamera camera; |
|
|
| camera.image = file_reader.Read<int>(); |
| ReadMatrix3x3(file_reader, &camera.R); |
| ReadVector3(file_reader, &camera.t); |
|
|
| if (camera.image >= all_cameras->size()) { |
| all_cameras->resize(camera.image + 1); |
| } |
|
|
| (*all_cameras)[camera.image].image = camera.image; |
| (*all_cameras)[camera.image].R = camera.R; |
| (*all_cameras)[camera.image].t = camera.t; |
| } |
|
|
| LOG(INFO) << "Read " << number_of_cameras << " cameras."; |
|
|
| |
| int number_of_points = file_reader.Read<int>(); |
| for (int i = 0; i < number_of_points; i++) { |
| EuclideanPoint point; |
|
|
| point.track = file_reader.Read<int>(); |
| ReadVector3(file_reader, &point.X); |
|
|
| if (point.track >= all_points->size()) { |
| all_points->resize(point.track + 1); |
| } |
|
|
| (*all_points)[point.track].track = point.track; |
| (*all_points)[point.track].X = point.X; |
| } |
|
|
| LOG(INFO) << "Read " << number_of_points << " points."; |
|
|
| |
| int number_of_markers = file_reader.Read<int>(); |
| for (int i = 0; i < number_of_markers; i++) { |
| Marker marker; |
|
|
| marker.image = file_reader.Read<int>(); |
| marker.track = file_reader.Read<int>(); |
| marker.x = file_reader.Read<float>(); |
| marker.y = file_reader.Read<float>(); |
|
|
| all_markers->push_back(marker); |
| } |
|
|
| LOG(INFO) << "Read " << number_of_markers << " markers."; |
|
|
| return true; |
| } |
|
|
| |
| |
| |
| |
| template <typename T> |
| inline void ApplyRadialDistortionCameraIntrinsics(const T& focal_length_x, |
| const T& focal_length_y, |
| const T& principal_point_x, |
| const T& principal_point_y, |
| const T& k1, |
| const T& k2, |
| const T& k3, |
| const T& p1, |
| const T& p2, |
| const T& normalized_x, |
| const T& normalized_y, |
| T* image_x, |
| T* image_y) { |
| T x = normalized_x; |
| T y = normalized_y; |
|
|
| |
| T r2 = x * x + y * y; |
| T r4 = r2 * r2; |
| T r6 = r4 * r2; |
| T r_coeff = 1.0 + k1 * r2 + k2 * r4 + k3 * r6; |
| T xd = x * r_coeff + 2.0 * p1 * x * y + p2 * (r2 + 2.0 * x * x); |
| T yd = y * r_coeff + 2.0 * p2 * x * y + p1 * (r2 + 2.0 * y * y); |
|
|
| |
| *image_x = focal_length_x * xd + principal_point_x; |
| *image_y = focal_length_y * yd + principal_point_y; |
| } |
|
|
| |
| |
| |
| |
| |
| struct OpenCVReprojectionError { |
| OpenCVReprojectionError(const double observed_x, const double observed_y) |
| : observed_x(observed_x), observed_y(observed_y) {} |
|
|
| template <typename T> |
| bool operator()(const T* const intrinsics, |
| const T* const R_t, |
| |
| const T* const X, |
| T* residuals) const { |
| |
| const T& focal_length = intrinsics[OFFSET_FOCAL_LENGTH]; |
| const T& principal_point_x = intrinsics[OFFSET_PRINCIPAL_POINT_X]; |
| const T& principal_point_y = intrinsics[OFFSET_PRINCIPAL_POINT_Y]; |
| const T& k1 = intrinsics[OFFSET_K1]; |
| const T& k2 = intrinsics[OFFSET_K2]; |
| const T& k3 = intrinsics[OFFSET_K3]; |
| const T& p1 = intrinsics[OFFSET_P1]; |
| const T& p2 = intrinsics[OFFSET_P2]; |
|
|
| |
| T x[3]; |
|
|
| ceres::AngleAxisRotatePoint(R_t, X, x); |
| x[0] += R_t[3]; |
| x[1] += R_t[4]; |
| x[2] += R_t[5]; |
|
|
| |
| T xn = x[0] / x[2]; |
| T yn = x[1] / x[2]; |
|
|
| T predicted_x, predicted_y; |
|
|
| |
| |
| |
| ApplyRadialDistortionCameraIntrinsics(focal_length, |
| focal_length, |
| principal_point_x, |
| principal_point_y, |
| k1, |
| k2, |
| k3, |
| p1, |
| p2, |
| xn, |
| yn, |
| &predicted_x, |
| &predicted_y); |
|
|
| |
| residuals[0] = predicted_x - observed_x; |
| residuals[1] = predicted_y - observed_y; |
|
|
| return true; |
| } |
|
|
| const double observed_x; |
| const double observed_y; |
| }; |
|
|
| |
| void BundleIntrinsicsLogMessage(const int bundle_intrinsics) { |
| if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) { |
| LOG(INFO) << "Bundling only camera positions."; |
| } else { |
| std::string bundling_message = ""; |
|
|
| #define APPEND_BUNDLING_INTRINSICS(name, flag) \ |
| if (bundle_intrinsics & flag) { \ |
| if (!bundling_message.empty()) { \ |
| bundling_message += ", "; \ |
| } \ |
| bundling_message += name; \ |
| } \ |
| (void)0 |
|
|
| APPEND_BUNDLING_INTRINSICS("f", BUNDLE_FOCAL_LENGTH); |
| APPEND_BUNDLING_INTRINSICS("px, py", BUNDLE_PRINCIPAL_POINT); |
| APPEND_BUNDLING_INTRINSICS("k1", BUNDLE_RADIAL_K1); |
| APPEND_BUNDLING_INTRINSICS("k2", BUNDLE_RADIAL_K2); |
| APPEND_BUNDLING_INTRINSICS("p1", BUNDLE_TANGENTIAL_P1); |
| APPEND_BUNDLING_INTRINSICS("p2", BUNDLE_TANGENTIAL_P2); |
|
|
| LOG(INFO) << "Bundling " << bundling_message << "."; |
| } |
| } |
|
|
| |
| void PrintCameraIntrinsics(const char* text, const double* camera_intrinsics) { |
| std::ostringstream intrinsics_output; |
|
|
| intrinsics_output << "f=" << camera_intrinsics[OFFSET_FOCAL_LENGTH]; |
|
|
| intrinsics_output << " cx=" << camera_intrinsics[OFFSET_PRINCIPAL_POINT_X] |
| << " cy=" << camera_intrinsics[OFFSET_PRINCIPAL_POINT_Y]; |
|
|
| #define APPEND_DISTORTION_COEFFICIENT(name, offset) \ |
| { \ |
| if (camera_intrinsics[offset] != 0.0) { \ |
| intrinsics_output << " " name "=" << camera_intrinsics[offset]; \ |
| } \ |
| } \ |
| (void)0 |
|
|
| APPEND_DISTORTION_COEFFICIENT("k1", OFFSET_K1); |
| APPEND_DISTORTION_COEFFICIENT("k2", OFFSET_K2); |
| APPEND_DISTORTION_COEFFICIENT("k3", OFFSET_K3); |
| APPEND_DISTORTION_COEFFICIENT("p1", OFFSET_P1); |
| APPEND_DISTORTION_COEFFICIENT("p2", OFFSET_P2); |
|
|
| #undef APPEND_DISTORTION_COEFFICIENT |
|
|
| LOG(INFO) << text << intrinsics_output.str(); |
| } |
|
|
| |
| |
| |
| |
| |
| vector<Vec6> PackCamerasRotationAndTranslation( |
| const vector<Marker>& all_markers, |
| const vector<EuclideanCamera>& all_cameras) { |
| vector<Vec6> all_cameras_R_t; |
| int max_image = MaxImage(all_markers); |
|
|
| all_cameras_R_t.resize(max_image + 1); |
|
|
| for (int i = 0; i <= max_image; i++) { |
| const EuclideanCamera* camera = CameraForImage(all_cameras, i); |
|
|
| if (!camera) { |
| continue; |
| } |
|
|
| ceres::RotationMatrixToAngleAxis(&camera->R(0, 0), &all_cameras_R_t[i](0)); |
| all_cameras_R_t[i].tail<3>() = camera->t; |
| } |
|
|
| return all_cameras_R_t; |
| } |
|
|
| |
| void UnpackCamerasRotationAndTranslation(const vector<Marker>& all_markers, |
| const vector<Vec6>& all_cameras_R_t, |
| vector<EuclideanCamera>* all_cameras) { |
| int max_image = MaxImage(all_markers); |
|
|
| for (int i = 0; i <= max_image; i++) { |
| EuclideanCamera* camera = CameraForImage(all_cameras, i); |
|
|
| if (!camera) { |
| continue; |
| } |
|
|
| ceres::AngleAxisToRotationMatrix(&all_cameras_R_t[i](0), &camera->R(0, 0)); |
| camera->t = all_cameras_R_t[i].tail<3>(); |
| } |
| } |
|
|
| void EuclideanBundleCommonIntrinsics(const vector<Marker>& all_markers, |
| const int bundle_intrinsics, |
| const int bundle_constraints, |
| double* camera_intrinsics, |
| vector<EuclideanCamera>* all_cameras, |
| vector<EuclideanPoint>* all_points) { |
| PrintCameraIntrinsics("Original intrinsics: ", camera_intrinsics); |
|
|
| ceres::Problem::Options problem_options; |
| problem_options.cost_function_ownership = ceres::DO_NOT_TAKE_OWNERSHIP; |
| ceres::Problem problem(problem_options); |
|
|
| |
| |
| |
| |
| |
| vector<Vec6> all_cameras_R_t = |
| PackCamerasRotationAndTranslation(all_markers, *all_cameras); |
|
|
| |
| ceres::SubsetManifold* constant_transform_manifold = nullptr; |
| if (bundle_constraints & BUNDLE_NO_TRANSLATION) { |
| std::vector<int> constant_translation; |
|
|
| |
| constant_translation.push_back(3); |
| constant_translation.push_back(4); |
| constant_translation.push_back(5); |
|
|
| constant_transform_manifold = |
| new ceres::SubsetManifold(6, constant_translation); |
| } |
|
|
| std::vector<OpenCVReprojectionError> errors; |
| std::vector<ceres::AutoDiffCostFunction<OpenCVReprojectionError, 2, 8, 6, 3>> |
| costFunctions; |
| errors.reserve(all_markers.size()); |
| costFunctions.reserve(all_markers.size()); |
|
|
| int num_residuals = 0; |
| bool have_locked_camera = false; |
| for (const auto& marker : all_markers) { |
| EuclideanCamera* camera = CameraForImage(all_cameras, marker.image); |
| EuclideanPoint* point = PointForTrack(all_points, marker.track); |
| if (camera == nullptr || point == nullptr) { |
| continue; |
| } |
|
|
| |
| |
| double* current_camera_R_t = &all_cameras_R_t[camera->image](0); |
|
|
| errors.emplace_back(marker.x, marker.y); |
| costFunctions.emplace_back(&errors.back(), ceres::DO_NOT_TAKE_OWNERSHIP); |
|
|
| problem.AddResidualBlock(&costFunctions.back(), |
| nullptr, |
| camera_intrinsics, |
| current_camera_R_t, |
| &point->X(0)); |
|
|
| |
| if (!have_locked_camera) { |
| problem.SetParameterBlockConstant(current_camera_R_t); |
| have_locked_camera = true; |
| } |
|
|
| if (bundle_constraints & BUNDLE_NO_TRANSLATION) { |
| problem.SetManifold(current_camera_R_t, constant_transform_manifold); |
| } |
|
|
| 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) { |
| |
| |
| problem.SetParameterBlockConstant(camera_intrinsics); |
| } else { |
| |
| |
|
|
| 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 |
|
|
| |
| constant_intrinsics.push_back(OFFSET_K3); |
|
|
| auto* subset_manifold = new ceres::SubsetManifold(8, constant_intrinsics); |
| problem.SetManifold(camera_intrinsics, subset_manifold); |
| } |
|
|
| |
| 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; |
|
|
| |
| ceres::Solver::Summary summary; |
| ceres::Solve(options, &problem, &summary); |
|
|
| std::cout << "Final report:\n" << summary.FullReport(); |
|
|
| |
| UnpackCamerasRotationAndTranslation( |
| all_markers, all_cameras_R_t, all_cameras); |
|
|
| PrintCameraIntrinsics("Final intrinsics: ", camera_intrinsics); |
| } |
| } |
|
|
| int main(int argc, char** argv) { |
| GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true); |
| google::InitGoogleLogging(argv[0]); |
|
|
| if (CERES_GET_FLAG(FLAGS_input).empty()) { |
| LOG(ERROR) << "Usage: libmv_bundle_adjuster --input=blender_problem"; |
| return EXIT_FAILURE; |
| } |
|
|
| double camera_intrinsics[8]; |
| vector<EuclideanCamera> all_cameras; |
| vector<EuclideanPoint> all_points; |
| bool is_image_space; |
| vector<Marker> all_markers; |
|
|
| if (!ReadProblemFromFile(CERES_GET_FLAG(FLAGS_input), |
| camera_intrinsics, |
| &all_cameras, |
| &all_points, |
| &is_image_space, |
| &all_markers)) { |
| LOG(ERROR) << "Error reading problem file"; |
| return EXIT_FAILURE; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int bundle_intrinsics = BUNDLE_NO_INTRINSICS; |
| if (CERES_GET_FLAG(FLAGS_refine_intrinsics).empty()) { |
| if (is_image_space) { |
| bundle_intrinsics = BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL; |
| } |
| } else { |
| if (CERES_GET_FLAG(FLAGS_refine_intrinsics) == "radial") { |
| bundle_intrinsics = BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL; |
| } else if (CERES_GET_FLAG(FLAGS_refine_intrinsics) != "none") { |
| LOG(ERROR) << "Unsupported value for refine-intrinsics"; |
| return EXIT_FAILURE; |
| } |
| } |
|
|
| |
| EuclideanBundleCommonIntrinsics(all_markers, |
| bundle_intrinsics, |
| BUNDLE_NO_CONSTRAINTS, |
| camera_intrinsics, |
| &all_cameras, |
| &all_points); |
|
|
| return EXIT_SUCCESS; |
| } |
|
|