예제 #1
0
PointPairVector Space::pairsInZone(const PointVector& zone, unsigned int d)
{
    PointPairVector result;
    PointVector::const_iterator iter = zone.begin();
    PointVector::const_iterator endIter = zone.end();
    for(;iter!=endIter;++iter)
    {
        for(unsigned int i = 1;(iter+i)!=endIter;++i)
        {
            // optimization
            if(iter->distanceYTo(*(iter+i))>d) // if distance by Y is higher than d
            {
                if(iter->y < (iter+i)->y) // if current point is before second one
                    break; // there won't be more interesting points in d-neighborhood
                else
                    continue; // we could not reach interesting points yet
            }
            if(iter->distanceTo(*(iter+i))<=d) // if distance is lower than d
            {
                result.insert(PointPair(*iter,*(iter+i))); // add pair of d-neighbors
            }
        }
    }
    return result;
}
예제 #2
0
  /**
   * @brief Clone a point set from a nearby (left image) point and Gruen affine
   *
   * This method is used to clone a PointPair from a new point and an Affine
   * transform.  Assume the left point in the set is at the center of the box
   * and compute the offset of the point using the Affine.  Apply it the right
   * point.
   *
   * @param point    Chip center location
   * @param newpoint New point to clone to via application of affine transform
   * @param affine   The affine transform to apply to get new (right) clone
   *                  point
   *
   * @return PointPair The clone point from the original
   */
  SmtkPoint SmtkMatcher::Clone(const SmtkPoint &point,
                               const Coordinate &left) {

    //  Computes local chip location (chipLoc) with Affine.  This gives offset
    //   in right pixel space.  Simply add result to right point to get the
    //   new cloned right point.
    Coordinate offset = left - point.getLeft();
    Coordinate right = point.getRight() + point.getAffine().getPoint(offset);
    PointPair cpoint = PointPair(left, right);

    MatchPoint mpt = point.m_matchpt;
    mpt.m_point = cpoint;

    //  Currently will not have any valid geometry
    SmtkPoint spnt = SmtkPoint(mpt, PointGeometry(right), PointPair());
    spnt.m_registered = false;
    spnt.m_isValid = inCube(lhCamera(), left) && inCube(rhCamera(), right);
    return (spnt);
  }
예제 #3
0
  /**
   * @brief Create an SmtkPoint from Gruen match result
   *
   * This method applies the Gruen registration to the points as provided.  It
   * assumes the points have been already set up in the gruen algorithm (@see
   * Register()) and simply calls the Gruen::RegisterI() function.
   *
   * The result is the transformed into a SmtkPoint base upon the result of the
   * registration.  The status of the point is set to reflect the registration
   * processing result.
   *
   * @author Kris Becker - 5/26/2011
   *
   * @param left  Left point with geometry
   * @param right RIght point with geometry
   * @param gruen Gruen algorithm to use to register points
   *
   * @return SmtkPoint
   */
  SmtkPoint SmtkMatcher::makeRegisteredPoint(const PointGeometry &left,
                                             const PointGeometry &right,
                                             Gruen *gruen) {

    if (gruen->Register() != AutoReg::SuccessSubPixel) {
      return (SmtkPoint(PointPair(left.getPoint(),right.getPoint()),
                         PointPair(left.getGeometry(), right.getGeometry())));
    }

    // Registration point data
    MatchPoint match = gruen->getLastMatch();

    // Compute new right coordinate data
    Coordinate rcorr = Coordinate(gruen->CubeLine(), gruen->CubeSample());
    Coordinate rgeom = getLatLon(rhCamera(), rcorr);
    PointGeometry rpoint = PointGeometry(rcorr, rgeom);

    //  Get left and original right geometry
    PointPair pgeom = PointPair(left.getGeometry(), right.getGeometry());

    // Create SMTK point and determine status/validity
    SmtkPoint spnt = SmtkPoint(match, rpoint, pgeom);

    //  Check for valid mapping
    if ( !rpoint.isValid() ) {
      m_offImage++;
      spnt.m_isValid = false;
    }
    else {
     // Check for distance error
      double dist = (rcorr - right.getPoint()).getDistance();
      if (dist > gruen->getSpiceConstraint()) {
        m_spiceErr++;
        spnt.m_isValid = false;
      }
      else {
        spnt.m_isValid = match.isValid();
      }
    }

    return (spnt);
  }
예제 #4
0
PointPairVector Space::bruteNeighbors(const PointVector& vec, unsigned int start, unsigned int end, unsigned int d) const
{
    PointPairVector result;
    PointVector::const_iterator i = vec.begin()+start;
    PointVector::const_iterator j = vec.begin()+start+1;
    PointVector::const_iterator endIter = (end>=vec.size()) ? vec.end() : vec.begin()+end+1;
    for(;i<endIter;++i)
    {
        for(j=i+1;j<endIter;++j)
        {
            if(j->distanceTo(*i)<=d)
            {
                result.insert(PointPair(*i,*j));
            }
        }
    }
    return result;
}
예제 #5
0
  /**
   * @brief Create a valid, unregistered SmtkPoint
   *
   * This method is typically used to create a point from a control point
   * network.  The point is deemed registered, but not necessarily by Gruen.
   * Therefore, it is set as unregistered.
   *
   * The left and right coordinates are deemed valid and geometry for both
   * points is computed and verified (either the points are off image or does
   * not map to a lat/long).
   *
   * The points is set as valid and when Register() is called it will likely be
   * run through the Gruen algorithm.
   *
   * In essence, a valid, but unregistered SmtkPoint is returned if all the
   * line/sample coordinates and geometry check out.
   *
   * @author Kris Becker - 5/30/2011
   *
   * @param left  Left point
   * @param right Right point
   *
   * @return SmtkPoint
   */
  SmtkPoint SmtkMatcher::Create(const Coordinate &left,
                                const Coordinate &right) {

    // Check out left image point
    Coordinate lgeom = getLatLon(lhCamera(), left);
    if (!lgeom.isValid() ) {
      m_offImage ++;
      return (SmtkPoint(PointPair(left,right), PointPair(lgeom)));
    }

    // Check out right image point
    Coordinate rgeom = getLatLon(rhCamera(), right);
    if (!rgeom.isValid() ) {
      m_offImage ++;
      return (SmtkPoint(PointPair(left,right), PointPair(lgeom,rgeom)));
    }

    //  Make the point
    SmtkPoint spnt = SmtkPoint(PointPair(left,right), PointPair(lgeom,rgeom));
    spnt.m_matchpt.m_analysis.setZeroState();
    spnt.m_isValid = true;
    return (spnt);
  }
예제 #6
0
  /**
   * @brief Applies registration of two points
   *
   * This method applies the registration of a left and right point set.  The
   * points sets may only have the left point defined.  This method determines
   * the valid geometry of the left point.  If the right point is not defined,
   * it uses the left geometry to determine the right point to register the
   * left point with.  If the right point is defined, it verifies the point has
   * valid geometry mapping in the right image.  All points and geometry must
   * fall within the boundaries of the image and be valid or the point is
   * deemed invalid.
   *
   * Once the points is validated, registration is applied to the two points
   * using the left point as truth (or the pattern chip) and the right point
   * (search chip) is loaded according to the geometry of the left chip.  An
   * affine transform is immediately applied in the Gruen algorithm to apply
   * the user supplied state of the affine and radiometric parameters.
   *
   * @author Kris Becker - 6/4/2011
   *
   * @param lpg
   * @param rpg
   * @param affrad
   *
   * @return SmtkPoint
   */
  SmtkPoint SmtkMatcher::Register(const PointGeometry &lpg,
                                  const PointGeometry &rpg,
                                  const AffineRadio &affrad) {

    // Validate object state
    validate();

    // Test if the left point is defined. This will throw an error if this
    // situation occurs
    if (!lpg.getPoint().isValid()) {
      QString mess = "Left point is not defined which is required";
      throw IException(IException::Programmer, mess, _FILEINFO_);
    }

   // First we need a lat,lon from the left image to find the same place in
    // the right image.
    Coordinate lpnt = lpg.getPoint();
    Coordinate lgeom = lpg.getGeometry();
    if (!lgeom.isValid()) {
      lgeom = getLatLon(lhCamera(), lpnt);
    }

    // Construct geometry and check validity
    PointGeometry left = PointGeometry(lpnt, lgeom);
    if (!left.isValid()) {
      m_offImage++;
      return ( SmtkPoint(PointPair(lpnt), PointPair(lgeom)) );
    }

    // Validate the right point
    Coordinate rpnt = rpg.getPoint();
    Coordinate rgeom = rpg.getGeometry();
    if ( !rpnt.isValid() ) {
      if (rgeom.isValid()) {
        rpnt = getLineSample(rhCamera(), rgeom);
      }
      else {
        rpnt = getLineSample(rhCamera(), lgeom);
        rgeom = lgeom;
      }
    }
    else if (!rgeom.isValid() ){
      rgeom = getLatLon(rhCamera(), rpnt);
    }

    //  Construct and for good right geometry
    PointGeometry right = PointGeometry(rpnt, rgeom);
    if (!right.isValid()) {
      m_spiceErr++;
      return (SmtkPoint(PointPair(lpnt, rpnt), PointPair(lgeom, rgeom)));
    }

    try {
      // These calls are computationally expensive... can we fix it?
      m_gruen->PatternChip()->TackCube(lpnt.getSample(), lpnt.getLine());
      m_gruen->PatternChip()->Load(*m_lhCube);
      m_gruen->SearchChip()->TackCube(rpnt.getSample(), rpnt.getLine());
      m_gruen->SearchChip()->Load(*m_rhCube, *m_gruen->PatternChip(),
                                  *m_lhCube);
    }
    catch (IException &) {
      m_offImage++;  // Failure to load is assumed an offimage error
      return (SmtkPoint(PointPair(lpnt,rpnt), PointPair(lgeom,rgeom)));
    }

    // Register the points with incoming affine/radiometric parameters
    m_gruen->setAffineRadio(affrad);
    return (makeRegisteredPoint(left, right, m_gruen.get()));
  }