Loading isis/src/juno/objs/JunoCamera/Camera.plugin 0 → 100644 +6 −0 Original line number Diff line number Diff line Group = JUNO/JNC Version = 1 Library = JunoCamera Routine = JunoCameraPlugin EndGroup isis/src/juno/objs/JunoCamera/JunoCamera.cpp 0 → 100644 +209 −0 Original line number Diff line number Diff line /** * @file * $Revision:$ * $Date:$ * * 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 & 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 "JunoCamera.h" #include <QDebug> #include <QString> #include "CameraDetectorMap.h" #include "CameraFocalPlaneMap.h" #include "CameraGroundMap.h" #include "CameraSkyMap.h" #include "iTime.h" #include "JunoDistortionMap.h" #include "NaifStatus.h" using namespace std; namespace Isis { /** * @brief Initialize the Juno camera model * * * @param cube The image cube. */ JunoCamera::JunoCamera(Cube &cube) : FramingCamera(cube) { m_instrumentNameLong = "Juno EPO Camera"; m_instrumentNameShort = "JNC"; // or JunoCam? m_spacecraftNameLong = "Juno"; m_spacecraftNameShort = "Juno"; NaifStatus::CheckErrors(); // Set up the camera characteristics instrumentRotation()->SetFrame( CkFrameId() ); SetFocalLength(); SetPixelPitch(); // Get all the necessary stuff from the labels Pvl &lab = *cube.label(); const PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse); // Get summing mode // Summing modes are: // 1 = 1x1 (No summing) // 2 = 2x2 int sumMode = (int) inst["SummingMode"]; int summing = sumMode; // Setup camera detector map CameraDetectorMap *detMap = new CameraDetectorMap(this); if ( summing > 0 ) { detMap->SetDetectorSampleSumming(summing); detMap->SetDetectorLineSumming(summing); } // Juno codes int junoCode = naifIkCode(); QString juno = toString(junoCode); // Setup focal plane map and set Juno detector boresight new CameraFocalPlaneMap(this, junoCode); CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, junoCode); double bsSample = getDouble("INS" + juno + "_BORESIGHT_SAMPLE"); double bsLine = getDouble("INS" + juno + "_BORESIGHT_LINE"); focalMap->SetDetectorOrigin(bsSample, bsLine); // Set starting filter location on the detector const PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse); QString filterIkCode = bandBin.findKeyword("NaifIkCode")[0]; detMap->SetStartingDetectorLine(getDouble("INS" + filterIkCode + "_FILTER_OFFSET")); // Set up distortion map, keeping z-direction positive JunoDistortion map defaults to z+ JunoDistortionMap *distortionMap = new JunoDistortionMap(this); distortionMap->SetDistortion(CkFrameId()); // Setup the ground and sky map new CameraGroundMap(this); new CameraSkyMap(this); // Set time based on clock count, frame number, exposure duration, and interframe delay QString startClockCount = inst["SpacecraftClockStartCount"]; double observationStartEt = getClockTime(startClockCount).Et(); // in seconds double frameNumber = (double) inst["FrameNumber"]; double interFrameDelay = (double) inst["InterFrameDelay"]; // in seconds double exposureDur = ((double) inst["ExposureDuration"]) / 1000.0; // in seconds // Get the fixed time biases double startTimeBias = getDouble("INS" + juno + "_START_TIME_BIAS"); double interFrameDelayBias = getDouble("INS" + juno + "_INTERFRAME_DELTA"); // get start et for this frame, in seconds double frameStartEt = observationStartEt + startTimeBias + (frameNumber - 1) * (exposureDur + interFrameDelay + interFrameDelayBias); // Set start time to center of exposure time to ensure the proper SPICE data is cached. setTime(frameStartEt + exposureDur / 2.0); LoadCache(); NaifStatus::CheckErrors(); } /** * Destroys the JunoCamera object. */ JunoCamera::~JunoCamera() { } /** * Returns the shutter open and close times. The user should pass in the * ExposureDuration keyword value, converted from milliseconds to seconds, and * the SpacecraftClockCount keyword value, converted to ephemeris time. The * StartTime keyword value from the labels represents the shutter open time of * the observation. This method uses the FramingCamera class implementation, * returning the given time value as the shutter open and the sum of the time * value and exposure duration as the shutter close. * * @param exposureDuration Exposure duration value from the labels, converted * to seconds. * @param time The SpacecraftClockCount value from the labels, converted to * ephemeris time * * @return @b pair < @b iTime, @b iTime > The first value is the shutter * open time and the second is the shutter close time. */ pair <iTime, iTime> JunoCamera::ShutterOpenCloseTimes(double time, double exposureDuration) { return FramingCamera::ShutterOpenCloseTimes(time, exposureDuration); } /** * Retrieves the CK frame ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the "Camera-matrix" * Kernel Frame ID. */ int JunoCamera::CkFrameId() const { return -61500; } /** * Retrieves the J2000 CK Reference ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the "Camera-matrix" * Kernel Reference ID. */ int JunoCamera::CkReferenceId() const { return 1; } /** * Retrieves the SPK Target Body ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the Spacecraft * Kernel Target ID. */ int JunoCamera::SpkTargetId() const { return -61; } /** * Retrieves the J2000 SPK Reference ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the Spacecraft * Kernel Reference ID. */ int JunoCamera::SpkReferenceId() const { return 1; } } /** * This is the function that is called in order to instantiate a JunoCamera * object. * * @param cube The image cube. * * @return Isis::Camera* JunoCamera */ extern "C" Isis::Camera *JunoCameraPlugin(Isis::Cube &cube) { return new Isis::JunoCamera(cube); } isis/src/juno/objs/JunoCamera/JunoCamera.h 0 → 100644 +59 −0 Original line number Diff line number Diff line #ifndef JunoCamera_h #define JunoCamera_h /** * @file * $Revision: $ * $Date: $ * * 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 & 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 "FramingCamera.h" #include <QString> namespace Isis { /** * @brief Juno's JNC (JunoCam) camera model * * This is the camera model for the JunoCam instrument. This * instrument is technically a pushframe instrument, but it is treated as a * framing instrument. This is * also a more flexible camera model since it will make controlling the * individual framelets alot easier. * * @ingroup SpiceInstrumentsAndCameras * @ingroup Juno * @author 2017-07-22 Jeannie Backer * * @internal * @history 2017-07-22 Jeannie Backer - Original version. */ class JunoCamera : public FramingCamera { public: JunoCamera(Cube &cube); ~JunoCamera(); virtual std::pair <iTime, iTime> ShutterOpenCloseTimes(double time, double exposureDuration); virtual int CkFrameId() const; virtual int CkReferenceId() const; virtual int SpkTargetId() const; virtual int SpkReferenceId() const; }; }; #endif isis/src/juno/objs/JunoCamera/JunoCamera.truth 0 → 100644 +33 −0 Original line number Diff line number Diff line Unit Test for JunoCamera... FileName: "JNCE_2013282_00M00099_V01_BLUE_0004.cub" CK Frame: -61500 Kernel IDs: CK Frame ID = -61500 CK Reference ID = 1 SPK Target ID = -61 SPK Reference ID = 1 Shutter open = 434617659.036347926 Shutter close = 434617668.63634795 Focal Length = 10.9563699999999997 For upper left corner ... DeltaSample = 0 DeltaLine = 0 For upper right corner ... DeltaSample = 0 DeltaLine = 0 For lower left corner ... DeltaSample = 0 DeltaLine = 0 For lower right corner ... DeltaSample = 0 DeltaLine = 0 For center pixel position ... Latitude OK Longitude OK isis/src/juno/objs/JunoCamera/JunoDistortionMap.cpp 0 → 100644 +217 −0 Original line number Diff line number Diff line /** * @file * $Revision: 1.4 $ * $Date: 2008/02/21 16:04:33 $ * * 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 & 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 "IString.h" #include "JunoDistortionMap.h" namespace Isis { /** * Juno JunoCam distortion map constructor * * Create a distortion map for Juno's JunoCam camera. This class maps between distorted * and undistorted focal plane x/y's. The default mapping is the * identity, that is, the focal plane x/y and undistorted focal plane * x/y will be identical. The Z direction is set internally to positive for * JunoCam. * * @param parent the parent camera that will use this distortion map * */ JunoDistortionMap::JunoDistortionMap(Camera *parent) : CameraDistortionMap(parent, 1.0) { } /** * Destructor */ JunoDistortionMap::~JunoDistortionMap() { } /** * Load distortion coefficients for JunoCam * * This method loads the distortion coefficients from the instrument * kernel. JunoCam's coefficients in the NAIF instrument kernel are * expected to be in the form of: * * @code * INS-61500_DISTORTION_K0 = coefficient, index 0 * INS-61500_DISTORTION_K1 = coefficient, index 1 * INS-61500_DISTORTION_K2 = coefficient, index 2 * @endcode * * These coefficients are designed for use with pixel coordinates, so they * are scaled based on the pixel pitch to operate in focal plane millimeters. * These coefficient will be used to convert from undistorted focal plane x,y * to distorted focal plane x,y as follows * * @code * r2 = r2 = (ux * ux) + (uy * uy); * dr = 1 + INS-61500_DISTORTION_K0 + INS-61500_DISTORTION_K1*r2 +INS-61500_DISTORTION_K2*r2*r2; * dx = ux * dr; * dy = uy * dr; * @endcode * * @param naifIkCode Code to search for in instrument kernel */ void JunoDistortionMap::SetDistortion(int naifIkCode) { // Use the pixel pitch to scale k1 and k2 coefficients to operate in focal // plane coordinates (millimeters). The coefficients found in the kernels // are based on detector coordinates (pixels). double pp = p_camera->PixelPitch(); double p2 = pp * pp; // Currently k0 is non-existant in kernels (i.e equals zero). The try is // here in case this coefficient is needed for future distortion models. try { QString odk0 = "INS" + toString(naifIkCode) + "_DISTORTION_K0"; p_odk.push_back(p_camera->Spice::getDouble(odk0)); } catch (IException &e) { p_odk.push_back(0.0); } QString odk1 = "INS" + toString(naifIkCode) + "_DISTORTION_K1"; p_odk.push_back(p_camera->Spice::getDouble(odk1) / p2); QString odk2 = "INS" + toString(naifIkCode) + "_DISTORTION_K2"; p_odk.push_back(p_camera->Spice::getDouble(odk2) / (p2 * p2)); } /** * Compute distorted focal plane x/y * * Compute distorted focal plane x/y given an undistorted focal plane x/y. * This virtual method is used to apply various techniques for adding * optical distortion in the focal plane of a camera. The default * implementation of this virtual method uses a polynomial distortion if * the SetDistortion method was invoked. * 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 @b if the conversion was successful * * @see SetDistortion */ bool JunoDistortionMap::SetUndistortedFocalPlane(const double ux, const double uy) { p_undistortedFocalPlaneX = ux; p_undistortedFocalPlaneY = uy; // Compute the distance from the focal plane center and if we are // close to the center then assume no distortion double r2 = (ux * ux) + (uy * uy); if (r2 <= 1.0E-6) { p_focalPlaneX = ux; p_focalPlaneY = uy; return true; } // The equation given in the IK computes the undistorted focal plane // ux = dx * (1 + k1*r^2), r^2 = dx^2 + dy^2 double dr = 1 + p_odk[0] + p_odk[1]*r2 + p_odk[2]*r2*r2; p_focalPlaneX = ux * dr; p_focalPlaneY = uy * dr; return true; } /** * Compute undistorted focal plane x/y * * Compute undistorted focal plane x/y given a distorted focal plane x/y. * This virtual method can be used to apply various techniques for removing * optical distortion in the focal plane of a camera. The default * implementation uses a polynomial distortion if the SetDistortion method * is invoked. 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 if the conversion was successful * @see SetDistortion * @todo Generalize polynomial equation */ bool JunoDistortionMap::SetFocalPlane(double dx, double dy) { p_focalPlaneX = dx; p_focalPlaneY = dy; // Get the distance from the focal plane center and if we are close // then skip the distortion double r2 = (dx * dx) + (dy * dy); if (r2 <= 1.0E-6) { p_undistortedFocalPlaneX = dx; p_undistortedFocalPlaneY = dy; return true; } bool converged = false; int i = 0; int maximumIterations = 15; double tolerance = p_camera->PixelPitch() / 100.0; double uxEstimate = dx; double uyEstimate = dy; double uxPrev = dx; double uyPrev = dy; double xDistortion = 0.0; double yDistortion = 0.0; double dr = 0.0; while (!converged) { dr = p_odk[0] + p_odk[1]*r2 + p_odk[2]*r2*r2; xDistortion = uxEstimate * dr; yDistortion = uyEstimate * dr; uxEstimate = dx - xDistortion; uyEstimate = dy - yDistortion; i++; if (fabs(uxEstimate - uxPrev) < tolerance && fabs(uyEstimate - uyPrev) < tolerance ) { converged = true; } // If doesn't converge, don't do correction if (i > maximumIterations) { p_undistortedFocalPlaneX = dx; p_undistortedFocalPlaneY = dy; break; } r2 = (uxEstimate * uxEstimate) + (uyEstimate * uyEstimate); uxPrev = uxEstimate; uyPrev = uyEstimate; } p_undistortedFocalPlaneX = uxEstimate; p_undistortedFocalPlaneY = uyEstimate; return true; } } Loading
isis/src/juno/objs/JunoCamera/Camera.plugin 0 → 100644 +6 −0 Original line number Diff line number Diff line Group = JUNO/JNC Version = 1 Library = JunoCamera Routine = JunoCameraPlugin EndGroup
isis/src/juno/objs/JunoCamera/JunoCamera.cpp 0 → 100644 +209 −0 Original line number Diff line number Diff line /** * @file * $Revision:$ * $Date:$ * * 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 & 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 "JunoCamera.h" #include <QDebug> #include <QString> #include "CameraDetectorMap.h" #include "CameraFocalPlaneMap.h" #include "CameraGroundMap.h" #include "CameraSkyMap.h" #include "iTime.h" #include "JunoDistortionMap.h" #include "NaifStatus.h" using namespace std; namespace Isis { /** * @brief Initialize the Juno camera model * * * @param cube The image cube. */ JunoCamera::JunoCamera(Cube &cube) : FramingCamera(cube) { m_instrumentNameLong = "Juno EPO Camera"; m_instrumentNameShort = "JNC"; // or JunoCam? m_spacecraftNameLong = "Juno"; m_spacecraftNameShort = "Juno"; NaifStatus::CheckErrors(); // Set up the camera characteristics instrumentRotation()->SetFrame( CkFrameId() ); SetFocalLength(); SetPixelPitch(); // Get all the necessary stuff from the labels Pvl &lab = *cube.label(); const PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse); // Get summing mode // Summing modes are: // 1 = 1x1 (No summing) // 2 = 2x2 int sumMode = (int) inst["SummingMode"]; int summing = sumMode; // Setup camera detector map CameraDetectorMap *detMap = new CameraDetectorMap(this); if ( summing > 0 ) { detMap->SetDetectorSampleSumming(summing); detMap->SetDetectorLineSumming(summing); } // Juno codes int junoCode = naifIkCode(); QString juno = toString(junoCode); // Setup focal plane map and set Juno detector boresight new CameraFocalPlaneMap(this, junoCode); CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, junoCode); double bsSample = getDouble("INS" + juno + "_BORESIGHT_SAMPLE"); double bsLine = getDouble("INS" + juno + "_BORESIGHT_LINE"); focalMap->SetDetectorOrigin(bsSample, bsLine); // Set starting filter location on the detector const PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse); QString filterIkCode = bandBin.findKeyword("NaifIkCode")[0]; detMap->SetStartingDetectorLine(getDouble("INS" + filterIkCode + "_FILTER_OFFSET")); // Set up distortion map, keeping z-direction positive JunoDistortion map defaults to z+ JunoDistortionMap *distortionMap = new JunoDistortionMap(this); distortionMap->SetDistortion(CkFrameId()); // Setup the ground and sky map new CameraGroundMap(this); new CameraSkyMap(this); // Set time based on clock count, frame number, exposure duration, and interframe delay QString startClockCount = inst["SpacecraftClockStartCount"]; double observationStartEt = getClockTime(startClockCount).Et(); // in seconds double frameNumber = (double) inst["FrameNumber"]; double interFrameDelay = (double) inst["InterFrameDelay"]; // in seconds double exposureDur = ((double) inst["ExposureDuration"]) / 1000.0; // in seconds // Get the fixed time biases double startTimeBias = getDouble("INS" + juno + "_START_TIME_BIAS"); double interFrameDelayBias = getDouble("INS" + juno + "_INTERFRAME_DELTA"); // get start et for this frame, in seconds double frameStartEt = observationStartEt + startTimeBias + (frameNumber - 1) * (exposureDur + interFrameDelay + interFrameDelayBias); // Set start time to center of exposure time to ensure the proper SPICE data is cached. setTime(frameStartEt + exposureDur / 2.0); LoadCache(); NaifStatus::CheckErrors(); } /** * Destroys the JunoCamera object. */ JunoCamera::~JunoCamera() { } /** * Returns the shutter open and close times. The user should pass in the * ExposureDuration keyword value, converted from milliseconds to seconds, and * the SpacecraftClockCount keyword value, converted to ephemeris time. The * StartTime keyword value from the labels represents the shutter open time of * the observation. This method uses the FramingCamera class implementation, * returning the given time value as the shutter open and the sum of the time * value and exposure duration as the shutter close. * * @param exposureDuration Exposure duration value from the labels, converted * to seconds. * @param time The SpacecraftClockCount value from the labels, converted to * ephemeris time * * @return @b pair < @b iTime, @b iTime > The first value is the shutter * open time and the second is the shutter close time. */ pair <iTime, iTime> JunoCamera::ShutterOpenCloseTimes(double time, double exposureDuration) { return FramingCamera::ShutterOpenCloseTimes(time, exposureDuration); } /** * Retrieves the CK frame ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the "Camera-matrix" * Kernel Frame ID. */ int JunoCamera::CkFrameId() const { return -61500; } /** * Retrieves the J2000 CK Reference ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the "Camera-matrix" * Kernel Reference ID. */ int JunoCamera::CkReferenceId() const { return 1; } /** * Retrieves the SPK Target Body ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the Spacecraft * Kernel Target ID. */ int JunoCamera::SpkTargetId() const { return -61; } /** * Retrieves the J2000 SPK Reference ID for the JunoCam instrument. * * @return @b int The appropriate instrument code for the Spacecraft * Kernel Reference ID. */ int JunoCamera::SpkReferenceId() const { return 1; } } /** * This is the function that is called in order to instantiate a JunoCamera * object. * * @param cube The image cube. * * @return Isis::Camera* JunoCamera */ extern "C" Isis::Camera *JunoCameraPlugin(Isis::Cube &cube) { return new Isis::JunoCamera(cube); }
isis/src/juno/objs/JunoCamera/JunoCamera.h 0 → 100644 +59 −0 Original line number Diff line number Diff line #ifndef JunoCamera_h #define JunoCamera_h /** * @file * $Revision: $ * $Date: $ * * 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 & 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 "FramingCamera.h" #include <QString> namespace Isis { /** * @brief Juno's JNC (JunoCam) camera model * * This is the camera model for the JunoCam instrument. This * instrument is technically a pushframe instrument, but it is treated as a * framing instrument. This is * also a more flexible camera model since it will make controlling the * individual framelets alot easier. * * @ingroup SpiceInstrumentsAndCameras * @ingroup Juno * @author 2017-07-22 Jeannie Backer * * @internal * @history 2017-07-22 Jeannie Backer - Original version. */ class JunoCamera : public FramingCamera { public: JunoCamera(Cube &cube); ~JunoCamera(); virtual std::pair <iTime, iTime> ShutterOpenCloseTimes(double time, double exposureDuration); virtual int CkFrameId() const; virtual int CkReferenceId() const; virtual int SpkTargetId() const; virtual int SpkReferenceId() const; }; }; #endif
isis/src/juno/objs/JunoCamera/JunoCamera.truth 0 → 100644 +33 −0 Original line number Diff line number Diff line Unit Test for JunoCamera... FileName: "JNCE_2013282_00M00099_V01_BLUE_0004.cub" CK Frame: -61500 Kernel IDs: CK Frame ID = -61500 CK Reference ID = 1 SPK Target ID = -61 SPK Reference ID = 1 Shutter open = 434617659.036347926 Shutter close = 434617668.63634795 Focal Length = 10.9563699999999997 For upper left corner ... DeltaSample = 0 DeltaLine = 0 For upper right corner ... DeltaSample = 0 DeltaLine = 0 For lower left corner ... DeltaSample = 0 DeltaLine = 0 For lower right corner ... DeltaSample = 0 DeltaLine = 0 For center pixel position ... Latitude OK Longitude OK
isis/src/juno/objs/JunoCamera/JunoDistortionMap.cpp 0 → 100644 +217 −0 Original line number Diff line number Diff line /** * @file * $Revision: 1.4 $ * $Date: 2008/02/21 16:04:33 $ * * 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 & 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 "IString.h" #include "JunoDistortionMap.h" namespace Isis { /** * Juno JunoCam distortion map constructor * * Create a distortion map for Juno's JunoCam camera. This class maps between distorted * and undistorted focal plane x/y's. The default mapping is the * identity, that is, the focal plane x/y and undistorted focal plane * x/y will be identical. The Z direction is set internally to positive for * JunoCam. * * @param parent the parent camera that will use this distortion map * */ JunoDistortionMap::JunoDistortionMap(Camera *parent) : CameraDistortionMap(parent, 1.0) { } /** * Destructor */ JunoDistortionMap::~JunoDistortionMap() { } /** * Load distortion coefficients for JunoCam * * This method loads the distortion coefficients from the instrument * kernel. JunoCam's coefficients in the NAIF instrument kernel are * expected to be in the form of: * * @code * INS-61500_DISTORTION_K0 = coefficient, index 0 * INS-61500_DISTORTION_K1 = coefficient, index 1 * INS-61500_DISTORTION_K2 = coefficient, index 2 * @endcode * * These coefficients are designed for use with pixel coordinates, so they * are scaled based on the pixel pitch to operate in focal plane millimeters. * These coefficient will be used to convert from undistorted focal plane x,y * to distorted focal plane x,y as follows * * @code * r2 = r2 = (ux * ux) + (uy * uy); * dr = 1 + INS-61500_DISTORTION_K0 + INS-61500_DISTORTION_K1*r2 +INS-61500_DISTORTION_K2*r2*r2; * dx = ux * dr; * dy = uy * dr; * @endcode * * @param naifIkCode Code to search for in instrument kernel */ void JunoDistortionMap::SetDistortion(int naifIkCode) { // Use the pixel pitch to scale k1 and k2 coefficients to operate in focal // plane coordinates (millimeters). The coefficients found in the kernels // are based on detector coordinates (pixels). double pp = p_camera->PixelPitch(); double p2 = pp * pp; // Currently k0 is non-existant in kernels (i.e equals zero). The try is // here in case this coefficient is needed for future distortion models. try { QString odk0 = "INS" + toString(naifIkCode) + "_DISTORTION_K0"; p_odk.push_back(p_camera->Spice::getDouble(odk0)); } catch (IException &e) { p_odk.push_back(0.0); } QString odk1 = "INS" + toString(naifIkCode) + "_DISTORTION_K1"; p_odk.push_back(p_camera->Spice::getDouble(odk1) / p2); QString odk2 = "INS" + toString(naifIkCode) + "_DISTORTION_K2"; p_odk.push_back(p_camera->Spice::getDouble(odk2) / (p2 * p2)); } /** * Compute distorted focal plane x/y * * Compute distorted focal plane x/y given an undistorted focal plane x/y. * This virtual method is used to apply various techniques for adding * optical distortion in the focal plane of a camera. The default * implementation of this virtual method uses a polynomial distortion if * the SetDistortion method was invoked. * 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 @b if the conversion was successful * * @see SetDistortion */ bool JunoDistortionMap::SetUndistortedFocalPlane(const double ux, const double uy) { p_undistortedFocalPlaneX = ux; p_undistortedFocalPlaneY = uy; // Compute the distance from the focal plane center and if we are // close to the center then assume no distortion double r2 = (ux * ux) + (uy * uy); if (r2 <= 1.0E-6) { p_focalPlaneX = ux; p_focalPlaneY = uy; return true; } // The equation given in the IK computes the undistorted focal plane // ux = dx * (1 + k1*r^2), r^2 = dx^2 + dy^2 double dr = 1 + p_odk[0] + p_odk[1]*r2 + p_odk[2]*r2*r2; p_focalPlaneX = ux * dr; p_focalPlaneY = uy * dr; return true; } /** * Compute undistorted focal plane x/y * * Compute undistorted focal plane x/y given a distorted focal plane x/y. * This virtual method can be used to apply various techniques for removing * optical distortion in the focal plane of a camera. The default * implementation uses a polynomial distortion if the SetDistortion method * is invoked. 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 if the conversion was successful * @see SetDistortion * @todo Generalize polynomial equation */ bool JunoDistortionMap::SetFocalPlane(double dx, double dy) { p_focalPlaneX = dx; p_focalPlaneY = dy; // Get the distance from the focal plane center and if we are close // then skip the distortion double r2 = (dx * dx) + (dy * dy); if (r2 <= 1.0E-6) { p_undistortedFocalPlaneX = dx; p_undistortedFocalPlaneY = dy; return true; } bool converged = false; int i = 0; int maximumIterations = 15; double tolerance = p_camera->PixelPitch() / 100.0; double uxEstimate = dx; double uyEstimate = dy; double uxPrev = dx; double uyPrev = dy; double xDistortion = 0.0; double yDistortion = 0.0; double dr = 0.0; while (!converged) { dr = p_odk[0] + p_odk[1]*r2 + p_odk[2]*r2*r2; xDistortion = uxEstimate * dr; yDistortion = uyEstimate * dr; uxEstimate = dx - xDistortion; uyEstimate = dy - yDistortion; i++; if (fabs(uxEstimate - uxPrev) < tolerance && fabs(uyEstimate - uyPrev) < tolerance ) { converged = true; } // If doesn't converge, don't do correction if (i > maximumIterations) { p_undistortedFocalPlaneX = dx; p_undistortedFocalPlaneY = dy; break; } r2 = (uxEstimate * uxEstimate) + (uyEstimate * uyEstimate); uxPrev = uxEstimate; uyPrev = uyEstimate; } p_undistortedFocalPlaneX = uxEstimate; p_undistortedFocalPlaneY = uyEstimate; return true; } }