13#include "IException.h"
14#include "Interpolator.h"
15#include "LeastSquares.h"
19#include "PolynomialBivariate.h"
199 if(algo.hasKeyword(
"ChipInterpolator")) {
203 if(algo.hasKeyword(
"SubpixelAccuracy")) {
207 if(algo.hasKeyword(
"ReductionFactor")) {
211 if (algo.hasKeyword(
"Gradient")) {
221 if(pchip.hasKeyword(
"ValidMinimum")) minimum = pchip[
"ValidMinimum"];
222 if(pchip.hasKeyword(
"ValidMaximum")) maximum = pchip[
"ValidMaximum"];
225 if(pchip.hasKeyword(
"MinimumZScore")) {
228 if(pchip.hasKeyword(
"ValidPercent")) {
238 if(schip.hasKeyword(
"ValidMinimum")) minimum = schip[
"ValidMinimum"];
239 if(schip.hasKeyword(
"ValidMaximum")) maximum = schip[
"ValidMaximum"];
241 if(schip.hasKeyword(
"SubchipValidPercent")) {
247 if(ar.hasGroup(
"SurfaceModel")) {
249 if(smodel.hasKeyword(
"DistanceTolerance")) {
253 if(smodel.hasKeyword(
"WindowSize")) {
260 QString msg =
"Improper format for AutoReg PVL [" + pvl.fileName() +
"]";
274 if (gradientFilterType ==
"None") {
277 else if (gradientFilterType ==
"Sobel") {
282 "Invalid Gradient type. Cannot use ["
283 + gradientFilterType +
"] to filter chip",
289 QString AutoReg::GradientFilterString()
const {
291 case None:
return "None";
292 case Sobel:
return "Sobel";
295 "AutoReg only allows Sobel gradient filter or None",
340 if((percent <= 0.0) || (percent > 100.0)) {
341 string msg =
"Invalid value for PatternChip ValidPercent ["
343 +
"]. Must be greater than 0.0 and less than or equal to 100.0 (Default is 50.0).";
368 if((percent <= 0.0) || (percent > 100.0)) {
369 string msg =
"Invalid value for SearchChip SubchipValidPercent ["
371 +
"]. Must be greater than 0.0 and less than or equal to 100.0 (Default is 50.0).";
396 string msg =
"Invalid value for PatternChip MinimumZScore ["
398 +
"]. Must be greater than 0.0. (Default is 1.0).";
443 if(interpolator ==
"NearestNeighborType") {
444 itype = Isis::Interpolator::NearestNeighborType;
446 else if(interpolator ==
"BiLinearType") {
447 itype = Isis::Interpolator::BiLinearType;
449 else if(interpolator ==
"CubicConvolutionType") {
450 itype = Isis::Interpolator::CubicConvolutionType;
454 "Invalid Interpolator type. Cannot use ["
455 + interpolator +
"] to load chip",
481 if(size % 2 != 1 || size < 3) {
482 string msg =
"Invalid value for SurfaceModel WindowSize ["
483 +
IString(size) +
"]. Must be an odd number greater than or equal to 3";
502 if(distance <= 0.0) {
503 string msg =
"Invalid value for SurfaceModel DistanceTolerance ["
504 +
IString(distance) +
"]. Must greater than 0.0.";
523 string msg =
"Invalid value for Algorithm ReductionFactor ["
524 +
IString(factor) +
"]. Must greater than or equal to 1.";
541 (
int)chip.
Lines() / reductionFactor);
542 if((
int)rChip.Samples() < 1 || (
int)rChip.Lines() < 1) {
549 for(
int line = 1; line <= rChip.Lines(); line++) {
550 for(
int samp = 1; samp <= rChip.Samples(); samp++) {
556 for(
int l = 1; l <= rChip.Lines(); l++) {
557 int istartLine = (l - 1) * reductionFactor + 1;
558 int iendLine = istartLine + reductionFactor - 1;
559 for(
int s = 1; s <= rChip.Samples(); s++) {
561 int istartSamp = (s - 1) * reductionFactor + 1;
562 int iendSamp = istartSamp + reductionFactor - 1;
565 for(
int line = istartLine; line < iendLine; line++) {
566 for(
int sample = istartSamp; sample < iendSamp; sample++) {
567 stats.AddData(chip.
GetValue(sample, line));
570 rChip.SetValue(s, l, stats.Average());
593 string msg =
"Search chips samples [";
595 msg +=
"least [" +
IString(N) +
"] pixels wider than the pattern chip samples [";
601 string msg =
"Search chips lines [";
603 msg +=
"least [" +
IString(N) +
"] pixels taller than the pattern chip lines [";
652 int startSamp = (gradientPatternChip.Samples() - 1) / 2 + 1;
653 int startLine = (gradientPatternChip.Lines() - 1) / 2 + 1;
654 int endSamp = gradientSearchChip.Samples() - startSamp + 1;
655 int endLine = gradientSearchChip.Lines() - startLine + 1;
663 string msg =
"Reduction factor is too large";
670 int bestSearchSamp = gradientSearchChip.TackSample();
671 int bestSearchLine = gradientSearchChip.TackLine();
705 reducedStartSamp, reducedEndSamp, reducedStartLine, reducedEndLine);
730 if(newstartLine < startLine) newstartLine = startLine;
731 if(newendSamp > endSamp) newendSamp = endSamp;
732 if(newstartSamp < startSamp) newstartSamp = startSamp;
733 if(newendLine > endLine) newendLine = endLine;
735 startSamp = newstartSamp;
736 endSamp = newendSamp;
737 startLine = newstartLine;
738 endLine = newendLine;
750 p_fitChip, startSamp, startLine, endSamp, endLine,
751 bestSearchSamp, bestSearchLine);
812 Chip &fChip,
int startSamp,
int startLine,
int endSamp,
int endLine,
813 int bestSamp,
int bestLine) {
816 Match(sChip, pChip, fChip, startSamp, endSamp, startLine, endLine);
841 if (!window.IsValid(100.0 * 2.1 / 3.0)) {
852 if (!computedSubPixel) {
897 for(
int i = 0; i < chip.
Samples(); i++) {
898 double pixels[chip.
Lines()];
899 for(
int j = 0; j < chip.
Lines(); j++) {
900 pixels[j] = chip.
GetValue(i + 1, j + 1);
902 patternStats.AddData(pixels, chip.
Lines());
906 p_zScoreMin = patternStats.ZScore(patternStats.Minimum());
907 p_zScoreMax = patternStats.ZScore(patternStats.Maximum());
941 "No rule to set sub-chip width for selected Gradient Filter Type.";
952 for (
int line = 1; line <= chip.
Lines(); line++) {
953 for (
int sample = 1; sample <= chip.
Samples(); sample++) {
954 Chip subChip = chip.
Extract(subChipWidth, subChipWidth,
959 Buffer buffer(subChipWidth, subChipWidth, 1, Isis::None);
962 for (
int subChipLine = 1; subChipLine <= subChip.Lines();
964 for (
int subChipSample = 1; subChipSample <= subChip.Samples();
966 doubleBuffer[bufferIndex] = subChip.GetValue(subChipSample,
974 double newPixelValue = 0;
978 filteredChip.SetValue(sample, line, newPixelValue);
983 for (
int line = 1; line <= filteredChip.Lines(); line++) {
984 for (
int sample = 1; sample <= filteredChip.Samples(); sample++) {
985 chip.
SetValue(sample, line, filteredChip.GetValue(sample, line));
1001 bool specials =
false;
1002 for(
int i = 0; i < in.size(); ++i) {
1011 v = abs((in[0] + 2 * in[1] + in[2]) - (in[6] + 2 * in[7] + in[8])) +
1012 abs((in[2] + 2 * in[5] + in[8]) - (in[0] + 2 * in[3] + in[6]));
1033 if(startSamp == endSamp && startLine == endLine) {
1034 string msg =
"StartSample [" +
IString(startSamp) +
"] = EndSample ["
1035 +
IString(endSamp) +
"] and StartLine [" +
IString(startLine) +
" = EndLine ["
1042 fChip.SetSize(sChip.Samples(), sChip.Lines());
1043 for(
int line = 1; line <= fChip.Lines(); line++) {
1044 for(
int samp = 1; samp <= fChip.Samples(); samp++) {
1050 Chip subsearch(pChip.Samples(), pChip.Lines());
1052 for(
int line = startLine; line <= endLine; line++) {
1053 for(
int samp = startSamp; samp <= endSamp; samp++) {
1055 sChip.Extract(samp, line, subsearch);
1065 fChip.SetValue(samp, line, fit);
1090 double samples = window.Samples();
1091 double lines= window.Lines();
1092 double bestDN = window.GetValue(window.ChipSample(), window.ChipLine());
1093 if (bestDN < window.GetValue(1, 1)) {
1094 for (
int s=1; s <= samples; s++)
1095 for (
int l=1; l <= lines; l++)
1096 window.SetValue(s, l, 1.0/window.GetValue(s, l));
1097 bestDN = 1 / bestDN;
1101 double greatestEdgeDn = 0.0;
1102 for (
int s = 1; s <= samples; s++) {
1103 greatestEdgeDn = max(window.GetValue(s, 1), greatestEdgeDn);
1104 greatestEdgeDn = max(window.GetValue(s, lines), greatestEdgeDn);
1106 for (
int l = 2; l <= lines - 1; l++) {
1107 greatestEdgeDn = max(window.GetValue(1, l), greatestEdgeDn);
1108 greatestEdgeDn = max(window.GetValue(samples, l), greatestEdgeDn);
1116 double temp = greatestEdgeDn + 0.2 * (bestDN - greatestEdgeDn);
1121 Chip selectionChip(window);
1122 floodFill.select(&window, &selectionChip);
1124 double windowSample;
1126 floodFill.centerOfMassWeighted(
1127 &window, &selectionChip, &windowSample, &windowLine);
1129 int offsetS =
p_bestSamp - window.ChipSample();
1130 int offsetL =
p_bestLine - window.ChipLine();
1163 return(std::fabs(
IdealFit() - fit) < 0.00001);
1179 PvlGroup stats(
"AutoRegStatistics");
1183 pvl.addGroup(stats);
1188 pvl.addGroup(successes);
1190 PvlGroup grp(
"PatternChipFailures");
1200 PvlGroup model(
"SurfaceModelFailures");
1204 pvl.addGroup(model);
1220 reg +=
PvlKeyword(
"Algorithm", algo[
"Name"][0]);
1221 reg +=
PvlKeyword(
"Tolerance", algo[
"Tolerance"][0]);
1222 if(algo.hasKeyword(
"SubpixelAccuracy")) {
1223 reg +=
PvlKeyword(
"SubpixelAccuracy", algo[
"SubpixelAccuracy"][0]);
1225 if(algo.hasKeyword(
"ReductionFactor")) {
1226 reg +=
PvlKeyword(
"ReductionFactor", algo[
"ReductionFactor"][0]);
1228 if(algo.hasKeyword(
"Gradient")) {
1229 reg +=
PvlKeyword(
"Gradient", algo[
"Gradient"][0]);
1233 reg +=
PvlKeyword(
"PatternSamples", pchip[
"Samples"][0]);
1234 reg +=
PvlKeyword(
"PatternLines", pchip[
"Lines"][0]);
1235 if(pchip.hasKeyword(
"ValidMinimum")) {
1236 reg +=
PvlKeyword(
"PatternMinimum", pchip[
"ValidMinimum"][0]);
1238 if(pchip.hasKeyword(
"ValidMaximum")) {
1239 reg +=
PvlKeyword(
"PatternMaximum", pchip[
"ValidMaximum"][0]);
1241 if(pchip.hasKeyword(
"MinimumZScore")) {
1242 reg +=
PvlKeyword(
"MinimumZScore", pchip[
"MinimumZScore"][0]);
1244 if(pchip.hasKeyword(
"ValidPercent")) {
1246 reg +=
PvlKeyword(
"ValidPercent", pchip[
"ValidPercent"][0]);
1250 reg +=
PvlKeyword(
"SearchSamples", schip[
"Samples"][0]);
1251 reg +=
PvlKeyword(
"SearchLines", schip[
"Lines"][0]);
1252 if(schip.hasKeyword(
"ValidMinimum")) {
1253 reg +=
PvlKeyword(
"SearchMinimum", schip[
"ValidMinimum"][0]);
1255 if(schip.hasKeyword(
"ValidMaximum")) {
1256 reg +=
PvlKeyword(
"SearchMaximum", schip[
"ValidMaximum"][0]);
1258 if(schip.hasKeyword(
"SubchipValidPercent")) {
1260 reg +=
PvlKeyword(
"SubchipValidPercent", schip[
"SubchipValidPercent"][0]);
1265 if(smodel.hasKeyword(
"DistanceTolerance")) {
1266 reg +=
PvlKeyword(
"DistanceTolerance", smodel[
"DistanceTolerance"][0]);
1269 if(smodel.hasKeyword(
"WindowSize")) {
1270 reg +=
PvlKeyword(
"WindowSize", smodel[
"WindowSize"][0]);
1297 reg +=
PvlKeyword(
"Gradient", GradientFilterString());
Isis::AutoReg::RegisterStatus p_registrationStatus
Registration status to be returned by Register().
double p_bestFit
Goodness of fit for adaptive algorithms.
RegisterStatus
Enumeration of the Register() method's return status.
@ PatternChipNotEnoughValidData
Not enough valid data in pattern chip.
@ SuccessPixel
Success registering to whole pixel.
@ PatternZScoreNotMet
Pattern data max or min does not pass the z-score test.
@ SurfaceModelSolutionInvalid
Could not model surface for sub-pixel accuracy.
@ SuccessSubPixel
Success registering to sub-pixel accuracy.
@ FitChipToleranceNotMet
Goodness of fit tolerance not satisfied.
@ FitChipNoData
Fit chip did not have any valid data.
@ SurfaceModelDistanceInvalid
Surface model moves registration more than one pixel.
@ SurfaceModelNotEnoughValidData
Not enough points to fit a surface model for sub-pixel accuracy.
double WindowSize() const
Return window size.
@ Sobel
Sobel gradient filter.
@ None
default, no gradient filter
int p_totalRegistrations
Registration Statistics Total keyword.
bool p_subpixelAccuracy
Indicates whether sub-pixel accuracy is enabled. Default is true.
double p_zScoreMax
Second Z-Score of pattern chip.
double p_lineMovement
The number of lines the point moved.
PvlGroup UpdatedTemplate()
Returns a PvlGroup containing the PvlKeywords of the parameters this object was most recently run wit...
void Init()
Initialize AutoReg object private variables.
void Match(Chip &sChip, Chip &pChip, Chip &fChip, int startSamp, int endSamp, int startLine, int endLine)
Empty copy constructor.
int p_fitChipNoDataCount
Registration statistics FitChipNoData keyword.
PvlObject p_template
AutoRegistration object that created this projection.
int p_patternChipNotEnoughValidDataCount
Registration statistics PatternNotEnoughValidData keyword.
virtual bool CompareFits(double fit1, double fit2)
This virtual method must return if the 1st fit is equal to or better than the second fit.
Chip p_searchChip
Chip to be searched for best registration.
AutoReg(Pvl &pvl)
Create AutoReg object.
void Parse(Pvl &pvl)
Initialize parameters in the AutoReg class using a PVL specification.
bool IsIdeal(double fit)
Returns true if the fit parameter is arbitrarily close to the ideal fit value.
void ApplyGradientFilter(Chip &chip)
Run a gradient filter over the chip.
int p_pixelSuccesses
Registration statistics Success keyword.
Chip p_reducedFitChip
Fit Chip with reduction factor.
int ReductionFactor()
Return the reduction factor.
void SetSubsearchValidPercent(const double percent)
Set the amount of data in the search chip's subchip that must be valid.
PvlGroup RegTemplate()
This function returns the keywords that this object was created from.
void SetChipInterpolator(const QString &interpolator)
Sets the Chip class interpolator type to be used to load pattern and search chips.
double DistanceTolerance() const
Return distance tolerance.
int p_surfaceModelDistanceInvalidCount
Registration statistics SurfaceModelDistanceInvalid keyword.
double p_cubeSample
Cube sample.
AutoReg::GradientFilterType p_gradientFilterType
Type of gradient filter to use before matching.
double p_cubeLine
Cube line.
int p_subpixelSuccesses
Registration statistics Success keyword.
bool Success() const
Return whether the match algorithm succeeded or not.
virtual double IdealFit() const =0
Returns the ideal (perfect) fit that could be returned by the MatchAlgorithm.
double PatternValidPercent() const
Return pattern chip valid percent. The default value is.
double p_chipLine
Chip line.
double p_zScoreMin
First Z-Score of pattern chip.
double p_chipSample
Chip sample.
Pvl RegistrationStatistics()
This returns the cumulative registration statistics.
int p_reduceFactor
Reduction factor.
int p_fitChipToleranceNotMetCount
Registration statistics FitChipToleranceNotMet keyword.
double p_tolerance
Tolerance for acceptable goodness of fit in match algorithm.
void SetPatternValidPercent(const double percent)
Set the amount of data in the pattern chip that must be valid.
int p_surfaceModelSolutionInvalidCount
Registration statistics SurfaceModelSolutionInvalid keyword.
double SubsearchValidPercent() const
Return subsearch chip valid percent.
Chip * SearchChip()
Return pointer to search chip.
virtual AutoReg::RegisterStatus Registration(Chip &sChip, Chip &pChip, Chip &fChip, int startSamp, int startLine, int endSamp, int endLine, int bestSamp, int bestLine)
Performs matching between the pattern and search at both whole-pixel and subpixel levels.
void SobelGradient(Buffer &in, double &v)
Compute a Sobel gradient based on an input buffer.
void SetReductionFactor(int reductionFactor)
Set the reduction factor used to speed up the pattern matching algorithm.
int p_bestLine
Line value of best fit.
bool SubPixelAccuracy()
Return whether this object will attempt to register to whole or sub-pixel accuracy.
int p_windowSize
Surface model window size.
void SetSubPixelAccuracy(bool on)
If the sub-pixel accuracy is enabled, the Register() method will attempt to match the pattern chip to...
double p_subsearchValidPercent
Percentage of data in subsearch chip that must be valid.
Chip p_reducedPatternChip
Pattern Chip with reduction factor.
bool ComputeChipZScore(Chip &chip)
This method computes the given Chip's Z-Score.
Chip Reduce(Chip &chip, int reductionFactor)
This method reduces the given chip by the given reduction factor.
int p_bestSamp
Sample value of best fit.
virtual ~AutoReg()
Destroy AutoReg object.
bool SetSubpixelPosition(Chip &window)
Set the search chip sample and line to subpixel values if possible.
double MinimumZScore() const
Return minimumPatternZScore.
void SetPatternZScoreMinimum(double minimum)
Set the minimum pattern zscore.
virtual Pvl AlgorithmStatistics(Pvl &pvl)
Provide (adaptive) algorithms a chance to report results.
int p_surfaceModelNotEnoughValidDataCount
Registration statistics SurfaceModelNotEnoughValidData keyword.
Chip p_gradientPatternChip
Chip to be matched with gradient applied.
double p_minimumPatternZScore
Minimum pattern Z-Score.
Chip p_gradientSearchChip
Chip to be searched for best registration with gradient applied.
void SetSurfaceModelDistanceTolerance(double distance)
Set a distance the surface model solution is allowed to move away from the best whole pixel fit in th...
Chip p_fitChip
Results from MatchAlgorithm() method.
Chip p_patternChip
Chip to be matched.
void SetTolerance(double tolerance)
Set the tolerance for an acceptable goodness of fit.
Chip * PatternChip()
Return pointer to pattern chip.
int p_patternZScoreNotMetCount
Registration statistics PatternZScoreNotMet keyword.
virtual double MatchAlgorithm(Chip &pattern, Chip &subsearch)=0
Given two identically sized chips return a double that indicates how well they match.
Chip p_reducedSearchChip
Search Chip with reduction factor.
virtual QString AlgorithmName() const =0
Returns the name of the algorithm.
void SetSurfaceModelWindowSize(int size)
Set the surface model window size.
double p_distanceTolerance
Maximum distance the surface model solution may be from the best whole pixel fit in the fit chip.
void SetGradientFilterType(const QString &gradientFilterType)
Set the gradient filter type to be applied to the search and pattern chips.
double p_goodnessOfFit
Goodness of fit of the match algorithm.
AutoReg::RegisterStatus Register()
Walk the pattern chip through the search chip to find the best registration.
double Tolerance() const
Return match algorithm tolerance.
double p_patternValidPercent
Percentage of data in pattern chip that must be valid.
double p_sampMovement
The number of samples the point moved.
Buffer for reading and writing cube data.
double * DoubleBuffer() const
Returns the value of the shape buffer.
Selection class derived from the Pure Virtual Parent Class for all Selection classes.
int setDNRange(double minimumDN, double maximumDN)
Set the range of the DNs.
A small chip of data used for pattern matching.
void SetReadInterpolator(const Interpolator::interpType type)
Sets Interpolator Type for loading a chip.
void SetSize(const int samples, const int lines)
Change the size of the Chip.
double GetValue(int sample, int line)
Loads a Chip with a value.
void SetValidRange(const double minimum=Isis::ValidMinimum, const double maximum=Isis::ValidMaximum)
Set the valid range of data in the chip.
void SetChipPosition(const double sample, const double line)
Compute the position of the cube given a chip coordinate.
Chip Extract(int samples, int lines, int samp, int line)
Extract a sub-chip from a chip.
void SetValue(int sample, int line, const double &value)
Sets a value in the chip.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
Adds specific functionality to C++ strings.
interpType
The interpolator type, including: None, Nearest Neighbor, BiLinear or Cubic Convultion.
Contains multiple PvlContainers.
Container for cube-like labels.
A single keyword-value pair.
Contains Pvl Groups and Pvl Objects.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
@ Traverse
Search child objects.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
This class is used to accumulate statistics on double arrays.
void Reset()
Reset all accumulators and counters to zero.
This is free and unencumbered software released into the public domain.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
const double ValidMaximum
The maximum valid double value for Isis pixels.
const double Null
Value for an Isis Null pixel.
const double ValidMinimum
The minimum valid double value for Isis pixels.
bool IsSpecial(const double d)
Returns if the input pixel is special.
Namespace for the standard library.