Ejemplo n.º 1
0
void MultiColorAdjustment::setAdjustmentForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
{
	assert(startLed <= endLed);
	assert(endLed < _ledAdjustments.size());

	// Get the identified adjustment (don't care if is nullptr)
	ColorAdjustment * adjustment = getAdjustment(id);
	for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
	{
		_ledAdjustments[iLed] = adjustment;
	}
}
//*************************************************************************************************
//! Saves the current active adjustment to the KWL file. If an adjustment of the same 
//! description already exists in the KWL, it is replaced by the current adjustment.
//*************************************************************************************************
void ossimAdjustableParameterInterface::saveCurrentAdjustmentOnly(ossimKeywordlist &kwl, 
                                                                  const ossimString &prefix) 
{
   // Fetch current adjustment:
   ossimAdjustmentInfo adjTosave;
   getAdjustment(adjTosave);
   ossimString currentLabel = adjTosave.getDescription();

   // Fetch the number of adjustments specified in the KWL:
   int numberOfAdjustments = 0;
   const char* value = kwl.find(prefix, NUMBER_OF_ADJUSTMENTS_KW);
   if (value)
   {
      numberOfAdjustments = atoi(value);
   }

   // Loop to read the descriptions of each adjustment in the KWL to see if a match exists. If 
   // we reach the end, insert it there:
   // int saved_adj_idx;
   ossimAdjustmentInfo adjInfo;
   int i = 0;
   while (true)
   {
      ossimString adjPrefix = prefix+(ossimString(ADJUSTMENT_PREFIX)+ossimString::toString(i)+".");
      if (i < numberOfAdjustments)
      {
         adjInfo.loadState(kwl, adjPrefix);
      }
      
      if ((i == numberOfAdjustments) || (adjInfo.getDescription() == currentLabel))
      {
         // match found or end of list, insert the  new adjustment at this position:
         adjTosave.saveState(kwl, adjPrefix);
         // saved_adj_idx = i;

         // Need to bump the number of adjustments by one if we added a new one:
         if (i == numberOfAdjustments)
         {
            kwl.add(prefix, NUMBER_OF_ADJUSTMENTS_KW, ++numberOfAdjustments);
         }

         break;
      }
      ++i;
   }

   //// Sync up this object with the contents of the KWL: NOT NEEDED???
   //loadAdjustments(kwl, prefix);
   //setCurrentAdjustment(saved_adj_idx);
}
void ossimAdjustableParameterInterface::getAdjustment(ossimAdjustmentInfo& adj) const
{
   getAdjustment(theCurrentAdjustment,  adj);
}
Ejemplo n.º 4
0
double
ossimRpcProjection::optimizeFit(const ossimTieGptSet& tieSet, double* /* targetVariance */)
{
#if 1
   //NOTE : ignore targetVariance
   ossimRefPtr<ossimRpcSolver> solver = new ossimRpcSolver(false, false); //TBD : choices should be part of setupFromString

   std::vector<ossimDpt> imagePoints;
   std::vector<ossimGpt> groundPoints;
   tieSet.getSlaveMasterPoints(imagePoints, groundPoints);
   solver->solveCoefficients(imagePoints, groundPoints);

   ossimRefPtr< ossimImageGeometry > optProj = solver->createRpcProjection();
   if (!optProj)
   {
      ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimRpcProjection::optimizeFit(): error when optimizing the RPC with given tie points"
                                             << std::endl;
      return -1.0;
   }

   if(optProj->hasProjection())
   {
      ossimKeywordlist kwl;
      optProj->getProjection()->saveState(kwl);
      this->loadState(kwl);
   }

   return std::pow(solver->getRmsError(), 2); //variance in pixel^2
#else
   // COPIED from ossimRpcProjection
   //
   //
   //use a simple Levenberg-Marquardt non-linear optimization
   //note : please limit the number of tie points
   //
   //INPUTS: requires Jacobian matrix (partial derivatives with regards to parameters)
   //OUTPUTS: will also compute parameter covariance matrix
   //
   //TBD: use targetVariance!
 
   int np = getNumberOfAdjustableParameters();
   int nobs = tieSet.size();

   //setup initail values
   int iter=0;
   int iter_max = 200;
   double minResidue = 1e-10; //TBC
   double minDelta = 1e-10; //TBC

   //build Least Squares initial normal equation
   // don't waste memory, add samples one at a time
   NEWMAT::SymmetricMatrix A;
   NEWMAT::ColumnVector residue;
   NEWMAT::ColumnVector projResidue;
   double deltap_scale = 1e-4; //step_Scale is 1.0 because we expect parameters to be between -1 and 1
   buildNormalEquation(tieSet, A, residue, projResidue, deltap_scale);
   double ki2=residue.SumSquare();

   //get current adjustment (between -1 and 1 normally) and convert to ColumnVector
   ossimAdjustmentInfo cadj;
   getAdjustment(cadj);
   std::vector< ossimAdjustableParameterInfo >& parmlist = cadj.getParameterList();
   NEWMAT::ColumnVector cparm(np), nparm(np);
   for(int n=0;n<np;++n)
   {
      cparm(n+1) = parmlist[n].getParameter();
   }

   double damping_speed = 2.0;
   //find max diag element for A
   double maxdiag=0.0;
   for(int d=1;d<=np;++d) {
      if (maxdiag < A(d,d)) maxdiag=A(d,d);
   }
   double damping = 1e-3 * maxdiag;
   double olddamping = 0.0;
   bool found = false;

//DEBUG TBR
cout<<"rms="<<sqrt(ki2/nobs)<<" ";
cout.flush();

   while ( (!found) && (iter < iter_max) ) //non linear optimization loop
   {
      bool decrease = false;

      do
      {
         //add damping update to normal matrix
         for(int d=1;d<=np;++d) A(d,d) += damping - olddamping;
         olddamping = damping;

         NEWMAT::ColumnVector deltap = solveLeastSquares(A, projResidue);

         if (deltap.NormFrobenius() <= minDelta) 
         {
            found = true;
         } else {
            //update adjustment
            nparm = cparm + deltap;
            for(int n=0;n<np;++n)
            {
               setAdjustableParameter(n, nparm(n+1), false); //do not update now, wait
            }
            adjustableParametersChanged();

            //check residue is reduced
            NEWMAT::ColumnVector newresidue = getResidue(tieSet);
            double newki2=newresidue.SumSquare();
            double res_reduction = (ki2 - newki2) / (deltap.t()*(deltap*damping + projResidue)).AsScalar();
 //DEBUG TBR
       cout<<sqrt(newki2/nobs)<<" ";
       cout.flush();

            if (res_reduction > 0)
            {
               //accept new parms
               cparm = nparm;
               ki2=newki2;

               deltap_scale = max(1e-15, deltap.NormInfinity()*1e-4);

               buildNormalEquation(tieSet, A, residue, projResidue, deltap_scale);
               olddamping = 0.0;

               found = ( projResidue.NormInfinity() <= minResidue );
               //update damping factor
               damping *= std::max( 1.0/3.0, 1.0-std::pow((2.0*res_reduction-1.0),3));
               damping_speed = 2.0;
               decrease = true;
            } else {
               //cancel parameter update
               for(int n=0;n<np;++n)
               {
                  setAdjustableParameter(n, nparm(n+1), false); //do not update right now
               }
               adjustableParametersChanged();

               damping *= damping_speed;
               damping_speed *= 2.0;
            }
         }
      } while (!decrease && !found);
      ++iter;
   }

//DEBUG TBR
cout<<endl;

   //compute parameter correlation
   // use normal matrix inverse
   //TBD

   return ki2/nobs;
#endif
}