Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
U
Usgscsm
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
aflab
astrogeology
Usgscsm
Commits
363546b7
Commit
363546b7
authored
May 2, 2019
by
Stuart Sides
Committed by
Jesse Mapel
May 2, 2019
Browse files
Options
Downloads
Patches
Plain Diff
New distortion model for LRO LROC NAC (#235)
parent
52cc5976
No related branches found
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
include/usgscsm/Distortion.h
+3
-1
3 additions, 1 deletion
include/usgscsm/Distortion.h
src/Distortion.cpp
+104
-3
104 additions, 3 deletions
src/Distortion.cpp
src/Utilities.cpp
+24
-2
24 additions, 2 deletions
src/Utilities.cpp
tests/DistortionTests.cpp
+61
-0
61 additions, 0 deletions
tests/DistortionTests.cpp
with
192 additions
and
6 deletions
include/usgscsm/Distortion.h
+
3
−
1
View file @
363546b7
...
...
@@ -10,9 +10,11 @@ enum DistortionType {
RADIAL
,
TRANSVERSE
,
KAGUYATC
,
DAWNFC
DAWNFC
,
LROLROCNAC
};
// Transverse Distortion
void
distortionJacobian
(
double
x
,
double
y
,
double
*
jacobian
,
const
std
::
vector
<
double
>
opticalDistCoeffs
);
...
...
This diff is collapsed.
Click to expand it.
src/Distortion.cpp
+
104
−
3
View file @
363546b7
...
...
@@ -43,6 +43,7 @@ void distortionJacobian(double x, double y, double *jacobian,
}
}
/**
* @description Compute distorted focal plane (dx,dy) coordinate given an undistorted focal
* plane (ux,uy) coordinate. This uses the third order Taylor approximation to the
...
...
@@ -81,6 +82,7 @@ void computeTransverseDistortion(double ux, double uy, double &dx, double &dy,
}
}
void
removeDistortion
(
double
dx
,
double
dy
,
double
&
ux
,
double
&
uy
,
const
std
::
vector
<
double
>
opticalDistCoeffs
,
DistortionType
distortionType
,
...
...
@@ -89,6 +91,7 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
uy
=
dy
;
switch
(
distortionType
)
{
// Compute undistorted focal plane coordinate given a distorted
// coordinate set and the distortion coefficients
case
RADIAL
:
{
...
...
@@ -102,6 +105,7 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
}
}
break
;
// Computes undistorted focal plane (x,y) coordinates given a distorted focal plane (x,y)
// coordinate. The undistorted coordinates are solved for using the Newton-Raphson
// method for root-finding if the distortionFunction method is invoked.
...
...
@@ -159,6 +163,8 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
// number of iterations
}
break
;
// KaguyaTC
case
KAGUYATC
:
{
// Apply distortion correction
// see: SEL_TC_V01.TI
...
...
@@ -201,6 +207,7 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
uy
=
dy
+
dr_y
;
}
break
;
// The dawn distortion model is "reversed" from other distortion models so
// the remove function iteratively computes undistorted coordinates based on
// the distorted coordinates, rather than iteratively computing distorted coordinates
...
...
@@ -252,18 +259,41 @@ void removeDistortion(double dx, double dy, double &ux, double &uy,
ux
=
guess_ux
;
uy
=
guess_uy
;
}
break
;
// LROLROCNAC
case
LROLROCNAC
:
{
if
(
opticalDistCoeffs
.
size
()
!=
1
)
{
throw
"Distortion coefficients for LRO LROC NAC must be of size 1, current size: "
+
std
::
to_string
(
opticalDistCoeffs
.
size
());
}
double
dk1
=
opticalDistCoeffs
[
0
];
double
den
=
1
+
dk1
*
dy
*
dy
;
// r = dy*dy = distance from the focal plane center
if
(
den
==
0.0
)
{
throw
"Unable to remove distortion for LRO LROC NAC. Focal plane position "
+
std
::
to_string
(
dy
);
}
ux
=
dx
;
uy
=
dy
/
den
;
return
;
}
break
;
}
}
void
applyDistortion
(
double
ux
,
double
uy
,
double
&
dx
,
double
&
dy
,
const
std
::
vector
<
double
>
opticalDistCoeffs
,
DistortionType
distortionType
,
const
double
desiredPrecision
,
const
double
tolerance
)
{
const
double
desiredPrecision
,
const
double
tolerance
)
{
dx
=
ux
;
dy
=
uy
;
switch
(
distortionType
)
{
// Compute undistorted focal plane coordinate given a distorted
// focal plane coordinate. This case works by iteratively adding distortion
// until the new distorted point, r, undistorts to within a tolerance of the
...
...
@@ -312,6 +342,8 @@ void applyDistortion(double ux, double uy, double &dx, double &dy,
computeTransverseDistortion
(
ux
,
uy
,
dx
,
dy
,
opticalDistCoeffs
);
}
break
;
// KaguyaTC
case
KAGUYATC
:
{
if
(
opticalDistCoeffs
.
size
()
!=
8
)
{
throw
"Distortion coefficients for Kaguya TC must be of size 8, got: "
+
std
::
to_string
(
opticalDistCoeffs
.
size
());
...
...
@@ -377,6 +409,7 @@ void applyDistortion(double ux, double uy, double &dx, double &dy,
}
}
break
;
// The dawn distortion model is "reversed" from other distortion models so
// the apply function computes distorted coordinates as a
// fn(undistorted coordinates)
...
...
@@ -388,5 +421,73 @@ void applyDistortion(double ux, double uy, double &dx, double &dy,
dx
=
ux
*
(
1.0
+
opticalDistCoeffs
[
0
]
*
r2
);
dy
=
uy
*
(
1.0
+
opticalDistCoeffs
[
0
]
*
r2
);
}
break
;
// The LRO LROC NAC distortion model uses an iterative approach to go from
// undistorted x,y to distorted x,y
// Algorithum adapted from ISIS3 LRONarrowAngleDistortionMap.cpp
case
LROLROCNAC
:
{
double
yt
=
uy
;
double
rr
,
dr
;
double
ydistorted
;
double
yprevious
=
1000000.0
;
double
tolerance
=
1.0e-10
;
bool
bConverged
=
false
;
if
(
opticalDistCoeffs
.
size
()
!=
1
)
{
throw
"Distortion coefficients for LRO LROC NAC must be of size 1, current size: "
+
std
::
to_string
(
opticalDistCoeffs
.
size
());
}
double
dk1
=
opticalDistCoeffs
[
0
];
// Owing to the odd distotion model employed in this senser if |y| is > 116.881145553046
// then there is no root to find. Further, the greatest y that any measure on the sensor
// will acutally distort to is less than 20. Thus, if any distorted measure is greater
// that that skip the iterations. The points isn't in the cube, and exactly how far outside
// the cube is irrelevant. Just let the camera model know its not in the cube....
if
(
fabs
(
uy
)
>
40
)
{
//if the point is way off the image.....
dx
=
ux
;
dy
=
uy
;
return
;
}
// iterating to introduce distortion (in sample only)...
// we stop when the difference between distorted coordinate
// in successive iterations is at or below the given tolerance
for
(
int
i
=
0
;
i
<
50
;
i
++
)
{
rr
=
yt
*
yt
;
// dr is the radial distortion contribution
dr
=
1.0
+
dk1
*
rr
;
// distortion at the current sample location
yt
=
uy
*
dr
;
// distorted sample
ydistorted
=
yt
;
if
(
yt
<
-
1e121
)
//debug
break
;
//debug
// check for convergence
if
(
fabs
(
yt
-
yprevious
)
<=
tolerance
)
{
bConverged
=
true
;
break
;
}
yprevious
=
yt
;
}
if
(
bConverged
)
{
dx
=
ux
;
dy
=
ydistorted
;
}
return
;
}
break
;
}
}
This diff is collapsed.
Click to expand it.
src/Utilities.cpp
+
24
−
2
View file @
363546b7
...
...
@@ -727,6 +727,7 @@ double getSemiMajorRadius(json isd, csm::WarningList *list) {
return
radius
;
}
double
getSemiMinorRadius
(
json
isd
,
csm
::
WarningList
*
list
)
{
double
radius
=
0.0
;
try
{
...
...
@@ -747,8 +748,9 @@ double getSemiMinorRadius(json isd, csm::WarningList *list) {
return
radius
;
}
// Gets the type of distortion model from the isd. If none is specified defaults
// to transverse
// Converts the distortion model name from the ISD (string) to the enumeration
// type. Defaults to transverse
DistortionType
getDistortionModel
(
json
isd
,
csm
::
WarningList
*
list
)
{
try
{
json
distoriton_subset
=
isd
.
at
(
"optical_distortion"
);
...
...
@@ -769,6 +771,9 @@ DistortionType getDistortionModel(json isd, csm::WarningList *list) {
else
if
(
distortion
.
compare
(
"dawnfc"
)
==
0
)
{
return
DistortionType
::
DAWNFC
;
}
else
if
(
distortion
.
compare
(
"lrolrocnac"
)
==
0
)
{
return
DistortionType
::
LROLROCNAC
;
}
}
catch
(...)
{
if
(
list
)
{
...
...
@@ -877,6 +882,23 @@ std::vector<double> getDistortionCoeffs(json isd, csm::WarningList *list) {
}
}
break
;
case
DistortionType
::
LROLROCNAC
:
{
try
{
coefficients
=
isd
.
at
(
"optical_distortion"
).
at
(
"lrolrocnac"
).
at
(
"coefficients"
).
get
<
std
::
vector
<
double
>>
();
return
coefficients
;
}
catch
(...)
{
if
(
list
)
{
list
->
push_back
(
csm
::
Warning
(
csm
::
Warning
::
DATA_NOT_AVAILABLE
,
"Could not parse the lrolrocnac distortion model coefficients."
,
"Utilities::getDistortion()"
));
}
coefficients
=
std
::
vector
<
double
>
(
1
,
0.0
);
}
}
break
;
}
if
(
list
)
{
list
->
push_back
(
...
...
This diff is collapsed.
Click to expand it.
tests/DistortionTests.cpp
+
61
−
0
View file @
363546b7
...
...
@@ -214,6 +214,7 @@ TEST(KaguyaTc, testRemoveCoeffs) {
EXPECT_NEAR
(
uy
,
1
+
1
+
2.828427125
+
6
+
11.313708499
,
1e-8
);
}
TEST
(
KaguyaTc
,
testCoeffs
)
{
csm
::
ImageCoord
imagePt
(
1.0
,
1.0
);
...
...
@@ -235,6 +236,7 @@ TEST(KaguyaTc, testCoeffs) {
EXPECT_NEAR
(
uy
,
1.0
,
1e-8
);
}
TEST
(
KaguyaTc
,
testZeroCoeffs
)
{
csm
::
ImageCoord
imagePt
(
1.0
,
1.0
);
...
...
@@ -254,3 +256,62 @@ TEST(KaguyaTc, testZeroCoeffs) {
ASSERT_DOUBLE_EQ
(
ux
,
1.0
);
ASSERT_DOUBLE_EQ
(
uy
,
1.0
);
}
// Test for LRO LROC NAC
TEST
(
LroLrocNac
,
testLastDetectorSample
)
{
double
ux
,
uy
,
dx
,
dy
;
double
desiredPrecision
=
0.0000001
;
// Coeffs obtained from file: lro_lroc_v18.ti
std
::
vector
<
double
>
coeffs
=
{
1.81E-5
};
removeDistortion
(
0.0
,
5064.0
/
2.0
*
0.007
,
ux
,
uy
,
coeffs
,
DistortionType
::
LROLROCNAC
,
desiredPrecision
);
applyDistortion
(
ux
,
uy
,
dx
,
dy
,
coeffs
,
DistortionType
::
LROLROCNAC
,
desiredPrecision
);
EXPECT_NEAR
(
dx
,
0.0
,
1e-8
);
EXPECT_NEAR
(
dy
,
17.724
,
1e-8
);
EXPECT_NEAR
(
ux
,
0.0
,
1e-8
);
EXPECT_NEAR
(
uy
,
17.6237922244
,
1e-8
);
}
TEST
(
LroLrocNac
,
testCoeffs
)
{
double
ux
,
uy
,
dx
,
dy
;
double
desiredPrecision
=
0.0000001
;
// Coeff obtained from file: lro_lroc_v18.ti
std
::
vector
<
double
>
coeffs
=
{
1.81E-5
};
applyDistortion
(
0.0
,
0.0
,
dx
,
dy
,
coeffs
,
DistortionType
::
LROLROCNAC
,
desiredPrecision
);
removeDistortion
(
dx
,
dy
,
ux
,
uy
,
coeffs
,
DistortionType
::
LROLROCNAC
,
desiredPrecision
);
EXPECT_NEAR
(
dx
,
0.0
,
1e-8
);
EXPECT_NEAR
(
dy
,
0.0
,
1e-8
);
EXPECT_NEAR
(
ux
,
0.0
,
1e-8
);
EXPECT_NEAR
(
uy
,
0.0
,
1e-8
);
}
TEST
(
LroLrocNac
,
testZeroCoeffs
)
{
double
ux
,
uy
,
dx
,
dy
;
double
desiredPrecision
=
0.0000001
;
std
::
vector
<
double
>
coeffs
=
{
0
};
applyDistortion
(
0.0
,
0.0
,
dx
,
dy
,
coeffs
,
DistortionType
::
LROLROCNAC
,
desiredPrecision
);
removeDistortion
(
dx
,
dy
,
ux
,
uy
,
coeffs
,
DistortionType
::
LROLROCNAC
,
desiredPrecision
);
ASSERT_DOUBLE_EQ
(
dx
,
0.0
);
ASSERT_DOUBLE_EQ
(
dy
,
0.0
);
ASSERT_DOUBLE_EQ
(
ux
,
0.0
);
ASSERT_DOUBLE_EQ
(
uy
,
0.0
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment