Skip to content
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

Add new parameters OFFBODY and OFFBODYTRIM to cam2cam #5704

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ release.
## [Unreleased]

### Added
- Added OFFBODY and OFFBODYTRIM parameters to cam2cam. Added tests and updated documentation. [#3602] (https://github.com/DOI-USGS/ISIS3/issues/3602)

### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Group = ShapeModel
RayTraceEngine = Bullet
OnError = Continue
EndGroup
End
26 changes: 26 additions & 0 deletions isis/src/base/apps/cam2cam/assets/files/cam2camExample3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

# Get example image acquired by OREX OCAMS during "Detailed Survey" phase\
dtype="map_iofL2b"\
fbase="20190509T180552S020"\

# Download the OSIRIS-REx image. Note wget can be installed using the command\
# "conda install wget"\
wget -P . "https://sbnarchive.psi.edu/pds4/orex/orex.ocams/data_calibrated/detailed_survey/$\{fbase\}_$\{dtype\}.fits"\

# Import into ISIS\
ocams2isis from="$\{fbase\}_$\{dtype\}.fits" to="$\{fbase\}_pck.cub"\
ocams2isis from="$\{fbase\}_$\{dtype\}.fits" to="$\{fbase\}_dtm.cub"\

spiceinit from="$\{fbase\}_pck.cub" shape=ellipsoid\
spiceinit from="$\{fbase\}_dtm.cub" shape=user model='$osirisrex/kernels/dsk/g_00880mm_alt_ptm_0000n00000_v020.bds' -pref=$ISISROOT/BulletEngineSelect.pref\

# Run cam2cam for each set\
cam2cam from="$\{fbase\}_pck.cub" match="$\{fbase\}_dtm.cub" to="$\{fbase\}_pck_to_dtm_def.cub"\
cam2cam from="$\{fbase\}_pck.cub" match="$\{fbase\}_dtm.cub" to="$\{fbase\}_pck_to_dtm_off.cub" offbody=true offbodytrim=false\
cam2cam from="$\{fbase\}_pck.cub" match="$\{fbase\}_dtm.cub" to="$\{fbase\}_pck_to_dtm_offtrim.cub" offbody=true offbodytrim=true\

cam2cam from="$\{fbase\}_dtm.cub" match="$\{fbase\}_pck.cub" to="$\{fbase\}_dtm_to_pck_def.cub"\
cam2cam from="$\{fbase\}_dtm.cub" match="$\{fbase\}_pck.cub" to="$\{fbase\}_dtm_to_pck_off.cub" offbody=true offbodytrim=false\
cam2cam from="$\{fbase\}_dtm.cub" match="$\{fbase\}_pck.cub" to="$\{fbase\}_dtm_to_pck_offtrim.cub" offbody=true offbodytrim=true\

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 16 additions & 55 deletions isis/src/base/apps/cam2cam/cam2cam.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
/** This is free and unencumbered software released into the public domain.
The authors of ISIS do not claim copyright on the contents of this file.
For more details about the LICENSE terms and the AUTHORS, you will
find files of those names at the top level of this repository. **/

/* SPDX-License-Identifier: CC0-1.0 */

#include <cmath>

#include "cam2cam.h"

#include "Application.h"
#include "Camera.h"
#include "CameraFactory.h"
#include "Distance.h"
#include "ProcessRubberSheet.h"

using namespace std;
Expand Down Expand Up @@ -56,10 +62,15 @@ namespace Isis {
referenceBand += (referenceBand % 2);
referenceBand /= 2;

// See if the user wants to override the reference band
// See if the user wants to override the reference band
if (ui.WasEntered("REFBAND")) {
referenceBand = ui.GetInteger("REFBAND");
}

// Check for propagation of off-body (based upon RA/Dec) pixels as well
// but allow for trimming of off target intersections in FROM file.
bool offbody = ui.GetBoolean("OFFBODY");
bool trim = ui.GetBoolean("OFFBODYTRIM");

// Using the Camera method out of the object opack will not work, because the
// filename required by the Camera is not passed by the process class in this
Expand Down Expand Up @@ -95,7 +106,9 @@ namespace Isis {
cam2camGlobal::incam,
ocube->sampleCount(),
ocube->lineCount(),
outcam);
outcam,
offbody,
trim);

// Add the reference band to the output if necessary
ocube->putGroup(instgrp);
Expand Down Expand Up @@ -127,56 +140,4 @@ namespace Isis {
}


// Transform object constructor
cam2camXform::cam2camXform(const int inputSamples, const int inputLines,
Camera *incam, const int outputSamples,
const int outputLines, Camera *outcam) {
p_inputSamples = inputSamples;
p_inputLines = inputLines;
p_incam = incam;

p_outputSamples = outputSamples;
p_outputLines = outputLines;
p_outcam = outcam;
}

// Transform method mapping output line/samps to lat/lons to input line/samps
bool cam2camXform::Xform(double &inSample, double &inLine,
const double outSample, const double outLine) {
// See if the output image coordinate converts to lat/lon
if (!p_outcam->SetImage(outSample, outLine)) return false;

// Get the universal lat/lon and see if it can be converted to input line/samp
double lat = p_outcam->UniversalLatitude();
double lon = p_outcam->UniversalLongitude();
Distance rad = p_outcam->LocalRadius();
if (rad.isValid()) {
if (!p_incam->SetUniversalGround(lat, lon, rad.meters())) return false;
}
else {
if (!p_incam->SetUniversalGround(lat, lon)) return false;
}

// Make sure the point is inside the input image
if (p_incam->Sample() < 0.5) return false;
if (p_incam->Line() < 0.5) return false;
if (p_incam->Sample() > p_inputSamples + 0.5) return false;
if (p_incam->Line() > p_inputLines + 0.5) return false;

// Everything is good
inSample = p_incam->Sample();
inLine = p_incam->Line();
return true;
}


int cam2camXform::OutputSamples() const {
return p_outputSamples;
}


int cam2camXform::OutputLines() const {
return p_outputLines;
}

}
212 changes: 205 additions & 7 deletions isis/src/base/apps/cam2cam/cam2cam.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
/** This is free and unencumbered software released into the public domain.
The authors of ISIS do not claim copyright on the contents of this file.
For more details about the LICENSE terms and the AUTHORS, you will
find files of those names at the top level of this repository. **/

/* SPDX-License-Identifier: CC0-1.0 */

#ifndef cam2cam_h
#define cam2cam_h

#include <memory>

#include "Transform.h"

#include "Application.h"
#include "Camera.h"
#include "Cube.h"
#include "Distance.h"
#include "UserInterface.h"

namespace Isis {
Expand All @@ -26,21 +36,209 @@ namespace Isis {
int p_inputLines;
int p_outputSamples;
int p_outputLines;
bool p_offbody;
bool p_trim;

public:
// constructor
cam2camXform(const int inputSamples, const int inputLines, Isis::Camera *incam,
const int outputSamples, const int outputLines, Isis::Camera *outcam);
const int outputSamples, const int outputLines, Isis::Camera *outcam,
const bool offbody = false, const bool trim = true) {

p_inputSamples = inputSamples;
p_inputLines = inputLines;
p_incam = incam;

p_outputSamples = outputSamples;
p_outputLines = outputLines;
p_outcam = outcam;
p_offbody = offbody;
p_trim = trim;
}

// destructor
~cam2camXform() {};
virtual ~cam2camXform() {};

/** Transform method mapping output line/samps to lat/lons to input line/samps */
inline bool Xform(double &inSample, double &inLine,
const double outSample, const double outLine) {

// See if the output image coordinate converts to lat/lon
if ( p_outcam->SetImage(outSample, outLine) ) {
// Get the universal lat/lon and see if it can be converted to input line/samp
double lat = p_outcam->UniversalLatitude();
double lon = p_outcam->UniversalLongitude();
Distance rad = p_outcam->LocalRadius();
if (rad.isValid()) {
if(!p_incam->SetUniversalGround(lat, lon, rad.meters())) return false;
}
else {
if(!p_incam->SetUniversalGround(lat, lon)) return false;
}
}
else if ( p_offbody ) {
double ra = p_outcam->RightAscension();
double dec = p_outcam->Declination();
if ( !p_incam->SetRightAscensionDeclination(ra,dec) ) return false;
if ( p_trim ) {
if ( p_incam->SetImage(p_incam->Sample(), p_incam->Line()) ) return (false);
}
}
else {
return false;
}

// Make sure the point is inside the input image
if (p_incam->Sample() < 0.5) return false;
if (p_incam->Line() < 0.5) return false;
if (p_incam->Sample() > p_inputSamples + 0.5) return false;
if (p_incam->Line() > p_inputLines + 0.5) return false;

// Everything is good
inSample = p_incam->Sample();
inLine = p_incam->Line();
return true;
}


inline int OutputSamples() const {
return p_outputSamples;
}


inline int OutputLines() const {
return p_outputLines;
}

};


/**
* @brief Standalone cam2cam pixel mapper functor
*
* This class provides an instance of a standalone implementation of the
* cam2cam mapping algorithm. It is designed to provide single pixel mapping
* of the match/to output image to the from image. Note that the MATCH and TO
* cubes have exactly the same geometry so TO is not required for this
* implementation.
*
* The cam2cam algorithm is output driven by mapping every sample/line pixel
* coordinate in the match image back into the from image FOV.
*
* This class functor is designed to just compute the coordinate in the FROM
* image and determine how it is mapped into the FROM/MATCH paramterization.
* This is well suited for testing the algorithm without significant overhead
* of processing, typically large, ISIS cubes.
*
* It does not create an output cube or interpolation algorithms. Selection of
* input bands is entirely managed by the owner of this object.
*
* Note this should *not* be used as the processing algorithm directly in
* cam2cam because it does not use the RubberSheet mapping algorithm as the
* main app uses. This essentially uses the RubberSheet::SlowGeom() method
* (w/out interpolation!), which is the least efficicent algorithm.
* However it may be applicable in a threaded implementation.
*
* @author 2024-10-27 Kris J. Becker
*/
class Cam2CamMapper {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this class is only used in the tests, can it be moved into FunctionalTestsCam2cam.cpp?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this class has general utility other than strictly testing. All one has to do is add the include file in their own code.

It also keeps the class with the context in which it is designed to model.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If cam2cam was updated to use it I would agree but it isn't currently being used in the codebase, only the test suite.

It also seems like a rewrite of the cam2camXform, could one not use the cam2camXform in the same way that one would use this new class?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, you may be right.

It is odd that it appears the only way to use this externally would require a link to cam2cam.o. It would be more better/useful if the implementation of cam2camXform is entirely in the header.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We could move the xform implementation into the .h as well

public:
Cam2CamMapper( ) : m_from( nullptr ), m_match( nullptr ),
m_offbody( false ),
m_offbodytrim( true ),
m_transform( nullptr ) { }
Cam2CamMapper( Cube *from, Cube *match,
const bool offbody = false,
const bool offbodytrim = true ) :
m_from( from ), m_match( match ),
m_offbody( offbody ),
m_offbodytrim( offbodytrim ),
m_transform( make_mapper() ) { }
~Cam2CamMapper() { }


inline bool IsValid() const {
return ( ( nullptr != m_from ) && ( nullptr != m_match ) && ( nullptr != m_transform.get() ) );
}

inline Cube *from( ) {
return ( m_from );
}

inline Cube *match( ) {
return ( m_match );
}

// Override parent's pure virtual members
bool Xform(double &inSample, double &inLine,
const double outSample, const double outLine);
int OutputSamples() const;
int OutputLines() const;
inline Camera *from_camera( ) {
return ( m_from->camera() );
}

inline Camera *match_camera( ) {
return ( m_match->camera() );
}

inline Transform *transform( ) {
return ( m_transform.get() );
}

inline bool offbody() const {
return ( m_offbody );
}

inline bool offbodytrim() const {
return ( m_offbodytrim );
}

/** Allocate a custom cam2map mapper transform */
inline Transform *make_mapper( const bool offbody, const bool offbodytrim) const {
if ( nullptr == m_from ) {
throw IException( IException::Programmer, "FROM cube is not valid!", _FILEINFO_ );
}

if ( nullptr == m_match ) {
throw IException( IException::Programmer, "MATCH cube is not valid!", _FILEINFO_ );
}

// Compute the transform
Transform *v_t = new cam2camXform( m_from->sampleCount(),
m_from->lineCount(),
m_from->camera(),
m_match->sampleCount(),
m_match->lineCount(),
m_match->camera(),
offbody,
offbodytrim );

// Check if we were successful
if ( nullptr == v_t ) {
QString mess = "Unable to allocate cam2map mapper for FROM (" + m_from->fileName() +
") and MATCH (" + m_match->fileName() + ")";
throw IException( IException::Programmer, mess, _FILEINFO_ );
}

return ( v_t );
}

/** Allocate a cam2map mapper transform with configured state */
inline Transform *make_mapper( ) const {
return ( make_mapper( m_offbody, m_offbodytrim ) );
}

/** Mapping method for (out)MATCH->(in)FROM pixel coordinates */
inline bool mapit( double &inSample, double &inLine,
const double outSample, const double outLine ) {
return ( m_transform->Xform( inSample, inLine, outSample, outLine ) );
}

private:
Cube *m_from;
Cube *m_match;
bool m_offbody;
bool m_offbodytrim;
std::shared_ptr<Transform> m_transform;
};


}

#endif
Loading