Skip to content

Commit 624a06a

Browse files
Copy over more logic from gcp_gen to image_align
1 parent 063e6f2 commit 624a06a

File tree

2 files changed

+79
-21
lines changed

2 files changed

+79
-21
lines changed

docs/tools/image_align.rst

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ Command-line options for image_align
198198
Specify the output image.
199199

200200
--output-prefix <string (default: "out_image_align/run")>
201-
Save the interest point matches, computed transform, and other auxiliary
201+
If set, save the interest point matches, computed transform, and other auxiliary
202202
data at this prefix. These are cached for future runs.
203203

204204
--alignment-transform <string (default: "rigid")>
@@ -213,17 +213,40 @@ Command-line options for image_align
213213
values are clamped (and also rounded for integer types) to avoid
214214
overflow.
215215

216-
--ip-per-image <integer (default: 0)>
217-
How many interest points to detect in each image (default: automatic
218-
determination).
216+
--ip-detect-method <integer (default: 0)>
217+
Interest point detection algorithm (0: Integral OBALoG (default), 1: OpenCV SIFT, 2: OpenCV ORB).
218+
219+
--ip-per-image <integer (default: 20000)>
220+
How many interest points to detect in each image (the resulting number of
221+
matches will be much less).
222+
223+
--ip-per-tile <integer (default: 0)>
224+
How many interest points to detect in each 1024^2 image tile (default: automatic
225+
determination). This is before matching. Not all interest points will have a match.
226+
See also ``--matches-per-tile``.
227+
228+
--matches-per-tile <integer (default: 0)>
229+
How many interest point matches to compute in each image tile (of size
230+
normally 1024^2 pixels). Use a value of ``--ip-per-tile`` a few times larger
231+
than this. See also ``--matches-per-tile-params``.
232+
233+
--matches-per-tile-params <string (default: "1024 1280")>
234+
To be used with ``--matches-per-tile``. The first value is the image tile size for both
235+
images. A larger second value allows each right tile to further expand to this size,
236+
resulting in the tiles overlapping. This may be needed if the homography alignment
237+
between these images is not great, as this transform is used to pair up left and
238+
right image tiles.
239+
240+
--individually-normalize
241+
Individually normalize the input images instead of using common values.
219242

220243
--num-ransac-iterations <integer (default: 1000)>
221244
How many iterations to perform in RANSAC when finding interest point
222245
matches.
223246

224-
--inlier-threshold <integer (default: 5)>
225-
The inlier threshold (in pixels) to separate inliers from outliers when
226-
computing interest point matches. A smaller threshold will result in fewer
247+
--inlier-threshold <double (default: 200.0)>
248+
The inlier threshold (in pixels) to separate inliers from outliers when
249+
computing interest point matches. A smaller threshold will result in fewer
227250
inliers.
228251

229252
--disparity-params <string (default: "")>

src/asp/Tools/image_align.cc

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ struct Options: vw::GdalWriteOptions {
4747
std::vector<std::string> input_images;
4848
std::string alignment_transform, output_image, output_prefix, output_data_string,
4949
input_transform, disparity_params, ecef_transform_type, dem1, dem2;
50-
double inlier_threshold;
51-
int num_ransac_iterations, output_data_type;
52-
Options(): num_ransac_iterations(0.0), inlier_threshold(0){}
50+
int output_data_type;
51+
Options(): output_data_type(0){}
5352
};
5453

5554
/// Get a list of matched IP based on an input disparity
@@ -127,7 +126,8 @@ Matrix<double> do_ransac(std::vector<Vector3> const& ransac_ip1,
127126
try {
128127
vw::math::RandomSampleConsensus<FunctorT, vw::math::InterestPointErrorMetric>
129128
ransac(FunctorT(), vw::math::InterestPointErrorMetric(),
130-
opt.num_ransac_iterations, opt.inlier_threshold,
129+
asp::stereo_settings().ip_num_ransac_iterations,
130+
asp::stereo_settings().epipolar_threshold,
131131
min_num_output_inliers, reduce_num_inliers_if_no_fit);
132132
tf = ransac(ransac_ip2, ransac_ip1);
133133
indices = ransac.inlier_indices(tf, ransac_ip2, ransac_ip1);
@@ -219,7 +219,7 @@ void calc_ecef_transform(std::vector<ip::InterestPoint> const& inlier_ip1,
219219
double scale;
220220
bool filter_outliers = true;
221221
Vector2 ransac_params;
222-
ransac_params[0] = opt.num_ransac_iterations;
222+
ransac_params[0] = asp::stereo_settings().ip_num_ransac_iterations;
223223
ransac_params[1] = 1.0; // factor; not the same as opt.inlier_threshold
224224
vw::math::find_3D_transform(points_src, points_ref,
225225
rotation, translation, scale,
@@ -322,26 +322,58 @@ void handle_arguments(int argc, char *argv[], Options& opt) {
322322
"Specify the transform to use to align the second image to the first. Options: "
323323
"translation, rigid (translation + rotation), similarity (translation + rotation + "
324324
"scale), affine, homography.")
325-
("ip-per-image", po::value(&ip_opt.ip_per_image)->default_value(0),
326-
"How many interest points to detect in each image (default: automatic determination).")
327325
("output-prefix", po::value(&opt.output_prefix)->default_value("out_image_align/run"),
328326
"If set, save the interest point matches, computed transform, and other auxiliary "
329327
"data at this prefix. These are cached for future runs.")
330328
("output-data-type,d", po::value(&opt.output_data_string)->default_value("float32"),
331329
"The data type of the output file. Options: uint8, uint16, uint32, int16, int32, "
332330
"float32, float64. The values are clamped (and also rounded for integer types) to avoid "
333331
"overflow.")
334-
("num-ransac-iterations", po::value(&opt.num_ransac_iterations)->default_value(1000),
332+
("ip-detect-method", po::value(&ip_opt.ip_detect_method)->default_value(0),
333+
"Interest point detection algorithm (0: Integral OBALoG (default), 1: OpenCV SIFT, 2: OpenCV ORB.")
334+
("ip-per-image", po::value(&ip_opt.ip_per_image)->default_value(20000),
335+
"How many interest points to detect in each image (the resulting number of "
336+
"matches will be much less).")
337+
("ip-per-tile", po::value(&ip_opt.ip_per_tile)->default_value(0),
338+
"How many interest points to detect in each 1024^2 image tile (default: automatic "
339+
"determination). This is before matching. Not all interest points will have a match. "
340+
"See also --matches-per-tile.")
341+
("matches-per-tile", po::value(&ip_opt.matches_per_tile)->default_value(0),
342+
"How many interest point matches to compute in each image tile (of size "
343+
"normally 1024^2 pixels). Use a value of --ip-per-tile a few times larger "
344+
"than this. See also --matches-per-tile-params.")
345+
("matches-per-tile-params",
346+
po::value(&ip_opt.matches_per_tile_params)->default_value(Vector2(1024, 1280),
347+
"1024 1280"),
348+
"To be used with --matches-per-tile. The first value is the image tile size for both "
349+
"images. A larger second value allows each right tile to further expand to this size, "
350+
"resulting in the tiles overlapping. This may be needed if the homography alignment "
351+
"between these images is not great, as this transform is used to pair up left and "
352+
"right image tiles.")
353+
("individually-normalize",
354+
po::bool_switch(&ip_opt.individually_normalize)->default_value(false)->implicit_value(true),
355+
"Individually normalize the input images instead of using common values.")
356+
("num-ransac-iterations",
357+
po::value(&ip_opt.ip_num_ransac_iterations)->default_value(1000),
335358
"How many iterations to perform in RANSAC when finding interest point matches.")
336-
("inlier-threshold", po::value(&opt.inlier_threshold)->default_value(5.0),
337-
"The inlier threshold (in pixels) to separate inliers from outliers when computing interest point matches. A smaller threshold will result in fewer inliers.")
359+
("inlier-threshold", po::value(&ip_opt.epipolar_threshold)->default_value(200.0),
360+
"The inlier threshold (in pixels) to separate inliers from outliers when "
361+
"computing interest point matches. A smaller threshold will result in fewer "
362+
"inliers.")
338363
("input-transform", po::value(&opt.input_transform)->default_value(""),
339364
"Instead of computing an alignment transform, read and apply the one from this file. Must be stored as a 3x3 matrix.")
340-
("ecef-transform-type", po::value(&opt.ecef_transform_type)->default_value(""), "Save the ECEF transform corresponding to the image alignment transform to <output prefix>-ecef-transform.txt. The type can be: 'translation', 'rigid' (rotation + translation), or 'similarity' (rotation + translation + scale).")
341-
("dem1", po::value(&opt.dem1)->default_value(""), "The DEM associated with the first image. To be used with --ecef-transform-type.")
342-
("dem2", po::value(&opt.dem2)->default_value(""), "The DEM associated with the second image. To be used with --ecef-transform-type.")
365+
("ecef-transform-type", po::value(&opt.ecef_transform_type)->default_value(""),
366+
"Save the ECEF transform corresponding to the image alignment transform to <output "
367+
"prefix>-ecef-transform.txt. The type can be: 'translation', 'rigid' (rotation + "
368+
"translation), or 'similarity' (rotation + translation + scale).")
369+
("dem1", po::value(&opt.dem1)->default_value(""),
370+
"The DEM associated with the first image. To be used with --ecef-transform-type.")
371+
("dem2", po::value(&opt.dem2)->default_value(""),
372+
"The DEM associated with the second image. To be used with --ecef-transform-type.")
343373
("disparity-params", po::value(&opt.disparity_params)->default_value(""),
344-
"Find the alignment transform by using, instead of interest points, a disparity, such as produced by 'parallel_stereo --correlator-mode'. Specify as a string in quotes, in the format: 'disparity.tif num_samples'.")
374+
"Find the alignment transform by using, instead of interest points, a disparity, such "
375+
"as produced by 'parallel_stereo --correlator-mode'. Specify as a string in quotes, "
376+
"in the format: 'disparity.tif num_samples'.")
345377
("nodata-value",
346378
po::value(&ip_opt.nodata_value)->default_value(g_nan_val),
347379
"Pixels with values less than or equal to this number are treated as no-data. This "
@@ -371,6 +403,9 @@ void handle_arguments(int argc, char *argv[], Options& opt) {
371403
if (opt.output_image.empty())
372404
vw_throw(ArgumentErr() << "Missing output image name.\n" << usage << general_options);
373405

406+
if (ip_opt.ip_per_image > 0 && ip_opt.ip_per_tile > 0)
407+
vw_throw(ArgumentErr() << "Can set only one of --ip-per-image and --ip-per-tile.\n");
408+
374409
if (opt.alignment_transform != "translation" && opt.alignment_transform != "rigid" &&
375410
opt.alignment_transform != "similarity" && opt.alignment_transform != "affine" &&
376411
opt.alignment_transform != "homography") {

0 commit comments

Comments
 (0)