|
Isis 3.0 Application Source Code Reference |
Home |
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 ........