USGS

Isis 3.0 Application Source Code Reference

Home

coreg.cpp

Go to the documentation of this file.
00001 #define GUIHELPERS
00002 
00003 #include "Isis.h"
00004 #include "PvlGroup.h"
00005 #include "UserInterface.h"
00006 #include "Cube.h"
00007 #include "Chip.h"
00008 #include "Progress.h"
00009 #include "iException.h"
00010 #include "AutoReg.h"
00011 #include "AutoRegFactory.h"
00012 #include "Statistics.h"
00013 #include "ControlNet.h"
00014 #include "SerialNumber.h"
00015 #include "ControlMeasure.h"
00016 #include "iTime.h"
00017                            
00018 using namespace std;
00019 using namespace Isis;
00020 
00021 //helper button functins in the code
00022 void helperButtonLog();
00023 
00024 map <string,void*> GuiHelpers(){
00025   map <string,void*> helper;
00026   helper ["helperButtonLog"] = (void*) helperButtonLog;
00027   return helper;
00028 }
00029 
00030 void IsisMain() {
00031   // Get user interface
00032   UserInterface &ui = Application::GetUserInterface();
00033 
00034   // Make sure the correct parameters are entered
00035   if (ui.WasEntered("TO")) {
00036     if (ui.GetString("TRANSFORM") == "WARP") {
00037       if (!ui.WasEntered("CNETFILE")) {
00038         string msg = "A Control Net file must be entered if the TO parameter is ";
00039         msg += "entered";
00040         throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
00041       }
00042     }
00043   }
00044 
00045   // Open the first cube.  It will be matched to the second input cube.
00046   Cube trans;
00047   CubeAttributeInput &attTrans = ui.GetInputAttribute("FROM");
00048   vector<string> bandTrans = attTrans.Bands();
00049   trans.SetVirtualBands(bandTrans);
00050   trans.Open(ui.GetFilename("FROM"),"r");
00051 
00052 
00053   // Open the second cube, it is held in place.  We will be matching the
00054   // first to this one by attempting to compute a sample/line translation
00055   Cube match;
00056   CubeAttributeInput &attMatch = ui.GetInputAttribute("MATCH");
00057   vector<string> bandMatch = attMatch.Bands();
00058   match.SetVirtualBands(bandMatch);
00059   match.Open(ui.GetFilename("MATCH"),"r");
00060 
00061   // Input cube Lines and Samples must be the same and each must have only
00062   // one band
00063   if ((trans.Lines() != match.Lines()) ||
00064       (trans.Samples() != match.Samples())) {
00065     string msg = "Input Cube Lines and Samples must be equal!";
00066     throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
00067   }
00068 
00069   if (trans.Bands() != 1 || match.Bands() != 1) {
00070     string msg = "Input Cubes must have only one band!";
00071     throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
00072   }
00073 
00074   // Get serial number
00075   string serialTrans = SerialNumber::Compose(trans, true);
00076   string serialMatch = SerialNumber::Compose(match, true);
00077 
00078 //  This still precludes band to band registrations.
00079   if (serialTrans == serialMatch) {
00080     string sTrans = Filename(trans.Filename()).Name();
00081     string sMatch = Filename(match.Filename()).Name();
00082     if (sTrans == sMatch) {
00083       string msg = "Cube Serial Numbers must be unique - FROM=" + serialTrans +
00084                    ", MATCH=" + serialMatch;
00085       throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
00086     }
00087     serialTrans = sTrans;
00088     serialMatch = sMatch;
00089   } 
00090 
00091 
00092   // We need to get a user definition of how to auto correlate around each
00093   // of the control points.
00094   Pvl regdef;
00095   regdef.Read(ui.GetFilename("REGDEF"));
00096   AutoReg *ar = AutoRegFactory::Create(regdef);
00097 
00098   // We want to create a grid of control points that is N rows by M columns.
00099   // Get row and column variables, if not entered, default to 1% of the input
00100   // image size
00101   int rows, cols;
00102   if (ui.WasEntered("ROWS")) {
00103     rows = ui.GetInteger("ROWS");
00104   }
00105   else {
00106     rows = (int)((trans.Lines() - 1) / ar->SearchChip()->Lines() + 1);
00107   }
00108   if (ui.WasEntered("COLUMNS")) {
00109     cols = ui.GetInteger("COLUMNS");
00110   }
00111   else {
00112     cols = (int)((trans.Samples() - 1) / ar->SearchChip()->Samples() + 1);
00113   }
00114 
00115   // Display the progress...10% 20% etc.
00116   Progress prog;
00117   prog.SetMaximumSteps(rows * cols);
00118   prog.CheckStatus();
00119 
00120   // Calculate spacing for the grid of points
00121   double lSpacing = (double)trans.Lines() / rows;
00122   double sSpacing = (double)trans.Samples() / cols;
00123 
00124   // Initialize control point network
00125   ControlNet cn;
00126   cn.SetType(ControlNet::ImageToImage);
00127   cn.SetUserName(Application::UserName());
00128   cn.SetCreatedDate(iTime::CurrentLocalTime());
00129 
00130   // Loop through grid of points and get statistics to compute
00131   // translation values
00132   Statistics sStats, lStats;
00133   for (int r=0; r<rows; r++) {
00134     for (int c=0; c<cols; c++) {
00135       int line = (int)(lSpacing / 2.0 + lSpacing * r + 0.5);
00136       int samp = (int)(sSpacing / 2.0 + sSpacing * c + 0.5);
00137       ar->PatternChip()->TackCube(samp, line);
00138       ar->PatternChip()->Load(match);
00139       ar->SearchChip()->TackCube(samp, line);
00140       ar->SearchChip()->Load(trans);
00141 
00142       // Set up ControlMeasure for cube to translate
00143       ControlMeasure cmTrans;
00144       cmTrans.SetCubeSerialNumber(serialTrans);
00145       cmTrans.SetCoordinate(samp, line, ControlMeasure::Unmeasured);
00146       cmTrans.SetChooserName("coreg");       
00147       cmTrans.SetReference(false);
00148 
00149       // Set up ControlMeasure for the pattern/Match cube 
00150       ControlMeasure cmMatch;
00151       cmMatch.SetCubeSerialNumber(serialMatch);
00152       cmMatch.SetCoordinate(samp, line, ControlMeasure::Automatic);
00153       cmMatch.SetChooserName("coreg");
00154       cmMatch.SetReference(true);
00155 
00156       // Match found
00157       if (ar->Register()==AutoReg::Success) {
00158         double sDiff = samp - ar->CubeSample();
00159         double lDiff = line - ar->CubeLine();
00160         sStats.AddData(&sDiff,(unsigned int)1);
00161         lStats.AddData(&lDiff,(unsigned int)1);
00162         cmTrans.SetCoordinate(ar->CubeSample(), ar->CubeLine(),
00163                           ControlMeasure::Automatic);
00164         cmTrans.SetError(sDiff, lDiff);
00165         cmTrans.SetGoodnessOfFit(ar->GoodnessOfFit());
00166       }
00167 
00168       // Add the measures to a control point
00169       string str = "Row " + iString(r) + " Column " + iString(c);
00170       ControlPoint cp(str);
00171       cp.SetType(ControlPoint::Tie);
00172       cp.Add(cmTrans);
00173       cp.Add(cmMatch);
00174       if (!cmTrans.IsMeasured()) cp.SetIgnore(true);
00175       cn.Add(cp);
00176       prog.CheckStatus();
00177     }
00178   }
00179 
00180   // If none of the points registered, throw an error
00181   if (sStats.TotalPixels() <1) {
00182     string msg = "Coreg was unable to register any points. Check your algorithm definition.";
00183     throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
00184   }
00185 
00186   // Don't need the cubes opened anymore
00187   trans.Close();
00188   match.Close();
00189 
00190   // If a cnet file was entered, write the ControlNet pvl to the file
00191   if (ui.WasEntered("CNETFILE")) {
00192     cn.Write(ui.GetFilename("CNETFILE"));
00193   }
00194 
00195   // If flatfile was entered, create the flatfile
00196   // The flatfile is comma seperated and can be imported into an excel
00197   // spreadsheet
00198   if (ui.WasEntered("FLATFILE")) {
00199     string fFile = Filename(ui.GetFilename("FLATFILE")).Expanded();
00200     ofstream os;
00201     os.open(fFile.c_str(),ios::out);
00202     os << "Sample,Line,TranslatedSample,TranslatedLine," <<
00203       "SampleDifference,LineDifference,GoodnessOfFit" << endl;
00204     for (int i=0; i<cn.Size(); i++) {
00205       ControlPoint cp = cn[i];
00206       if (cp.Ignore()) continue;
00207       ControlMeasure cmTrans = cp[0];
00208       ControlMeasure cmMatch = cp[1];
00209       os << cmTrans.Sample() << "," << cmTrans.Line() << ","
00210          << cmMatch.Sample() << "," << cmMatch.Line() << ","
00211          << cmTrans.SampleError() << "," << cmTrans.LineError() << ","
00212          << cmTrans.GoodnessOfFit() << endl;
00213     }
00214   }
00215 
00216   // Write translation to log
00217   PvlGroup results("Translation");
00218   double sMin = (int)(sStats.Minimum() * 100.0) / 100.0;
00219   double sTrans = (int)(sStats.Average() * 100.0) / 100.0;
00220   double sMax = (int)(sStats.Maximum() * 100.0) / 100.0;
00221   double sDev = (int)(sStats.StandardDeviation() * 100.0) / 100.0;
00222   double lMin = (int)(lStats.Minimum() * 100.0) / 100.0;
00223   double lTrans = (int)(lStats.Average() * 100.0) / 100.0;
00224   double lMax = (int)(lStats.Maximum() * 100.0) / 100.0;
00225   double lDev = (int)(lStats.StandardDeviation() * 100.0) / 100.0;
00226 
00227   results += PvlKeyword ("SampleMinimum", sMin);
00228   results += PvlKeyword ("SampleAverage", sTrans);
00229   results += PvlKeyword ("SampleMaximum", sMax);
00230   results += PvlKeyword ("SampleStandardDeviation", sDev);
00231   results += PvlKeyword ("LineMinimum", lMin);
00232   results += PvlKeyword ("LineAverage", lTrans);
00233   results += PvlKeyword ("LineMaximum", lMax);
00234   results += PvlKeyword ("LineStandardDeviation", lDev);
00235   Application::Log(results);
00236 
00237   Pvl arPvl = ar->RegistrationStatistics();
00238 
00239   for(int i = 0; i < arPvl.Groups(); i++) {
00240     Application::Log(arPvl.Group(i));
00241   }
00242 
00243   // add the auto registration information to print.prt
00244   PvlGroup autoRegTemplate = ar->RegTemplate(); 
00245   Application::Log(autoRegTemplate); 
00246 
00247   // If a TO parameter was specified, apply the average translation found to the
00248   // second input image
00249   if (ui.WasEntered("TO")) {
00250     if (ui.GetString("TRANSFORM") == "TRANSLATE") {
00251       string params = "from=" + ui.GetFilename("FROM") + " to=" +
00252         ui.GetFilename("TO") + " strans=" + iString(sTrans) + " ltrans="
00253         + iString(lTrans) + " interp=" + ui.GetString("INTERP");
00254       iApp->Exec("translate",params);
00255     }
00256     else {
00257       string params = "from=" + ui.GetFilename("FROM") + " to=" +
00258         ui.GetFilename("TO") + " cube=" + ui.GetFilename("MATCH") + " control=" + 
00259         ui.GetFilename("CNETFILE") + " interp=" + ui.GetString("INTERP") + 
00260         " degree=" + iString(ui.GetInteger("DEGREE"));
00261       iApp->Exec("warp",params);
00262 
00263     }
00264   }
00265 }
00266 
00267 //Helper function to output the regdeft file to log.
00268 void helperButtonLog () {
00269   UserInterface &ui = Application::GetUserInterface();
00270   string file(ui.GetFilename("REGDEF"));
00271   Pvl p;
00272   p.Read(file);
00273   Application::GuiLog(p);
00274 }
00275 //...........end of helper function ........