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; }
/** * @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); }
/** * @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); }
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; }
/** * @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); }
/** * @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())); }