45 return rig_cameras_.count(camera_id);
52 ref_camera_id_ = camera_id;
56 std::vector<camera_t> rig_camera_ids;
58 for (
const auto& rig_camera : rig_cameras_) {
59 rig_camera_ids.push_back(rig_camera.first);
61 return rig_camera_ids;
69 const Eigen::Vector4d& rel_qvec,
70 const Eigen::Vector3d& rel_tvec) {
74 rig_camera.rel_qvec = rel_qvec;
75 rig_camera.rel_tvec = rel_tvec;
76 rig_cameras_.emplace(camera_id, rig_camera);
80 CHECK(!image_ids.empty());
83 snapshots_.push_back(image_ids);
89 for (
const auto& rig_camera : rig_cameras_) {
93 std::unordered_set<image_t> all_image_ids;
94 for (
const auto& snapshot : snapshots_) {
95 CHECK(!snapshot.empty());
97 bool has_ref_camera =
false;
98 for (
const auto image_id : snapshot) {
100 CHECK_EQ(all_image_ids.count(image_id), 0);
101 all_image_ids.insert(image_id);
102 const auto&
image = reconstruction.
Image(image_id);
104 if (
image.CameraId() == ref_camera_id_) {
105 has_ref_camera =
true;
108 CHECK(has_ref_camera);
113 return rig_cameras_.at(camera_id).rel_qvec;
117 return rig_cameras_.at(camera_id).rel_qvec;
121 return rig_cameras_.at(camera_id).rel_tvec;
125 return rig_cameras_.at(camera_id).rel_tvec;
131 double scaling_factor = 0;
132 size_t num_dists = 0;
133 std::vector<Eigen::Vector3d> rel_proj_centers(
NumCameras());
134 std::vector<Eigen::Vector3d> abs_proj_centers(
NumCameras());
135 for (
const auto& snapshot : snapshots_) {
138 const auto&
image = reconstruction.
Image(snapshot[i]);
141 abs_proj_centers[i] =
image.ProjectionCenter();
146 for (
size_t j = 0; j < i; ++j) {
147 const double rel_dist =
148 (rel_proj_centers[i] - rel_proj_centers[j]).norm();
149 const double abs_dist =
150 (abs_proj_centers[i] - abs_proj_centers[j]).norm();
151 const double kMinDist = 1
e-6;
152 if (rel_dist > kMinDist && abs_dist > kMinDist) {
153 scaling_factor += rel_dist / abs_dist;
160 if (num_dists == 0) {
161 return std::numeric_limits<double>::quiet_NaN();
164 return scaling_factor / num_dists;
171 for (
auto& rig_camera : rig_cameras_) {
172 rig_camera.second.rel_tvec = Eigen::Vector3d::Zero();
175 std::unordered_map<camera_t, std::vector<Eigen::Vector4d>> rel_qvecs;
177 for (
const auto& snapshot : snapshots_) {
179 const Image* ref_image =
nullptr;
180 for (
const auto image_id : snapshot) {
181 const auto&
image = reconstruction.
Image(image_id);
182 if (
image.CameraId() == ref_camera_id_) {
187 CHECK_NOTNULL(ref_image);
191 for (
const auto image_id : snapshot) {
192 const auto&
image = reconstruction.
Image(image_id);
193 if (
image.CameraId() != ref_camera_id_) {
194 Eigen::Vector4d rel_qvec;
195 Eigen::Vector3d rel_tvec;
197 image.Tvec(), &rel_qvec, &rel_tvec);
199 rel_qvecs[
image.CameraId()].push_back(rel_qvec);
206 RelativeTvec(ref_camera_id_) = Eigen::Vector3d(0, 0, 0);
209 for (
auto& rig_camera : rig_cameras_) {
210 if (rig_camera.first != ref_camera_id_) {
211 if (rel_qvecs.count(rig_camera.first) == 0) {
212 std::cout <<
"Need at least one snapshot with an image of camera "
213 << rig_camera.first <<
" and the reference camera "
215 <<
" to compute its relative pose in the camera rig"
219 const std::vector<Eigen::Vector4d>& camera_rel_qvecs =
220 rel_qvecs.at(rig_camera.first);
221 const std::vector<double> rel_qvec_weights(camera_rel_qvecs.size(), 1.0);
222 rig_camera.second.rel_qvec =
224 rig_camera.second.rel_tvec /= camera_rel_qvecs.size();
232 Eigen::Vector4d* abs_qvec,
233 Eigen::Vector3d* abs_tvec)
const {
234 const auto& snapshot = snapshots_.at(snapshot_idx);
236 std::vector<Eigen::Vector4d> abs_qvecs;
237 *abs_tvec = Eigen::Vector3d::Zero();
239 for (
const auto image_id : snapshot) {
240 const auto&
image = reconstruction.
Image(image_id);
241 Eigen::Vector4d inv_rel_qvec;
242 Eigen::Vector3d inv_rel_tvec;
244 &inv_rel_qvec, &inv_rel_tvec);
246 const Eigen::Vector4d qvec =
251 abs_qvecs.push_back(qvec);
255 const std::vector<double> abs_qvec_weights(snapshot.size(), 1);
257 *abs_tvec /= snapshot.size();
std::shared_ptr< core::Tensor > image
void SetRefCameraId(const camera_t camera_id)
camera_t RefCameraId() const
void Check(const Reconstruction &reconstruction) const
void AddCamera(const camera_t camera_id, const Eigen::Vector4d &rel_qvec, const Eigen::Vector3d &rel_tvec)
bool HasCamera(const camera_t camera_id) const
size_t NumSnapshots() const
Eigen::Vector3d & RelativeTvec(const camera_t camera_id)
void AddSnapshot(const std::vector< image_t > &image_ids)
size_t NumCameras() const
bool ComputeRelativePoses(const Reconstruction &reconstruction)
std::vector< camera_t > GetCameraIds() const
const std::vector< std::vector< image_t > > & Snapshots() const
Eigen::Vector4d & RelativeQvec(const camera_t camera_id)
void ComputeAbsolutePose(const size_t snapshot_idx, const Reconstruction &reconstruction, Eigen::Vector4d *abs_qvec, Eigen::Vector3d *abs_tvec) const
double ComputeScale(const Reconstruction &reconstruction) const
const Eigen::Vector3d & Tvec() const
const Eigen::Vector4d & Qvec() const
const class Image & Image(const image_t image_id) const
bool ExistsCamera(const camera_t camera_id) const
bool ExistsImage(const image_t image_id) const
QTextStream & endl(QTextStream &stream)
void ComputeRelativePose(const Eigen::Vector4d &qvec1, const Eigen::Vector3d &tvec1, const Eigen::Vector4d &qvec2, const Eigen::Vector3d &tvec2, Eigen::Vector4d *qvec12, Eigen::Vector3d *tvec12)
Eigen::Vector4d ComposeIdentityQuaternion()
void InvertPose(const Eigen::Vector4d &qvec, const Eigen::Vector3d &tvec, Eigen::Vector4d *inv_qvec, Eigen::Vector3d *inv_tvec)
Eigen::Vector4d AverageQuaternions(const std::vector< Eigen::Vector4d > &qvecs, const std::vector< double > &weights)
bool VectorContainsDuplicateValues(const std::vector< T > &vector)
const camera_t kInvalidCameraId
Eigen::Vector4d ConcatenateQuaternions(const Eigen::Vector4d &qvec1, const Eigen::Vector4d &qvec2)
Eigen::Vector3d QuaternionRotatePoint(const Eigen::Vector4d &qvec, const Eigen::Vector3d &point)
Eigen::Vector3d ProjectionCenterFromPose(const Eigen::Vector4d &qvec, const Eigen::Vector3d &tvec)