Help for MARSCOR2

PURPOSE:
To compute, from a stereo pair of images, the line and sample disparity
of every pixel in the scene.  The output is typically run through the
program MARSXYZ to generate X,Y,Z coordinates over the entire image.

This is a 2-D correlation program derived from MARSCORR.  The primary
difference is that MARSCOR2 has been adapted to work with parallel
processors (using MPI), but even when run on one processor, there are
some algorithm updates w.r.t. the original MARSCORR program.

The primary algorithmic difference is that MARSCOR2 acquires seed points
automatically.  This means that the input images must be supported by the
PIG library, because camera model information is used to determine the seeds.
MARSSEEDGEN is not needed for, nor can it be used with, MARSCOR2.

Despite the requirements of a camera model via PIG, the input images do
not have to be epipolar aligned or linearized, because a full 2-dimensional
correlation is performed.  This distinguishes the program from MARSJPLSTEREO,
which correlates in one dimension only (and thus the inputs must be aligned).

EXECUTION:
marscor2 inp=(left,right) out=(disparity) params

where:
left is the left eye image of a stereo pair
right is the corresponding right eye image of a stereo pair
disparity is the output (2-band) disparity file.

Although "left" and "right" are used above, there is no actual restriction
that the first image be left and the second be right.  Correlations are done
from the first image to the second.  Output images (disparity and mask)
correspond to the first image, containing matching coordinates in the second
image.  However, for convenience, "left" and "right" are used throughout
this help.

Additionally, mask can be used to name an output file with a completion
status, and out_quality can name an output file which will contain the
correlation qualities for each pixel.

PARALLEL EXECUTION:

MARSCOR2 can be run in parallel on multiple machines.  This dramatically
improves the wall-clock execution time of the program.  The MPI (Message
Passing Interface) package is used for interprocess communication.  This is
intended for Beowulf-style clusters, but can be used on any set of machines.
Each node processes a rectangular tile of the image in a grid pattern.
Because of the regular grid, only the following numbers of nodes are
currently supported:

1,2,3,4,5,6,9,10,12,15,16,18,20,24,25,28,32,36,40,44,45,48,49,50

If parallel execution is not desired, nothing special need be done.
The program will work on one processor with no extra parameters.
This program can be recompiled without using the MPI library by removing
the LIB_MPI definition from the imake file.  However, this is not
necessary - the MPI-linked version will work in serial fashion just fine.

Consult the MPI documentation for details on parallel execution.  However,
for the simplest case, the following can be done:

First, make sure all involved machines can be accessed via ssh from the
main node (the one on which you start the program).  It is convenient
to set up ssh to work without a password (consult your local System
Administrator), but that is not required.

Second, make sure that any required setups are done in your .cshrc file
on each machine.  This includes environment variables and generally
involves source'ing vicset1.csh and vicset2.csh.  The following is
recommended for a .cshrc file:

if ($?V2TOP == 0) then
    setenv V2TOP /usr/local/vicar/dev    (or wherever your VICAR resides)
    source $V2TOP/vicset1.csh
endif
source $V2TOP/vicset2.csh

Third, make sure all pathnames are absolute and accessible from all
machines.  The current directory is not transferred to the remote machines,
so relative pathnames will not work.

Finally, set up a file containing the node name of each machine to use.
Node names can be repeated, in which case multiple processes will be started
on each machine.  The first one becomes the master machine, and is often
(but not necessarily) the one on which the program is being started.  The
nodes should be of the same architecture (e.g. solaris vs. linux).
For example:

lowe% cat machines.solaris
# Change this file to contain the machines that you want to use
# to run MPI jobs on.  The format is one host name per line, with either
#    hostname
# or
#    hostname:n
# where n is the number of processors in an SMP.  The hostname should
# be the same as the result from the command "hostname"
lowe
pinatubo
potato
wind

Then the program can be run like this:

$MPILIB/bin/mpirun -np 4 -machinefile machines.solaris $MARSLIB/marscor2 ...

where -np is the number of processor nodes, -machinefile is the name of
the file above (this pathname can be relative), and ... are the normal
parameters to marscor2 (with absolute pathnames).

Each node sends its stdout/stderr output to the controlling terminal,
so messages from each node will be interleaved.


METHOD:

The process starts by finding a seed point, which is an initial guess to
obtain a starting correlation.  Initally, the center of the tile being
processed by the CPU is used.  Later seeds are obtained randomly within
the tile.  The prospective seed is projected to the PIG surface model
and then projected back into the second image.  The locations thus obtained
are then correlated.  If the correlation fails (or the seed has already
been correlated), another seed point is chosen (up to a max of 100).

The seed point is correlated using a wide search area (defined by AMAX(2)).
A region is then grown from the seed outward in a spiral-like pattern until
the picture is filled.

For each pixel, the 8 neighbors are examined to find the one with the best
correlation value so far.  This neighbor is used as the initial guess for
the pixel in question (modified +/-1 as appropriate).  If no correlated
neighbors are found, the pixel is skipped.  The correlation window is
defined via the TEMPLATE and SEARCH parameters.

Once the region has grown to the size of the image segment for the current
CPU (or TPTLIMIT pixels have been correlated), a second pass goes through
the region and attempts to fill gores, or pixels that did not correlate on
the first pass, by again examining all of its neighbors (since neighbors on
the other side, which were not done previously, might provide a better
starting location, which will correlate, especially near edges).  This
process continues until no more gores are filled in a pass.

After the gore-filling pass, the percent coverage of tiepoints is compared
to FILL_FRACTION.  If not enough tiepoints have been acquired to satisfy
FILL_FRACTION, the entire process is repeated using different randomly-
chosen seeds (up to a limit of MAX_TRIALS iterations).

After all that, the results from all processors are combined on the master
node (if running in parallel).  If SECOND_PASS is defined, the master node
then goes through the entire above algorithm again, this time using the
entire image.  This tends to fill in some gaps that might otherwise occur
at the boundaries between tiles.

CORRELATIONS:

All correlations are performed using the gruen correlation routine.  See
the gruen documentation for details of the algorithm.  Seed points are
always correlated using mode 3 (linear followed by amoeba) to handle large
offsets.  The rest of the points may be correlated using any gruen mode
via the MODE parameter:

linear:            gruen mode 0
annealing:         gruen mode 1
amoeba:            gruen mode 2
linear_amoeba:     gruen mode 3
annealing_amoeba:  gruen mode 4
amoeba2:           gruen mode 5
linear_amoeba2:    gruen mode 6

Of the above, only amoeba and amoeba2 (modes 2 and 5) are recommended.  The
others are provided only for experimentation, and may significantly increase
the execution time of the program.  The annealing modes are not fully
implemented in the code at this time, but it would be trivial to do so if
desired.

The amoeba mode uses a full 6 degree of freedom search from the starting point
(derived from the best neighbor).  The starting point must be within 2 pixels.
The amoeba2 mode uses only 2 degrees of freedom (x/y offsets only) so it will
be faster, at the possible expense of accuracy.  The starting point must also
be within 2 pixels.  amoeba2 is not recommended for images that are not derived
from a stereo camera, e.g. using different instruments or involving motion
between the two frames.  The other modes generally do not have a 2 pixels
starting point limitation, so they might be useful for scenes with wildly
varying disparity values.  However, they are exceedingly slow.

The template (correlation patch) and search area sizes may be rectangular
instead of square.  For landed images such as Mars Pathfinder, the Mars 98
lander, or MER, it may be advantageous to specify areas that are much wider
than they are tall.

OUTPUT FILE CONTENTS:

All output files are in the coordinates of the first (left eye) image.
For example if the sample disparity file has a value of 56.67 at sample 50
it means that the sample location of a tiepoint located at sample 50 in the
left eye image corresponds to sample 56.67 in the right eye image.   

The line and sample disparities are written into two separate files, if
two filenames are provided.  If only one filename is provided, both are
written to a single, 2-banded file, with line in the first band and sample
in the second.

First output (or band): A REAL image containing the line disparity.  The
line/sample coordinate of each pixel in the output defines the position
in the left eye.  The value of the pixel contains the line coordinate of
the corresponding pixel in the right eye image.

Second output (or band): A REAL image containing the sample disparity.  The
line/sample coordinate of each pixel in the output defines the position
in the left eye.  The value of the pixel contains the sample coordinate of
the corresponding pixel in the right eye image.

If both line & sample disparity values are 0.000 the point has no value
(meaning correlation failed for that point).

Note that all disparity values use 1-based coordinates for the right
image, per VICAR conventions.

Mask file (optional): A BYTE image showing the coverage of tiepoints.
 0 dn means the pixel could not be reached in order to be correlated
   (i.e. there were no neighbors to supply an initial value, or TPTLIMIT
   was reached).
 128 dn means a correlation was successfully performed at this location.
 255 dn means a correlation was attempted at this location but it failed,
   usually because of low correlation quality.

Output quality file (optional): A REAL image containing the correlation
quality of each pixel attempted, from 0 to 1.  0 indicates either a
correlation failure unrelated to the QUALITY setting, or a pixel that was
not reached (the MASK output can distinguish).  Note that the file will
contain just a thin border of poor-quality pixels around each area,
because poor-quality pixels prevent the correlator from searching farther
in that direction.

HISTORY:

  1995-12-01 J Lorre - Initial MPFTPT program
  1999-07    Bob Deen - Signficant internal restructuring and addition of features.
             Program renamed to marscorr.  
  2002       G. Klimeck of Section 381 - Took marscorr as a base and implemented 
             parallel algorithms and seed derivation improvements.  
  2003-02    Bob Deen - Integrated parallel code into VICAR; became marscor2.
  2019-10-02 Walt Bunch - IDS-7926 - Initialized some variables.
             Commented unused variables. Added test script and log.
  2020-03-05 Walt Bunch - IDS-7927 - Replaced sprintf with snprintf or zvnprintf.
  2020-03-18 Walt Bunch - IDS-7927 - Replaced zvnprintf with snprintf.

COGNIZANT PROGRAMMER:  Bob Deen


PARAMETERS:


INP

input images. first: left eye second: right eye

OUT

Output file(s). Combined disparity, or (line, sample)

MASK

Output mask file (optional)

OUT_QUALITY

Output quality image (optional)

BAND

The vicar image band number. Defaults to 1

TEMPLATE

correlation size

SEARCH

correlation search area

QUALITY

Minimum acceptable correlation quality.

TPTLIMIT

Limit number of tiepoints to TPTLIMIT

AMAX

Maximum template/ search areas

MODE

Correlation mode. Use only amoeba, amoeba2.

MAX_TRIALS

Maximum iterations for outer loop; i.e. how many seeds to try.

FILL_FRACTION

Desired percentage of correlated pixels within one segment

SECOND_PASS

Turns on a second pass on the master CPU after the nodes are done

SEGMENT_BORDER

Border (in pixels) to leave between tiles (nodes)

OUTSIDE_BORDER

Border (in pixels) to leave on the outside edge of the image

RAND_SEED

Seeds random number generator if given. 0 seeds to current time

NAVTABLE

Corrected navigation filename.

NORMAL

Surface normal vector.

GROUND

Surface ground point.

SURF_COORD

Coordinate system used to define surface parameters.

SURFACE

The type of mars surface to use INFINITY, PLANE, SPHERE1, SPHERE2.

CONFIG_PATH

Path used to find configuration/calibration files.

MATCH_METHOD

Specifies a method for pointing corrections.

MATCH_TOL

Tolerance value for matching pointing params in pointing corrections file.

POINT_METHOD

Specifies a mission- specific pointing method to use

NOSITE

Disables coordinate system sites.

DATA_SET_NAME

Specifies the full name given to a data set or a data product.

DATA_SET_ID

Specifies a unique alphanumeric identifier for a data set or data product.

RELEASE_ID

Specifies the unique identifier associated with the release to the public of all or part of a data set. The release number is associated with the data set, not the mission.

PRODUCT_ID

Specifies a permanent, unique identifier assigned to a data product by its producer.

PRODUCER_ID

Specifies the unique identifier of an entity associated with the production a data set.

PRODUCER_INST

Specifies the full name of the identity of an entity associated with the production of a data set.

TARGET_NAME

Specifies a target.

TARGET_TYPE

Specifies the type of a named target.

RSF

Rover State File(s) to use.

DEBUG_RSF

Turns on debugging of RSF parameter.

COORD

Coordinate system to use.

COORD_INDEX

Coordinate system index for some COORD/mission combos.

FIXED_SITE

Which site is FIXED for rover missions.

SOLUTION_ID

Solution ID to use for pointing correction.

See Examples:


Cognizant Programmer: