Beispiel #1
0
void IsisMain() {

  // Get user interface
  UserInterface &ui = Application::GetUserInterface();

//  Open the shift definitions file
  Pvl shiftdef;
  if (ui.WasEntered("SHIFTDEF")) {
    shiftdef.Read(ui.GetFilename("SHIFTDEF"));
  }
  else {
    shiftdef.AddObject(PvlObject("Hiccdstitch"));
  }

  PvlObject &stitch = shiftdef.FindObject("Hiccdstitch", Pvl::Traverse);


  // Open the first cube.  It will be matched to the second input cube.
  HiJitCube trans;
  CubeAttributeInput &attTrans = ui.GetInputAttribute("FROM");
  vector<string> bandTrans = attTrans.Bands();
  trans.SetVirtualBands(bandTrans);
  trans.OpenCube(ui.GetFilename("FROM"), stitch);

 
  // Open the second cube, it is held in place.  We will be matching the
  // first to this one by attempting to compute a sample/line translation
  HiJitCube match;
  CubeAttributeInput &attMatch = ui.GetInputAttribute("MATCH");
  vector<string> bandMatch = attMatch.Bands();
  match.SetVirtualBands(bandMatch);
  match.OpenCube(ui.GetFilename("MATCH"), stitch);

//  Ensure only one band
  if ((trans.Bands() != 1) || (match.Bands() != 1)) {
    string msg = "Input Cubes must have only one band!";
    throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
  }

//  Now test compatability (basically summing)
  trans.Compatable(match);

//  Determine intersection
  if (!trans.intersects(match)) {
    string msg = "Input Cubes do not overlap!";
    throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
  }

//  Get overlapping regions of each cube
  HiJitCube::Corners fcorns, mcorns;
  trans.overlap(match, fcorns);
  match.overlap(trans, mcorns);

#if defined(ISIS_DEBUG)
  cout << "FROM Poly:  " << trans.PolyToString() << std::endl;
  cout << "MATCH Poly: " << match.PolyToString() << std::endl;
  cout << "From Overlap:  (" << fcorns.topLeft.sample << ","
                             << fcorns.topLeft.line   << "), ("
                             << fcorns.lowerRight.sample << "," 
                             << fcorns.lowerRight.line << ")\n" ;
  cout << "Match Overlap: (" << mcorns.topLeft.sample << ","
                             << mcorns.topLeft.line   << "), ("
                             << mcorns.lowerRight.sample << "," 
                             << mcorns.lowerRight.line << ")\n" ;
#endif


  // We need to get a user definition of how to auto correlate around each
  // of the grid points.
  Pvl regdef;
  Filename regFile(ui.GetFilename("REGDEF"));
  regdef.Read(regFile.Expanded());
  AutoReg *ar = AutoRegFactory::Create(regdef);


  double flines(fcorns.lowerRight.line - fcorns.topLeft.line + 1.0);
  double fsamps(fcorns.lowerRight.sample - fcorns.topLeft.sample + 1.0);

  // We want to create a grid of control points that is N rows by M columns.
  // Get row and column variables, if not entered, default to 1% of the input
  // image size
  int rows(1), cols(1);
  if (ui.WasEntered("ROWS")) {
    rows = ui.GetInteger("ROWS");
  }
  else {
    rows = (int)(((flines - 1.0) / ar->SearchChip()->Lines()) + 1);
  }

  cols = ui.GetInteger("COLUMNS");
  if (cols == 0) {
    cols = (int)(((fsamps - 1.0) / ar->SearchChip()->Samples()) + 1);
  }

  // Calculate spacing for the grid of points
  double lSpacing = floor(flines / rows);
  double sSpacing = floor(fsamps / cols);

#if defined(ISIS_DEBUG)
  cout << "# Samples in Overlap: " << fsamps << endl;
  cout << "# Lines in Overlap  : " << flines << endl;
  cout << "# Rows:    " << rows << endl;
  cout << "# Columns: " << cols << endl;
  cout << "Line Spacing:   " << lSpacing << endl;
  cout << "Sample Spacing: " << sSpacing << endl;
#endif

  // Display the progress...10% 20% etc.
  Progress prog;
  prog.SetMaximumSteps(rows * cols);
  prog.CheckStatus();

  // Initialize control point network
  ControlNet cn;
  cn.SetType(ControlNet::ImageToImage);
  cn.SetUserName(Application::UserName());
  cn.SetCreatedDate(iTime::CurrentLocalTime());

  //  Get serial numbers for input cubes
  string transSN = SerialNumber::Compose(trans, true);
  string matchSN = SerialNumber::Compose(match, true);

  cn.SetTarget(transSN);
  cn.SetDescription("Records s/c jitter between two adjacent HiRISE images");

//  Set up results parameter saves
  JitterParms jparms;
  jparms.fromCorns = fcorns;
  jparms.fromJit = trans.GetInfo();
  jparms.matchCorns = mcorns;
  jparms.matchJit = match.GetInfo();
  jparms.regFile =  regFile.Expanded();
  jparms.cols = cols;
  jparms.rows = rows;
  jparms.lSpacing = lSpacing;
  jparms.sSpacing = sSpacing;
  jparms.nSuspects = 0;

  // Loop through grid of points and get statistics to compute
  // translation values
  RegList reglist;
  double fline0(fcorns.topLeft.line-1.0), fsamp0(fcorns.topLeft.sample-1.0);
  double mline0(mcorns.topLeft.line-1.0), msamp0(mcorns.topLeft.sample-1.0);

  for (int r=0; r<rows; r++) {
    int line = (int)(lSpacing / 2.0 + lSpacing * r + 0.5);
    for (int c=0; c<cols; c++) {
      int samp = (int)(sSpacing / 2.0 + sSpacing * c + 0.5);

      ar->PatternChip()->TackCube(msamp0+samp, mline0+line);
      ar->PatternChip()->Load(match);
      ar->SearchChip()->TackCube(fsamp0+samp, fline0+line);
      ar->SearchChip()->Load(trans);

     // Set up ControlMeasure for cube to translate
      ControlMeasure cmTrans;
      cmTrans.SetCubeSerialNumber(transSN);
      cmTrans.SetCoordinate(msamp0+samp, mline0+line, 
                            ControlMeasure::Unmeasured);
      cmTrans.SetChooserName("hijitreg");
      cmTrans.SetReference(false);

      // Set up ControlMeasure for the pattern/Match cube 
      ControlMeasure cmMatch;
      cmMatch.SetCubeSerialNumber(matchSN);
      cmMatch.SetCoordinate(fsamp0+samp, fline0+line, 
                            ControlMeasure::Automatic);
      cmMatch.SetChooserName("hijitreg");
      cmMatch.SetReference(true);


      // Match found
      if (ar->Register()==AutoReg::Success) {
        RegData reg;
        reg.fLine = fline0 + line;
        reg.fSamp = fsamp0 + samp;
        reg.fLTime = trans.getLineTime(reg.fLine);
        reg.mLine = mline0 + line;
        reg.mSamp = msamp0 + samp;
        reg.mLTime = match.getLineTime(reg.mLine);
        reg.regLine = ar->CubeLine();
        reg.regSamp = ar->CubeSample();
        reg.regCorr = ar->GoodnessOfFit();


        if (fabs(reg.regCorr) > 1.0) jparms.nSuspects++;

        double sDiff = reg.fSamp - reg.regSamp;
        double lDiff = reg.fLine - reg.regLine;
        jparms.sStats.AddData(&sDiff,(unsigned int)1);
        jparms.lStats.AddData(&lDiff,(unsigned int)1);

//  Record the translation in the control point
        cmTrans.SetCoordinate(ar->CubeSample(), ar->CubeLine(), 
                              ControlMeasure::Automatic);
        cmTrans.SetError(sDiff, lDiff);
        cmTrans.SetGoodnessOfFit(ar->GoodnessOfFit());

//  Reread the chip location centering the offset and compute
//  linear regression statistics
        try {
          Chip &pchip(*ar->PatternChip());
          Chip fchip(pchip.Samples(), pchip.Lines());
          fchip.TackCube(ar->CubeSample(), ar->CubeLine());
          fchip.Load(trans);

//  Writes correlated chips to files for visual inspection
#if defined(ISIS_DEBUG)
          ostringstream tstr;
          tstr << "R" << r << "C" << c << "_chip.cub";
          string fcname("from"  + tstr.str());
          string mcname("match" + tstr.str());

          pchip.Write(mcname);
          fchip.Write(fcname);
#endif

          MultivariateStatistics mstats;
          for (int line = 1 ; line <= fchip.Lines() ; line++) {
            for(int sample = 1; sample < fchip.Samples(); sample++) {
              double fchipValue = fchip.GetValue(sample,line);
              double pchipValue = pchip.GetValue(sample,line);
              mstats.AddData(&fchipValue, &pchipValue, 1);
            }
          }

//  Get regression and correlation values
          mstats.LinearRegression(reg.B0, reg.B1);
          reg.Bcorr = mstats.Correlation();
          if (IsSpecial(reg.B0)) throw 1;
          if (IsSpecial(reg.B1)) throw 2;
          if (IsSpecial(reg.Bcorr)) throw 3;
        } 
        catch (...) {
//  If fails, flag this condition
          reg.B0 = 0.0;
          reg.B1= 0.0;
          reg.Bcorr = 0.0;
        }

        reglist.push_back(reg);
      }

      // Add the measures to a control point
      string str = "Row " + iString(r) + " Column " + iString(c);
      ControlPoint cp(str);
      cp.SetType(ControlPoint::Tie);
      cp.Add(cmTrans);
      cp.Add(cmMatch);
      if (!cmTrans.IsMeasured()) cp.SetIgnore(true);
      cn.Add(cp);
      prog.CheckStatus();
    }
  }

  // If flatfile was entered, create the flatfile
  // The flatfile is comma seperated and can be imported into an excel
  // spreadsheet
  if (ui.WasEntered("FLATFILE")) {
    string fFile = ui.GetFilename("FLATFILE");
    ofstream os;
    string fFileExpanded = Filename(fFile).Expanded();
    os.open(fFileExpanded.c_str(),ios::out);
    dumpResults(os, reglist, jparms, *ar);
  }

  // If a cnet file was entered, write the ControlNet pvl to the file
  if (ui.WasEntered("CNETFILE")) {
    cn.Write(ui.GetFilename("CNETFILE"));
  }

  // Don't need the cubes opened anymore
  trans.Close();
  match.Close();


  // Write translation to log
  PvlGroup results("AverageTranslation");
  if (jparms.sStats.ValidPixels() > 0) {
    double sTrans = (int)(jparms.sStats.Average() * 100.0) / 100.0;
    double lTrans = (int)(jparms.lStats.Average() * 100.0) / 100.0;
    results += PvlKeyword ("Sample",sTrans);
    results += PvlKeyword ("Line",lTrans);
    results += PvlKeyword ("NSuspects",jparms.nSuspects);
  }
  else {
    results += PvlKeyword ("Sample","NULL");
    results += PvlKeyword ("Line","NULL");
  }

  Application::Log(results);

  // add the auto registration information to print.prt
  PvlGroup autoRegTemplate = ar->RegTemplate(); 
  Application::Log(autoRegTemplate); 

  return;
}
Beispiel #2
0
void IsisMain() {
  // Get user interface
  UserInterface &ui = Application::GetUserInterface();

  bool register_ignored = ui.GetBoolean("REGISTERIGNOREDONLY");

  // Open the files list in a SerialNumberList for
  // reference by SerialNumber
  SerialNumberList files(ui.GetFilename("FILES"));

  // Create a ControlNet from the input file
  ControlNet inNet(ui.GetFilename("CNET"));

  // Create an AutoReg from the template file
  Pvl pvl(ui.GetFilename("TEMPLATE"));
  AutoReg *ar = AutoRegFactory::Create(pvl);

  // Create the output ControlNet
  ControlNet outNet;
  outNet.SetType(inNet.Type());
  outNet.SetUserName(Application::UserName());
  outNet.SetDescription(inNet.Description());
  outNet.SetCreatedDate(iTime::CurrentLocalTime());
  outNet.SetTarget(inNet.Target());
  outNet.SetNetworkId(inNet.NetworkId());

  Progress progress;
  progress.SetMaximumSteps(inNet.Size());
  progress.CheckStatus();

  int ignored=0, unmeasured=0, registered=0, unregistered=0, validated=0;

  CubeManager cubeMgr;
  cubeMgr.SetNumOpenCubes(50);

  // Register the points and create a new
  // ControlNet containing the refined measurements
  for (int i=0; i<inNet.Size(); i++) {
    ControlPoint &inPoint = inNet[i];

    ControlPoint outPoint;
    outPoint.SetType(inPoint.Type());
    outPoint.SetId(inPoint.Id());
    outPoint.SetUniversalGround(inPoint.UniversalLatitude(), inPoint.UniversalLongitude(), inPoint.Radius());
    outPoint.SetHeld(inPoint.Held());
    outPoint.SetIgnore(inPoint.Ignore());

    // CHECK TO SEE IF THE CONTROL POINT SHOULD BE REGISTERED

    // "Ignore" point and we are not registering ignored
    if (inPoint.Ignore() && !register_ignored){
      ignored++;
      // add "Ignored" to network only if indicated
      if (ui.GetBoolean("OUTPUTIGNORED")) {
        // only include appropriate control measures
        for (int j = 0; j < inPoint.Size(); j++) {
          if (inPoint[j].IsMeasured()){
            outPoint.Add(inPoint[j]); 
          } 
          else{
            unmeasured++;
            if (ui.GetBoolean("OUTPUTUNMEASURED")){
              outPoint.Add(inPoint[j]); 
            } 
          }
        }
        // only add this point if OUTPUTIGNORED
        outNet.Add(outPoint);
      }
      // go to next control point
      continue;
    }
    // Not "Ignore" point (i.e. "valid") and we are only registering "Ignored"
    else if (!inPoint.Ignore() && register_ignored) {
      // add all "valid" points to network
      // only include appropriate control measures
      for (int j = 0; j < inPoint.Size(); j++) {
        if (inPoint[j].IsMeasured()){
          outPoint.Add(inPoint[j]); 
        } 
        else{
          unmeasured++;
          if (ui.GetBoolean("OUTPUTUNMEASURED")) {
            outPoint.Add(inPoint[j]);
          } 
        }
      }
      // add this point since it is not ignored
      outNet.Add(outPoint);
      // go to next control point
      continue;
    }
    // "Ignore" point or "valid" point to be registered
    else { // if ( (inPoint.Ignore() && register_ignored) || (!inPoint.Ignore() && !register_ignored ) ) {
      if (inPoint.Ignore()) { outPoint.SetIgnore(false); }
      
      ControlMeasure &patternCM = inPoint[inPoint.ReferenceIndex()];
      Cube &patternCube = *cubeMgr.OpenCube(files.Filename(patternCM.CubeSerialNumber()));
      
      ar->PatternChip()->TackCube(patternCM.Sample(), patternCM.Line());
      ar->PatternChip()->Load(patternCube);
      
      if (patternCM.IsValidated()) validated++;
      if (!patternCM.IsMeasured()) continue;
      if(!patternCM.IsReference()) {
        patternCM.SetReference(true);
        patternCM.SetChooserName("Application pointreg");
        patternCM.SetDateTime();
      }
      outPoint.Add(patternCM);
      
      // reset goodMeasureCount for this point before looping measures
      int goodMeasureCount = 0; 
      // Register all the unvalidated measurements
      for (int j = 0; j < inPoint.Size(); j++) {
        // don't register the reference, go to next measure
        if (j == inPoint.ReferenceIndex()){
          if (!inPoint[j].Ignore()) goodMeasureCount++;
          continue;
        }
        // if the measurement is valid, keep it as is and go to next measure
        if (inPoint[j].IsValidated()) {
          validated++;
          outPoint.Add(inPoint[j]);
          if (!inPoint[j].Ignore()) goodMeasureCount++;
          continue;
        }
        // if the point is unmeasured, add to output only if necessary and go to next measure
        if (!inPoint[j].IsMeasured()) {
          unmeasured++;
          if (ui.GetBoolean("OUTPUTUNMEASURED")) {
            outPoint.Add(inPoint[j]);
          }
          continue;
        }
      
        ControlMeasure searchCM = inPoint[j];
      
        // refresh pattern cube pointer to ensure it stays valid
        Cube &patternCube = *cubeMgr.OpenCube(files.Filename(patternCM.CubeSerialNumber()));
        Cube &searchCube = *cubeMgr.OpenCube(files.Filename(searchCM.CubeSerialNumber()));

        ar->SearchChip()->TackCube(searchCM.Sample(), searchCM.Line());
      
        try {
          ar->SearchChip()->Load(searchCube,*(ar->PatternChip()),patternCube);
      
          // If the measurements were correctly registered
          // Write them to the new ControlNet
          AutoReg::RegisterStatus res = ar->Register();
      
          double score1, score2;
          ar->ZScores(score1, score2);
          searchCM.SetZScores(score1, score2);
      
          if(res == AutoReg::Success) {
            registered++;
            searchCM.SetType(ControlMeasure::Automatic);
            searchCM.SetError(searchCM.Sample() - ar->CubeSample(), searchCM.Line() - ar->CubeLine());
            searchCM.SetCoordinate(ar->CubeSample(),ar->CubeLine());
            searchCM.SetGoodnessOfFit(ar->GoodnessOfFit());
            searchCM.SetChooserName("Application pointreg");
            searchCM.SetDateTime();
            searchCM.SetIgnore(false);
            outPoint.Add(searchCM);
            goodMeasureCount++;
          }
          // Else use the original marked as "Estimated"
          else {
            unregistered++;
            searchCM.SetType(ControlMeasure::Estimated);
      
            if(res == AutoReg::FitChipToleranceNotMet) {
              searchCM.SetError(inPoint[j].Sample() - ar->CubeSample(), inPoint[j].Line() - ar->CubeLine());
              searchCM.SetGoodnessOfFit(ar->GoodnessOfFit());
            }
            searchCM.SetChooserName("Application pointreg");
            searchCM.SetDateTime();
            searchCM.SetIgnore(true);
            outPoint.Add(searchCM);
          }
        } catch (iException &e) {
          e.Clear();
          unregistered++;
          searchCM.SetType(ControlMeasure::Estimated);
          searchCM.SetChooserName("Application pointreg");
          searchCM.SetDateTime();
          searchCM.SetIgnore(true);
          outPoint.Add(searchCM);
        }
      }

      // Jeff Anderson put in this test (Dec 2, 2008) to allow for control 
      // points to be good so long as at least two measure could be 
      // registered. When a measure can't be registered to the reference then
      // that measure is set to be ignored where in the past the whole point
      // was ignored
      if (goodMeasureCount < 2) {
        if (!outPoint.Held() && outPoint.Type() != ControlPoint::Ground) {
          outPoint.SetIgnore(true);
        }
      }
      // Otherwise, ignore=false. This is already set at the beginning of the registration process

      // Check to see if the control point has now been assigned
      // to "ignore".  If not, add it to the network. If so, only 
      // add it to the output if the OUTPUTIGNORED parameter is selected
      // 2008-11-14 Jeannie Walldren
      if (!outPoint.Ignore()) {                             
        outNet.Add(outPoint);
      }
      else{                                              
        ignored++;                                   
        if (ui.GetBoolean("OUTPUTIGNORED")) outNet.Add(outPoint);
      }
    }
    progress.CheckStatus();
  }

  // If flatfile was entered, create the flatfile
  // The flatfile is comma seperated and can be imported into an excel
  // spreadsheet
  if (ui.WasEntered("FLATFILE")) {
    string fFile = Filename(ui.GetFilename("FLATFILE")).Expanded();
    ofstream os;
    os.open(fFile.c_str(),ios::out);
    os << "PointId,OriginalMeasurementSample,OriginalMeasurementLine," <<
      "RegisteredMeasurementSample,RegisteredMeasurementLine,SampleDifference," <<
      "LineDifference,ZScoreMin,ZScoreMax,GoodnessOfFit" << endl;
    os << NULL8 << endl;
    for (int i=0; i<outNet.Size(); i++) {
      // get point from output control net and its
      // corresponding point from input control net
      ControlPoint outPoint = outNet[i];
      ControlPoint *inPoint = inNet.Find(outPoint.Id());
      if (outPoint.Ignore()) continue;
      for (int i = 0; i<outPoint.Size();i++) {
        // get measure and find its corresponding measure from input net
        ControlMeasure cmTrans = outPoint[i];
        ControlMeasure cmOrig = (*inPoint)[cmTrans.CubeSerialNumber()];
        double inSamp = cmOrig.Sample();
        double inLine = cmOrig.Line();
        double outSamp = cmTrans.Sample();
        double outLine = cmTrans.Line();
        double sampErr = cmTrans.SampleError();
        double lineErr = cmTrans.LineError();
        double zScoreMin = cmTrans.GetZScoreMin();
        if (fabs(zScoreMin) <= DBL_EPSILON || zScoreMin == NULL8) zScoreMin = 0;
        double zScoreMax = cmTrans.GetZScoreMax();
        if (fabs(zScoreMax) <= DBL_EPSILON || zScoreMax == NULL8) zScoreMax = 0;
        double goodnessOfFit = cmTrans.GoodnessOfFit();
        if (fabs(goodnessOfFit) <= DBL_EPSILON || goodnessOfFit == NULL8) goodnessOfFit = 0;
        string pointId = outPoint.Id();
        
        os << pointId << "," << inSamp << ","
           << inLine << "," << outSamp << ","
           << outLine << "," << sampErr << "," 
           << lineErr << "," << zScoreMin << ","
           << zScoreMax << "," << goodnessOfFit << endl;
      }
    }
  }

  PvlGroup pLog("Points");
  pLog+=PvlKeyword("Ignored", ignored);
  Application::Log(pLog);

  PvlGroup mLog("Measures");
  mLog+=PvlKeyword("Validated", validated);
  mLog+=PvlKeyword("Registered", registered);
  mLog+=PvlKeyword("Unregistered", unregistered);
  mLog+=PvlKeyword("Unmeasured", unmeasured);
  Application::Log(mLog);

  // Log Registration Statistics
  Pvl arPvl = ar->RegistrationStatistics();

  for(int i = 0; i < arPvl.Groups(); i++) {
    Application::Log(arPvl.Group(i));
  }

  // add the auto registration information to print.prt
  PvlGroup autoRegTemplate = ar->RegTemplate(); 
  Application::Log(autoRegTemplate); 

  outNet.Write(ui.GetFilename("TO"));

  delete ar;
}