Skip to content

Commit

Permalink
Expand the camera_calibrate tool and the doc of camera solve, mention…
Browse files Browse the repository at this point in the history
… --fix-gcp-xyz
  • Loading branch information
oleg-alexandrov committed Apr 23, 2024
1 parent 29038aa commit 6e08c41
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 57 deletions.
32 changes: 18 additions & 14 deletions docs/sfm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ Creation of cameras in an arbitrary coordinate system
If we do not see any obvious problems we can go ahead and run the
``camera_solve`` tool::

camera_solve out/ AS15-M-0114_MED.png AS15-M-0115_MED.png \
--datum D_MOON --calib-file metric_model.tsai
camera_solve out/ AS15-M-0114_MED.png AS15-M-0115_MED.png \
--theia-overrides '--matching_strategy=CASCADE_HASHING' \
--datum D_MOON --calib-file metric_model.tsai

The reconstruction can be visualized as::

Expand Down Expand Up @@ -214,13 +215,15 @@ such a GCP file to ``camera_solve`` together with the flag::

--bundle-adjust-params "--transform-cameras-using-gcp"

This may not be as robust as the earlier approach.
This may not be as robust as the earlier approach. Consider the option
``--fix-gcp-xyz``, to not move the GCP during optimization.

Solving for cameras when using GCP::

camera_solve out_gcp/ \
AS15-M-0114_MED.png AS15-M-0115_MED.png \
--datum D_MOON --calib-file metric_model.tsai \
camera_solve out_gcp/ \
AS15-M-0114_MED.png AS15-M-0115_MED.png \
--datum D_MOON --calib-file metric_model.tsai \
--theia-overrides '--matching_strategy=CASCADE_HASHING' \
--gcp-file ground_control_points.gcp

Examine the lines ending in ``# GCP`` in the file::
Expand Down Expand Up @@ -382,14 +385,15 @@ to match. Commands using these options may look like this::
icebridge_kmz_to_csv 1000123_DMS_Frame_Events.kmz \
camera_positions.csv
camera_solve out \
2009_11_05_00667.JPG 2009_11_05_00668.JPG \
2009_11_05_00669.JPG 2009_11_05_00670.JPG \
2009_11_05_02947.JPG 2009_11_05_02948.JPG \
2009_11_05_02949.JPG 2009_11_05_02950.JPG \
2009_11_05_01381.JPG 2009_11_05_01382.JPG \
--datum WGS84 --calib-file icebridge_model.tsai \
--bundle-adjust-params \
camera_solve out \
2009_11_05_00667.JPG 2009_11_05_00668.JPG \
2009_11_05_00669.JPG 2009_11_05_00670.JPG \
2009_11_05_02947.JPG 2009_11_05_02948.JPG \
2009_11_05_02949.JPG 2009_11_05_02950.JPG \
2009_11_05_01381.JPG 2009_11_05_01382.JPG \
--theia-overrides '--matching_strategy=CASCADE_HASHING' \
--datum WGS84 --calib-file icebridge_model.tsai \
--bundle-adjust-params \
'--no-datum
--camera-positions camera_positions.csv
--csv-format "1:file 2:lon 3:lat 4:height_above_datum"
Expand Down
8 changes: 7 additions & 1 deletion docs/tools/bundle_adjust.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ control points (:numref:`bagcp`)::
file1.tif file2.tif \
file1.xml file2.xml \
gcp1.gcp gcp2.gcp gcp3.gcp \
--fix-gcp-xyz \
-o run_ba/run

Using the proper value for ``--datum`` is very important, otherwise the
longitude-latitude-height values in the GCP files will not be interpreted
correctly.

There can be more than one GCP file.
There can be more than one GCP file. The option ``--fix-gcp-xyz`` fixes the GCP
coordinates during optimization. This is useful when the GCP are very accurate.
Otherwise set per-GCP sigma.

The residuals for the GCP will be printed at the end of the
``{output-prefix}-final_residuals_pointmap.csv`` file,
Expand Down Expand Up @@ -471,6 +474,9 @@ to transform them as a group, with the ``bundle_adjust`` options
``--transform-cameras-with-shared-gcp`` and ``--transform-cameras-using-gcp``.
For use with SfM, see :numref:`sfm_world_coords`.

The option ``--fix-gcp-xyz`` fixes the GCP coordinates during optimization. This
is useful when the GCP are very accurate. Otherwise set per-GCP sigma.

The option ``--save-cnet-as-csv`` can be invoked to save the entire control
network in the GCP format, before any optimization. This can be useful for
comparing with any manually created GCP.
Expand Down
62 changes: 39 additions & 23 deletions docs/tools/camera_calibrate.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,48 @@
camera_calibrate
----------------

Overview
~~~~~~~~

The ``camera_calibrate`` tool can generate camera models suitable for use by
``camera_solve`` (:numref:`camera_solve`), and other ASP tools. This program
only solves for intrinsic camera parameters. To obtain the camera pose you
should use ``camera_solve``.

This tool is a wrapper around the OpenCV (http://opencv.org/) checkerboard
calibration tool which takes care of converting the output into readily usable
formats.
This tool is a wrapper around the `OpenCV camera calibration
<https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html>`_ software,
which takes care of converting the output into readily usable formats.

Other tools
~~~~~~~~~~~

ASP also ships the ``rig_calibrator`` program (:numref:`rig_calibrator`),
which calibrates the intrinsic and extrinsics of a rig of cameras, without
using a calibration target.

The ``bundle_adjust`` program can refine the intrinsics and extrinsics of
cameras, and can also constrain against a known well-aligned terrain (:numref:`floatingintrinsics`).

Example
~~~~~~~

::

camera_calibrate --box-size-cm 4.28625 outputFolder \
12 12 "images/image*.jpg"

Here, the checkerboard pattern has 13 squares in each direction, so
12 inner corners.

How to use
~~~~~~~~~~

::

camera_calibrate [options] <output folder> \
<num inner vertical corners> \
<num inner horizontal corners> \
<image wildcard>

When you run the tool, three camera model files will be created in the output
folder: ``solve_cam_params.txt``, ``vw_cam_params.tsai``, and
Expand All @@ -35,26 +69,8 @@ This must be in quotes so that the wildcard is not expanded before it is passed
to the tool. If you do not provide the ``--box-size`` parameter, the output
calibration numbers will be unitless.

ASP also ships the ``rig_calibrator`` program (:numref:`rig_calibrator`),
which calibrates the intrinsic and extrinsics of a rig of cameras, without
using a calibration target.

Example::

camera_calibrate --box-size-cm 4.28625 outputFolder \
12 12 "images/image*.jpg"

Here, the checkerboard pattern has 13 squares in each direction, so
12 inner corners.

Usage::

camera_calibrate [options] <output folder> \
<num inner vertical corners> \
<num inner horizontal corners> \
<image wildcard>

Command-line options for camera_calibrate:
Command-line options
~~~~~~~~~~~~~~~~~~~~

-h, --help
Display this help message.
Expand Down
11 changes: 6 additions & 5 deletions docs/tools/camera_solve.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,18 @@ each output folder and pass it back to ``camera_solve`` via
``--theia-flagfile``, or use the option ``--theia-overrides``.

In particular, setting ``--feature_density=DENSE`` in the flags file can be of
great help if there are not enough matches between images.
great help if there are not enough matches between images. The option
``--matching_strategy=CASCADE_HASHING`` can greatly speed up finding matches.

Example
^^^^^^^

::

camera_solve \
--bundle-adjust-params '--camera-positions nav.csv \
--csv-format "1:file 12:lat 13:lon 14:height_above_datum" \
--camera-weight 100.0' \
camera_solve \
--theia-overrides '--matching_strategy=CASCADE_HASHING' \
--bundle-adjust-params '--camera-positions nav.csv
--csv-format 1:file,12:lat,13:lon,14:height_above_datum' \
<other options>

The produced Theia reconstruction can be visualized with ``view_reconstruction``
Expand Down
3 changes: 3 additions & 0 deletions docs/tools/stereo_gui.rst
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,9 @@ will prompt for their names.
If having many images, this process can be repeated for several small sets,
creating several GCP files that can then be passed together to ``bundle_adjust``.

The sigmas for the GCP should be set manually. Or use ``bundle_adjust``
with the option ``--fix-gcp-xyz`` to ensure they are not adjusted.

GCP can be visualized in ``stereo_gui`` (:numref:`stereo_gui_vwip_gcp`).

If the input images and the orthoimage are very similar visually, one can
Expand Down
2 changes: 1 addition & 1 deletion src/asp/Camera/BundleAdjustCamera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ void asp::matchFilesProcessing(vw::ba::ControlNetwork const& cnet,
std::vector<std::vector<float>> & mapprojOffsetsPerCam,
std::vector<asp::HorizVertErrorStats> & horizVertErrors) {

vw_out() << "Filtering outliers and creating reports.\n";
vw_out() << "Creating reports.\n";

// Wipe the outputs
mapprojPoints.clear();
Expand Down
4 changes: 3 additions & 1 deletion src/asp/Core/GCP.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ void writeGCP(std::vector<std::string> const& image_files,
// It is important to keep track of the datum and projection, because the
// elevations are relative to it
// TODO(oalexan1): Put below dem_georef.get_wkt() instead.
// TODO(oalexan1): Have a single GCP-writing function, and put it in VW.
// See also the existing one called write_in_gcp_format() in VW.
output_handle << "# WKT: " << dem_georef.datum().get_wkt() << std::endl;

// TODO(oalexan1): Write here if the format is lon,lat,height, or easting, northing, height.
size_t num_pts_skipped = 0, num_pts_used = 0;

const size_t num_ips = matchlist.getNumPoints();
Expand Down
1 change: 0 additions & 1 deletion src/asp/Core/MatchList.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <vector>
#include <vw/BundleAdjustment/ControlNetworkLoader.h>
#include <vw/InterestPoint/Matcher.h> // Needed for vw::ip::match_filename

#include <asp/Core/MatchList.h>

using namespace vw;
Expand Down
24 changes: 13 additions & 11 deletions src/asp/Tools/bundle_adjust.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1509,6 +1509,10 @@ void do_ba_ceres(Options & opt, std::vector<Vector3> const& estimated_camera_gcc
// Always save the updated cameras, even if we are not doing any optimization
saveUpdatedCameras(opt, param_storage);

// If we are only applying an initial transform, we are done
if (opt.apply_initial_transform_only)
return;

// Write the GCP stats to a file
if (num_gcp > 0)
param_storage.print_gcp_stats(opt.out_prefix, cnet, opt.datum);
Expand Down Expand Up @@ -1594,24 +1598,22 @@ void do_ba_ceres(Options & opt, std::vector<Vector3> const& estimated_camera_gcc
asp::saveTriOffsetsPerCamera(opt.image_files, orig_parameters, param_storage, crn,
tri_offsets_file);

if (!opt.apply_initial_transform_only && has_datum &&
if (has_datum &&
(opt.stereo_session == "pinhole") || (opt.stereo_session == "nadirpinhole"))
saveCameraReport(opt, param_storage, opt.datum, "final");

// Save the updated cnet to ISIS or nvm format. Note that param_storage has
// the latest triangulated points and outlier info, while the cnet has the
// initially triangulated points and the interest point matches.
if (!opt.apply_initial_transform_only) {
if (opt.isis_cnet != "" && opt.output_cnet_type == "isis-cnet")
asp::saveUpdatedIsisCnet(opt.out_prefix, cnet, param_storage, isisCnetData);
else if (opt.output_cnet_type == "isis-cnet")
asp::saveIsisCnet(opt.out_prefix, opt.datum, cnet, param_storage);
else if (opt.output_cnet_type == "nvm") {
asp::saveNvm(opt, opt.no_poses_from_nvm, cnet, param_storage,
world_to_cam, optical_offsets);
}
if (opt.isis_cnet != "" && opt.output_cnet_type == "isis-cnet")
asp::saveUpdatedIsisCnet(opt.out_prefix, cnet, param_storage, isisCnetData);
else if (opt.output_cnet_type == "isis-cnet")
asp::saveIsisCnet(opt.out_prefix, opt.datum, cnet, param_storage);
else if (opt.output_cnet_type == "nvm") {
asp::saveNvm(opt, opt.no_poses_from_nvm, cnet, param_storage,
world_to_cam, optical_offsets);
}

} // end do_ba_ceres

/// Looks in the input camera position file to generate a GCC position for
Expand Down

0 comments on commit 6e08c41

Please sign in to comment.