Unverified Commit ae1d6465 authored by jcwbacker's avatar jcwbacker Committed by GitHub
Browse files

Merge pull request #450 from jcwbacker/lroc

Added Clementine UVVIS distortion model.
parents d7ca21df 65115dde
Loading
Loading
Loading
Loading
+49 −28
Original line number Diff line number Diff line
#include "Isis.h"

#include <cstdio>

#include <QString>

#include "pds.h"
#include "ProcessByLine.h"
#include "PvlToPvlTranslationManager.h"
#include "SpecialPixel.h"
#include "UserInterface.h"
#include "FileName.h"
#include "IException.h"
#include "iTime.h"
#include "Preference.h"
#include "IString.h"
#include "OriginalLabel.h"
#include "pds.h"
#include "Preference.h"
#include "ProcessByLine.h"
#include "PvlToPvlTranslationManager.h"
#include "SpecialPixel.h"
#include "UserInterface.h"

using namespace std;
using namespace Isis;

void WriteLine(Buffer &b);
void TranslateLabels(FileName in, Cube *ocube);
void writeLine(Buffer &b);
void translateLabels(FileName in, Cube *ocube);
PDSINFO *pdsi;

void IsisMain() {
@@ -64,13 +65,13 @@ void IsisMain() {
  ProcessByLine p;
  CubeAttributeOutput cubeAtt("+unsignedByte+1.0:254.0");
  Cube *ocube = p.SetOutputCube(ui.GetFileName("TO"), cubeAtt, pdsi->image_ncols, pdsi->image_nrows);
  p.StartProcess(WriteLine);
  TranslateLabels(in, ocube);
  p.StartProcess(writeLine);
  translateLabels(in, ocube);
  p.EndProcess();
}

//Function to move uncompressed data to a cube
void WriteLine(Buffer &b) {
void writeLine(Buffer &b) {
  for (int i = 0; i < pdsi->image_ncols; i++) {
    double d = pdsi->image[((b.Line()-1)*pdsi->image_ncols) + i];
    if (d <= 0.0) {
@@ -85,6 +86,7 @@ void WriteLine(Buffer &b) {
  }
}


/**
 *  Function to propagate the labels.
 *
@@ -95,7 +97,7 @@ void WriteLine(Buffer &b) {
 *
 */

void TranslateLabels(FileName in, Cube *ocube) {
void translateLabels(FileName in, Cube *ocube) {
  // Get the directory where the Clementine translation tables are.
  PvlGroup &dataDir = Preference::Preferences().findGroup("DataDirectory");

@@ -149,7 +151,26 @@ void TranslateLabels(FileName in, Cube *ocube) {
    kern += PvlKeyword("NaifFrameCode", "-40001");
  }
  if (((QString)inst["InstrumentId"]) == "UVVIS") {
    kern += PvlKeyword("NaifFrameCode", "-40002");
    // JAA & VS ... modified to support variable focal length and optical
    // distortion for UVVIS
    if (filter == "A") {
      kern += PvlKeyword("NaifFrameCode", "-40021");
    }
    if (filter == "B") {
      kern += PvlKeyword("NaifFrameCode", "-40022");
    }
    if (filter == "C") {
      kern += PvlKeyword("NaifFrameCode", "-40023");
    }
    if (filter == "D") {
      kern += PvlKeyword("NaifFrameCode", "-40024");
    }
    if (filter == "E") {
      kern += PvlKeyword("NaifFrameCode", "-40025");
    }
    if (filter == "F") {
      kern += PvlKeyword("NaifFrameCode", "-40026");
    }
  }
  if (((QString)inst["InstrumentId"]) == "NIR") {
    kern += PvlKeyword("NaifFrameCode", "-40003");
+7 −0
Original line number Diff line number Diff line
@@ -72,6 +72,13 @@
      Modified label transfer to include MCP_Gain_Mode_ID when images is from 
      HIRES camera.
    </change>
    <change name="Jeff Anderson and Victor Silva" date="2017-12-27">
      Modified Kernels group to support filter dependent focal length and optical distortion 
      for UVVIS camera.
    </change>
    <change name="Jeannie Backer" date="2018-09-01">
      Added documentation, brought closer to coding standards and merged into public repo.
    </change>
  </history>

  <groups>
+195 −0
Original line number Diff line number Diff line
/**
 * @file
 * $Revision: 1.19 $
 * $Date: 2010/03/22 19:44:53 $
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are
 *   public domain. See individual third-party library and package descriptions
 *   for intellectual property information, user agreements, and related
 *   information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or
 *   implied, is made by the USGS as to the accuracy and functioning of such
 *   software and related material nor shall the fact of distribution
 *   constitute any such warranty, and no responsibility is assumed by the
 *   USGS in connection therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
 *   in a browser or see the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */

#include <iomanip>

#include "CameraFocalPlaneMap.h"
#include "ClementineUvvisDistortionMap.h"

using namespace std;

namespace Isis {
  /** 
   * Construct a distortion map for the Clementine UVVIS instrument. 
   *  
   * @param parent Camera object corresponding to this distortion map. 
   * @param xp The x coordinate for the principal point offset.
   * @param yp The y coordinate for the principal point offset. 
   * @param k1 The constant term coefficient for the radial distortion 
   *           contribution polynomial.
   * @param k2 The linear term coefficient for the radial distortion 
   *           contribution polynomial.
   * @param k3 The quadratic term coefficient for the radial distortion 
   *           contribution polynomial.
   * @param p1 First decentering distortion term.
   * @param p2 Second decentering distortion term.
   *  
   */ 
  ClementineUvvisDistortionMap::ClementineUvvisDistortionMap(Camera *parent,
                                                             double xp, double yp,
                                                             double k1, double k2, double k3,
                                                             double p1, double p2) :
      CameraDistortionMap(parent, 1.0) {

    p_xp = xp;
    p_yp = yp;
    p_k1 = k1;
    p_k2 = k2;
    p_k3 = k3;
    p_p1 = p1;
    p_p2 = p2;

  }


  /** 
   * Deconstruct the distortion map for the Clementine UVVIS instrument. 
   */ 
  ClementineUvvisDistortionMap::~ClementineUvvisDistortionMap() {
  }


  /**
   * Compute undistorted focal plane x/y
   *
   * Compute undistorted focal plane x/y given a distorted focal plane x/y.
   * after calling this method, you can obtain the undistorted
   * x/y via the UndistortedFocalPlaneX and UndistortedFocalPlaneY methods
   *
   * @param dx Distorted focal plane x in millimeters.
   * @param dy Distorted focal plane y in millimeters.
   *
   * @return @b bool Indicates whether the conversion was successful.
   */
  bool ClementineUvvisDistortionMap::SetFocalPlane(const double dx, const double dy) {
    p_focalPlaneX = dx;
    p_focalPlaneY = dy;

    // reducing to principal point offset (xp,yp)
    double x = dx - p_xp;
    double y = dy - p_yp;

//    std::cout << setprecision(14) << " dx " << dx << " dy " << dy << " p_xp " << p_xp << " p_yp " << p_yp;
    // r is the distance between the principal point and the measured point on the image
    double rr = x * x + y * y;
//    std::cout << " rr " << rr << " r " << sqrt(rr);

    //  dr is the radial distortion contribution
    double dr = p_k1 + p_k2 * rr + p_k3 * rr * rr;
//    std::cout << " dr " << dr;

    // dtx and dty are the decentering distortion contribution in x and y
    double dtx = p_p1 * (rr + 2.0 * x * x) + 2.0 * p_p2 * x * y;
    double dty = 2.0 * p_p1 * x * y + p_p2 * (rr + 2 * y * y);
//    std::cout << " dtx " << dtx << " dty " << dty << std::endl;

    // image coordinates corrected for principal point, radial and decentering distortion (p1,p2,p3)
    p_undistortedFocalPlaneX = dx + x * dr + dtx;
    p_undistortedFocalPlaneY = dy + y * dr + dty;

    return true;
  }


  /**
   * Compute distorted focal plane x/y
   *
   * Compute distorted focal plane x/y given an undistorted focal plane x/y.
   * After calling this method, you can obtain the distorted x/y via the
   * FocalPlaneX and FocalPlaneY methods
   *
   * @param ux undistorted focal plane x in millimeters
   * @param uy undistorted focal plane y in millimeters
   *
   * @return if the conversion was successful
   */
  bool ClementineUvvisDistortionMap::SetUndistortedFocalPlane(const double ux, const double uy) {

    double xt = ux;
    double yt = uy;

    double xx, yy, rr, dr;
    double xdistortion, ydistortion;
    double xdistorted, ydistorted;
    double xprevious, yprevious;
    
    //  dr is the radial distortion contribution
    //  dtx and dty are the decentering distortion contributions in x and y
   
    xprevious = 1000000.0;
    yprevious = 1000000.0;

    double tolerance = 0.000001;

    bool bConverged = false;

    // iterating to introduce distortion...
    // we stop when the difference between distorted coordinates
    // in successive iterations is at or below the given tolerance
    for (int i = 0; i < 50; i++) {
      xx = xt * xt;
      yy = yt * yt;
      rr = xx + yy;

      // radial distortion
      //  dr is the radial distortion contribution
      // -dt*sin(p_t0) is the decentering distortion contribution in the x-direction
      //  dt*cos(p_t0) is the decentering distortion contribution in the y-direction
      dr = p_k1 + p_k2 * rr + p_k3 * rr * rr;

      double dtx = p_p1 * (rr + 2.0 * xt * xt) + 2.0 * p_p2 * xt * yt;
      double dty = 2.0 * p_p1 * xt * yt + p_p2 * (rr + 2 * yt * yt);

      // distortion at the current point location
      xdistortion = dr * xt + dtx;
      ydistortion = dr * yt + dty;

      // updated image coordinates
      xt = ux - xdistortion;
      yt = uy - ydistortion;

      // distorted point corrected for principal point
      xdistorted = xt + p_xp;
      ydistorted = yt + p_yp;

      // check for convergence
      if ((fabs(xt - xprevious) <= tolerance) && (fabs(yt - yprevious) <= tolerance)) {
        bConverged = true;
        break;
      }

      xprevious = xt;
      yprevious = yt;
    }

    if (bConverged) {
      p_undistortedFocalPlaneX = ux;
      p_undistortedFocalPlaneY = uy;

      p_focalPlaneX = xdistorted;
      p_focalPlaneY = ydistorted;
    }

    return bConverged;
  }
}
+68 −0
Original line number Diff line number Diff line
#ifndef ClementineUvvisDistortionMap_h
#define ClementineUvvisDistortionMap_h

/**
 * @file
 * $Revision: 1.17 $
 * $Date: 2010/03/22 19:44:53 $
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are
 *   public domain. See individual third-party library and package descriptions
 *   for intellectual property information, user agreements, and related
 *   information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or
 *   implied, is made by the USGS as to the accuracy and functioning of such
 *   software and related material nor shall the fact of distribution
 *   constitute any such warranty, and no responsibility is assumed by the
 *   USGS in connection therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
 *   in a browser or see the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */


#include "Camera.h"
#include "CameraDistortionMap.h"

namespace Isis {

  /**
   * @brief Distortion map for the Clementine UVVIS camera
   *
   * This class is was copied from the Chandrayaan1 M3 camera model as its distortion map.
   * Equations provided by Randy Kirk and code provided by Ken Edmundson.
   *
   * @ingroup Camera
   *
   * @author 2017-12-27 Jeff Anderson & Victor Silva
   *
   * @internal
   *   @history 2017-12-27 Jeff Anderson & Victor Silva - Copied code from Chandrayaan1 M3 camera.
   *   @history 2018-09-01 Jeannie Backer - Added documentation and merged into public repo.
   */

  class ClementineUvvisDistortionMap : public CameraDistortionMap {
    public:
      ClementineUvvisDistortionMap(Camera *parent, double xp, double yp,
                                  double k1, double k2, double k3,
                                  double p1, double p2);
      ~ClementineUvvisDistortionMap();

      bool SetFocalPlane(const double dx, const double dy);
      bool SetUndistortedFocalPlane(const double ux, const double uy);

    private: // parameters below are from camera calibration report
      double p_xp; //!< Principal point x coordinate.
      double p_yp; //!< Principal point y coordinate.
      double p_k1; //!< Constant term coefficient of radial distortion.
      double p_k2; //!< Linear term coefficient of radial distortion.
      double p_k3; //!< Quadratic term coefficient of radial distortion.
      double p_p1; //!< First coefficient of decentering distortion.
      double p_p2; //!< Second coefficient of decentering distortion.
  };
};
#endif
+12 −2
Original line number Diff line number Diff line
@@ -23,10 +23,10 @@
#include <QString>

#include "CameraDetectorMap.h"
#include "CameraDistortionMap.h"
#include "CameraFocalPlaneMap.h"
#include "CameraGroundMap.h"
#include "CameraSkyMap.h"
#include "ClementineUvvisDistortionMap.h"
#include "IString.h"
#include "iTime.h"
#include "NaifStatus.h"
@@ -79,8 +79,17 @@ namespace Isis {
      Spice::getDouble("INS" + toString(naifIkCode()) + 
                       "_BORESIGHT_LINE"));

    QString ppKey("INS" + toString(naifIkCode()) + "_PP");
    QString odKey("INS" + toString(naifIkCode()) + "_OD_K");
    QString decenterKey("INS" + toString(naifIkCode()) + "_DECENTER");

    // Setup distortion map
    new CameraDistortionMap(this);
    new ClementineUvvisDistortionMap(this, 
                                    getDouble(ppKey, 0), getDouble(ppKey, 1),
                                    getDouble(odKey, 0), getDouble(odKey, 1), getDouble(odKey, 2),
                                    getDouble(decenterKey, 0), getDouble(decenterKey, 1));



    // Setup the ground and sky map
    new CameraGroundMap(this);
@@ -91,6 +100,7 @@ namespace Isis {
    NaifStatus::CheckErrors();
  }


  /**
   * Returns the shutter open and close times. The user should pass in the
   * ExposureDuration keyword value, converted to seconds, and the StartTime
Loading