8000 Add fixed extrinsics in rig config by anmatako · Pull Request #1144 · colmap/colmap · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add fixed extrinsics in rig config #1144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/base/camera_rig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ double CameraRig::ComputeScale(const Reconstruction& reconstruction) const {
return scaling_factor / num_dists;
}

void CameraRig::ComputeRelativePoses(const Reconstruction& reconstruction) {
bool CameraRig::ComputeRelativePoses(const Reconstruction& reconstruction) {
CHECK_GT(NumSnapshots(), 0);
CHECK_NE(ref_camera_id_, kInvalidCameraId);

Expand Down Expand Up @@ -208,10 +208,14 @@ void CameraRig::ComputeRelativePoses(const Reconstruction& reconstruction) {
// Compute the average relative poses.
for (auto& rig_camera : rig_cameras_) {
if (rig_camera.first != ref_camera_id_) {
CHECK_GT(rel_qvecs.count(rig_camera.first), 0)
<< "Need at least one snapshot with an image of camera "
<< rig_camera.first << " and the reference camera " << ref_camera_id_
<< " to compute its relative pose in the camera rig";
if (rel_qvecs.count(rig_camera.first) == 0) {
std::cout << "Need at least one snapshot with an image of camera "
<< rig_camera.first << " and the reference camera "
<< ref_camera_id_
<< " to compute its relative pose in the camera rig"
<< std::endl;
return false;
}
const std::vector<Eigen::Vector4d>& camera_rel_qvecs =
rel_qvecs.at(rig_camera.first);
const std::vector<double> rel_qvec_weights(camera_rel_qvecs.size(), 1.0);
Expand All @@ -220,6 +224,7 @@ void CameraRig::ComputeRelativePoses(const Reconstruction& reconstruction) {
rig_camera.second.rel_tvec /= camera_rel_qvecs.size();
}
}
return true;
}

void CameraRig::ComputeAbsolutePose(const size_t snapshot_idx,
Expand Down
2 changes: 1 addition & 1 deletion src/base/camera_rig.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class CameraRig {
// the relative poses over all snapshots. The pose of the reference camera
// will be the identity transformation. This assumes that the camera rig has
// snapshots that are registered in the reconstruction.
void ComputeRelativePoses(const Reconstruction& reconstruction);
bool ComputeRelativePoses(const Reconstruction& reconstruction);

// Compute the absolute camera pose of the rig. The absolute camera pose of
// the rig is computed as the average of all relative camera poses in the rig
Expand Down
63 changes: 54 additions & 9 deletions src/exe/colmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1633,23 +1633,38 @@ int RunPointTriangulator(int argc, char** argv) {
// {
// "camera_id": 1,
// "image_prefix": "left1_image"
// "rel_tvec": [0, 0, 0],
// "rel_qvec": [1, 0, 0, 0]
// },
// {
// "camera_id": 2,
// "image_prefix": "left2_image"
// "rel_tvec": [0, 0, 0],
// "rel_qvec": [0, 1, 0, 0]
// },
// {
// "camera_id": 3,
// "image_prefix": "right1_image"
// "rel_tvec": [0, 0, 0],
// "rel_qvec": [0, 0, 1, 0]
// },
// {
// "camera_id": 4,
// "image_prefix": "right2_image"
// "rel_tvec": [0, 0, 0],
// "rel_qvec": [0, 0, 0, 1]
// }
// ]
// }
// ]
//
// The "camera_id" and "image_prefix" fields are required, whereas the
// "rel_tvec" and "rel_qvec" fields optionally specify the relative
// extrinsics of the camera rig in the form of a translation vector and a
// rotation quaternion. The relative extrinsics rel_qvec and rel_tvec transform
// coordinates from rig to camera coordinate space. If the relative extrinsics
// are not provided then they are automatically inferred from the reconstruction.
//
// This file specifies the configuration for a single camera rig and that you
// could potentially define multiple camera rigs. The rig is composed of 4
// cameras: all images of the first camera must have "left1_image" as a name
Expand Down Expand Up @@ -1683,11 +1698,9 @@ int RunPointTriangulator(int argc, char** argv) {
// frame002.png
// ...
//
// TODO: Provide an option to manually / explicitly set the relative extrinsics
// of the camera rig. At the moment, the relative extrinsics are automatically
// inferred from the reconstruction.
std::vector<CameraRig> ReadCameraRigConfig(
const std::string& rig_config_path, const Reconstruction& reconstruction) {
std::vector<CameraRig> ReadCameraRigConfig(const std::string& rig_config_path,
const Reconstruction& reconstruction,
bool estimate_rig_relative_poses) {
boost::property_tree::ptree pt;
boost::property_tree::read_json(rig_config_path.c_str(), pt);

Expand All @@ -1699,8 +1712,28 @@ std::vector<CameraRig> ReadCameraRigConfig(
for (const auto& camera : rig_config.second.get_child("cameras")) {
const int camera_id = camera.second.get<int>("camera_id");
image_prefixes.push_back(camera.second.get<std::string>("image_prefix"));
camera_rig.AddCamera(camera_id, ComposeIdentityQuaternion(),
Eigen::Vector3d(0, 0, 0));
Eigen::Vector3d rel_tvec;
Eigen::Vector4d rel_qvec;
int index = 0;
auto rel_tvec_node = camera.second.get_child_optional("rel_tvec");
if (rel_tvec_node) {
for (const auto& node : rel_tvec_node.get()) {
rel_tvec[index] = node.second.get_value<double>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You missed the ++ after index 🙂 Same for loading rel_qvec below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on that one; I'll post a fix.

}
} else {
estimate_rig_relative_poses = true;
}
index = 0;
auto rel_qvec_node = camera.second.get_child_optional("rel_qvec");
if (rel_qvec_node) {
for (const auto& node : rel_qvec_node.get()) {
rel_qvec[index] = node.second.get_value<double>();
}
} else {
estimate_rig_relative_poses = true;
}

camera_rig.AddCamera(camera_id, rel_qvec, rel_tvec);
}

camera_rig.SetRefCameraId(rig_config.second.get<int>("ref_camera_id"));
Expand Down Expand Up @@ -1732,7 +1765,15 @@ std::vector<CameraRig> ReadCameraRigConfig(
}

camera_rig.Check(reconstruction);
camera_rig.ComputeRelativePoses(reconstruction);
if (estimate_rig_relative_poses) {
PrintHeading2("Estimating relative rig poses");
if (!camera_rig.ComputeRelativePoses(reconstruction)) {
std::cout << "WARN: Failed to estimate rig poses from reconstruction; "
"cannot use rig BA"
<< std::endl;
return std::vector<CameraRig>();
}
}

camera_rigs.push_back(camera_rig);
}
Expand All @@ -1744,13 +1785,16 @@ int RunRigBundleAdjuster(int argc, char** argv) {
std::string input_path;
std::string output_path;
std::string rig_config_path;
bool estimate_rig_relative_poses = true;

RigBundleAdjuster::Options rig_ba_options;

OptionManager options;
options.AddRequiredOption("input_path", &input_path);
options.AddRequiredOption("output_path", &output_path);
options.AddRequiredOption("rig_config_path", &rig_config_path);
options.AddDefaultOption("estimate_rig_relative_poses",
&estimate_rig_relative_poses);
options.AddDefaultOption("RigBundleAdjustment.refine_relative_poses",
&rig_ba_options.refine_relative_poses);
options.AddBundleAdjustmentOptions();
Expand All @@ -1761,7 +1805,8 @@ int RunRigBundleAdjuster(int argc, char** argv) {

PrintHeading1("Camera rig configuration");

auto camera_rigs = ReadCameraRigConfig(rig_config_path, reconstruction);
auto camera_rigs = ReadCameraRigConfig(rig_config_path, reconstruction,
estimate_rig_relative_poses);

BundleAdjustmentConfig config;
for (size_t i = 0; i < camera_rigs.size(); ++i) {
Expand Down
0