// Copyright (c) 2013 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
// Author: mierle@gmail.com (Keir Mierle)
//         sergey.vfx@gmail.com (Sergey Sharybin)
//
// This is an example application which contains bundle adjustment code used
// in the Libmv library and Blender. It reads problems from files passed via
// the command line and runs the bundle adjuster on the problem.
//
// File with problem a binary file, for which it is crucial to know in which
// order bytes of float values are stored in. This information is provided
// by a single character in the beginning of the file. There're two possible
// values of this byte:
//  - V, which means values in the file are stored with big endian type
//  - v, which means values in the file are stored with little endian type
//
// The rest of the file contains data in the following order:
//   - Space in which markers' coordinates are stored in
//   - Camera intrinsics
//   - Number of cameras
//   - Cameras
//   - Number of 3D points
//   - 3D points
//   - Number of markers
//   - Markers
//
// Markers' space could either be normalized or image (pixels). This is defined
// by the single character in the file. P means markers in the file is in image
// space, and N means markers are in normalized space.
//
// Camera intrinsics are 8 described by 8 float 8.
// This values goes in the following order:
//
//   - Focal length, principal point X, principal point Y, k1, k2, k3, p1, p2
//
// Every camera is described by:
//
//   - Image for which camera belongs to (single 4 bytes integer value).
//   - Column-major camera rotation matrix, 9 float values.
//   - Camera translation, 3-component vector of float values.
//
// Image number shall be greater or equal to zero. Order of cameras does not
// matter and gaps are possible.
//
// Every 3D point is decribed by:
//
//  - Track number point belongs to (single 4 bytes integer value).
//  - 3D position vector, 3-component vector of float values.
//
// Track number shall be greater or equal to zero. Order of tracks does not
// matter and gaps are possible.
//
// Finally every marker is described by:
//
//  - Image marker belongs to single 4 bytes integer value).
//  - Track marker belongs to single 4 bytes integer value).
//  - 2D marker position vector, (two float values).
//
// Marker's space is used a default value for refine_intrinsics command line
// flag. This means if there's no refine_intrinsics flag passed via command
// line, camera intrinsics will be refined if markers in the problem are
// stored in image space and camera intrinsics will not be refined if markers
// are in normalized space.
//
// Passing refine_intrinsics command line flag defines explicitly whether
// refinement of intrinsics will happen. Currently, only none and all
// intrinsics refinement is supported.
//
// There're existing problem files dumped from blender stored in folder
// ../data/libmv-ba-problems.

#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 <stdint.h>
#include <unistd.h>

// O_BINARY is not defined on unix like platforms, as there is no
// difference between binary and text files.
#define O_BINARY 0

#endif

#include "ceres/ceres.h"
#include "ceres/rotation.h"
#include "gflags/gflags.h"
#include "glog/logging.h"

typedef Eigen::Matrix<double, 3, 3> Mat3;
typedef Eigen::Matrix<double, 6, 1> Vec6;
typedef Eigen::Vector3d Vec3;
typedef Eigen::Vector4d Vec4;

using std::vector;

DEFINE_string(input, "", "Input File name");
DEFINE_string(refine_intrinsics,
              "",
              "Camera intrinsics to be refined. Options are: none, radial.");

namespace {

// A EuclideanCamera is the location and rotation of the camera
// viewing an image.
//
// image identifies which image this camera represents.
// R is a 3x3 matrix representing the rotation of the camera.
// t is a translation vector representing its positions.
struct EuclideanCamera {
  EuclideanCamera() : image(-1) {}
  EuclideanCamera(const EuclideanCamera& c) : image(c.image), R(c.R), t(c.t) {}

  int image;
  Mat3 R;
  Vec3 t;
};

// A Point is the 3D location of a track.
//
// track identifies which track this point corresponds to.
// X represents the 3D position of the track.
struct EuclideanPoint {
  EuclideanPoint() : track(-1) {}
  EuclideanPoint(const EuclideanPoint& p) : track(p.track), X(p.X) {}
  int track;
  Vec3 X;
};

// A Marker is the 2D location of a tracked point in an image.
//
// x and y is the position of the marker in pixels from the top left corner
// in the image identified by an image. All markers for to the same target
// form a track identified by a common track number.
struct Marker {
  int image;
  int track;
  double x, y;
};

// Cameras intrinsics to be bundled.
//
// BUNDLE_RADIAL actually implies bundling of k1 and k2 coefficients only,
// no bundling of k3 is possible at this moment.
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,
};

// Denotes which blocks to keep constant during bundling.
// For example it is useful to keep camera translations constant
// when bundling tripod motions.
enum BundleConstraints {
  BUNDLE_NO_CONSTRAINTS = 0,
  BUNDLE_NO_TRANSLATION = 1,
};

// The intrinsics need to get combined into a single parameter block; use these
// enums to index instead of numeric constants.
enum {
  OFFSET_FOCAL_LENGTH,
  OFFSET_PRINCIPAL_POINT_X,
  OFFSET_PRINCIPAL_POINT_Y,
  OFFSET_K1,
  OFFSET_K2,
  OFFSET_K3,
  OFFSET_P1,
  OFFSET_P2,
};

// Returns a pointer to the camera corresponding to a image.
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;
}

// Returns maximal image number at which marker exists.
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;
}

// Returns a pointer to the point corresponding to a track.
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;
}

// Reader of binary file which makes sure possibly needed endian
// conversion happens when loading values like floats and integers.
//
// File's endian type is reading from a first character of file, which
// could either be V for big endian or v for little endian.  This
// means you need to design file format assuming first character
// denotes file endianness in this way.
class EndianAwareFileReader {
 public:
  EndianAwareFileReader(void) : file_descriptor_(-1) {
    // Get an endian type of the host machine.
    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(void) {
    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;
    }
    // Get an endian tpye of data in the file.
    unsigned char 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;
  }

  // Read value from the file, will switch endian if needed.
  template <typename T>
  T Read(void) const {
    T value;
    CHECK_GT(read(file_descriptor_, &value, sizeof(value)), 0);
    // Switch endian type if file contains data in different type
    // that current machine.
    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;

  // Switch endian type between big to little.
  template <typename T>
  T SwitchEndian(const T value) const {
    if (sizeof(T) == 4) {
      unsigned int temp_value = static_cast<unsigned int>(value);
      // clang-format off
      return ((temp_value >> 24)) |
             ((temp_value << 8) & 0x00ff0000) |
             ((temp_value >> 8) & 0x0000ff00) |
             ((temp_value << 24));
      // clang-format on
    } 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_;
};

// Read 3x3 column-major matrix from the file
void ReadMatrix3x3(const EndianAwareFileReader& file_reader, Mat3* matrix) {
  for (int i = 0; i < 9; i++) {
    (*matrix)(i % 3, i / 3) = file_reader.Read<float>();
  }
}

// Read 3-vector from file
void ReadVector3(const EndianAwareFileReader& file_reader, Vec3* vector) {
  for (int i = 0; i < 3; i++) {
    (*vector)(i) = file_reader.Read<float>();
  }
}

// Reads a bundle adjustment problem from the file.
//
// file_name denotes from which file to read the problem.
// camera_intrinsics will contain initial camera intrinsics values.
//
// all_cameras is a vector of all reconstructed cameras to be optimized,
// vector element with number i will contain camera for image i.
//
// all_points is a vector of all reconstructed 3D points to be optimized,
// vector element with number i will contain point for track i.
//
// all_markers is a vector of all tracked markers existing in
// the problem. Only used for reprojection error calculation, stay
// unchanged during optimization.
//
// Returns false if any kind of error happened during
// reading.
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;
  }

  // Read markers' space flag.
  unsigned char 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.";
  }

  // Read camera intrinsics.
  for (int i = 0; i < 8; i++) {
    camera_intrinsics[i] = file_reader.Read<float>();
  }

  // Read all cameras.
  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.";

  // Read all reconstructed 3D points.
  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.";

  // And finally read all markers.
  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;
}

// Apply camera intrinsics to the normalized point to get image coordinates.
// This applies the radial lens distortion to a point which is in normalized
// camera coordinates (i.e. the principal point is at (0, 0)) to get image
// coordinates in pixels. Templated for use with autodifferentiation.
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;

  // Apply distortion to the normalized points to get (xd, yd).
  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);

  // Apply focal length and principal point to get the final image coordinates.
  *image_x = focal_length_x * xd + principal_point_x;
  *image_y = focal_length_y * yd + principal_point_y;
}

// Cost functor which computes reprojection error of 3D point X
// on camera defined by angle-axis rotation and it's translation
// (which are in the same block due to optimization reasons).
//
// This functor uses a radial distortion model.
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,  // Rotation denoted by angle axis
                                       // followed with translation
                  const T* const X,    // Point coordinates 3x1.
                  T* residuals) const {
    // Unpack the intrinsics.
    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];

    // Compute projective coordinates: x = RX + t.
    T x[3];

    ceres::AngleAxisRotatePoint(R_t, X, x);
    x[0] += R_t[3];
    x[1] += R_t[4];
    x[2] += R_t[5];

    // Compute normalized coordinates: x /= x[2].
    T xn = x[0] / x[2];
    T yn = x[1] / x[2];

    T predicted_x, predicted_y;

    // Apply distortion to the normalized points to get (xd, yd).
    // TODO(keir): Do early bailouts for zero distortion; these are expensive
    // jet operations.
    ApplyRadialDistortionCameraIntrinsics(focal_length,
                                          focal_length,
                                          principal_point_x,
                                          principal_point_y,
                                          k1,
                                          k2,
                                          k3,
                                          p1,
                                          p2,
                                          xn,
                                          yn,
                                          &predicted_x,
                                          &predicted_y);

    // The error is the difference between the predicted and observed position.
    residuals[0] = predicted_x - observed_x;
    residuals[1] = predicted_y - observed_y;

    return true;
  }

  const double observed_x;
  const double observed_y;
};

// Print a message to the log which camera intrinsics are gonna to be optimized.
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 << ".";
  }
}

// Print a message to the log containing all the camera intriniscs values.
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();
}

// Get a vector of camera's rotations denoted by angle axis
// conjuncted with translations into single block
//
// Element with index i matches to a rotation+translation for
// camera at image i.
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;
}

// Convert cameras rotations fro mangle axis back to rotation matrix.
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);

  // 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);

  // Manifold used to restrict camera motion for modal solvers.
  ceres::SubsetManifold* constant_transform_manifold = nullptr;
  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_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 (int i = 0; i < all_markers.size(); ++i) {
    const Marker& marker = all_markers[i];
    EuclideanCamera* camera = CameraForImage(all_cameras, marker.image);
    EuclideanPoint* point = PointForTrack(all_points, marker.track);
    if (camera == nullptr || point == nullptr) {
      continue;
    }

    // Rotation of camera denoted in angle axis followed with
    // camera translaiton.
    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));

    // 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.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) {
    // 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::SubsetManifold* subset_manifold =
        new ceres::SubsetManifold(8, constant_intrinsics);
    problem.SetManifold(camera_intrinsics, subset_manifold);
  }

  // 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);
}
}  // namespace

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;
  }

  // If there's no refine_intrinsics passed via command line
  // (in this case FLAGS_refine_intrinsics will be an empty string)
  // we use problem's settings to detect whether intrinsics
  // shall be refined or not.
  //
  // Namely, if problem has got markers stored in image (pixel)
  // space, we do full intrinsics refinement. If markers are
  // stored in normalized space, and refine_intrinsics is not
  // set, no refining will happen.
  //
  // Using command line argument refine_intrinsics will explicitly
  // declare which intrinsics need to be refined and in this case
  // refining flags does not depend on problem at all.
  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;
    }
  }

  // Run the bundler.
  EuclideanBundleCommonIntrinsics(all_markers,
                                  bundle_intrinsics,
                                  BUNDLE_NO_CONSTRAINTS,
                                  camera_intrinsics,
                                  &all_cameras,
                                  &all_points);

  return EXIT_SUCCESS;
}
