12 #include "atp/AtpCommon.h" 16 static const int DEFAULT_CMP_PATCH_SIZING_FACTOR = 2;
17 static const double DEFAULT_NOMINAL_POSITION_ERROR = 50;
20 : m_nominalCmpPatchSize(0)
27 m_nominalCmpPatchSize(0)
34 m_nominalCmpPatchSize(0)
50 double total_error = 0;
53 if (refIVT.valid() && cmpIVT.valid())
55 ossimDpt gsd = refIVT->getOutputMetersPerPixel();
56 double nominalGsd = (gsd.
x + gsd.
y)/2.0;
60 refIVT->getImageGeometry()->getProjection());
62 cmpIVT->getImageGeometry()->getProjection());
67 total_error = ref_ce + cmp_ce;
68 double searchSizePixels = 2.0 * total_error / nominalGsd;
73 double searchSizePixels = 2.0*DEFAULT_NOMINAL_POSITION_ERROR/nominalGsd;
82 static const char* MODULE =
"ossimCorrelationSource::getTile() ";
85 CINFO<<
"\n\nossimCorrelationSource::getTile() -- tileRect UL: "<<tileRect.
ul()<<endl;
105 vector<ossimIpt> featurePoints;
109 if (featurePoints.empty())
113 for (
size_t i=0; i<featurePoints.size(); ++i)
116 atp->setRefViewPt(featurePoints[i]);
121 sid = atp->getTiePointId();
132 CINFO<<MODULE<<
"Before filtering: num matches in tile = "<<
m_tiePoints.size()<<endl;
137 unsigned int num_attempts = 0;
138 int corrStepSize = 1;
141 for (
int y = tileRect.
ul().
y;
y < tileRect.
lr().
y;
y += corrStepSize)
143 for (
int x = tileRect.
ul().
x;
x < tileRect.
lr().
x;
x += corrStepSize)
151 sid = atp->getTiePointId();
160 CINFO<<MODULE<<
"Tile match ratio: "<<
m_tiePoints.size()<<
" / "<<num_attempts<<endl;
170 vector<ossimIpt>& feature_points)
172 const char* MODULE =
"ossimCorrelationSource::findFeatures() -- ";
174 feature_points.clear();
177 CWARN<<MODULE<<
"WARNING: NULL or empty image data passed in."<<endl;
187 const int averaging_block_size = (int) refPatchSize;
193 CFATAL<<MODULE <<
"ERROR: Got null IplImage pointer converting from ossimImageData*!";
205 CvSize bufsize = cvGetSize(ipl_image);
206 mask = cvCreateImage(bufsize, IPL_DEPTH_8U, 1 );
209 for (
int y=0;
y<bufsize.height;
y++)
211 for (
int x=0;
x<=bufsize.width-1;
x++)
213 if (imageChip->
getPix(offset) != null_pixel)
214 mask->imageData[offset] = (
unsigned char) 0xFF;
216 mask->imageData[offset] = (
unsigned char) 0;
232 CvPoint2D32f* points = (CvPoint2D32f*)cvAlloc(num_pts*
sizeof(CvPoint2D32f));
233 cvGoodFeaturesToTrack(ipl_image, 0, 0, points, &num_pts, quality, refPatchSize, mask,
234 averaging_block_size, use_harris, harris_k);
239 unsigned int num_added = 0;
240 for(
int i=0; i<num_pts; i++)
244 CvPoint pt=cvPointFrom32f(points[i]);
254 feature_points.push_back(viewPt);
261 CINFO<<MODULE<<
"Number of features found in search patch: "<<num_added<<endl;
263 CINFO<<MODULE<<
"No features found."<<endl;
268 cvReleaseImage(&mask);
269 cvReleaseImage(&ipl_image);
270 cvFree((
void**)&points);
279 const ossimString MODULE(
"ossimCorrelationSource::correlate() -- ");
286 atp->getRefViewPoint(refViewPt);
287 ossimIrect refPatchRect(refViewPt, refPatchSize, refPatchSize);
292 if (!refpatch.valid())
294 CWARN << MODULE <<
"Error getting ref patch image data." << endl;
301 m_generator->getRefIVT()->viewToImage(refViewPt, refImgPt);
302 m_generator->getCmpIVT()->viewToImage(refViewPt, cmpImgPt);
303 CINFO<<
"\nFeature view pt: "<<refViewPt
304 <<
"\n REF img pt: "<<refImgPt
305 <<
"\n CMP img pt: "<<cmpImgPt<<endl;
306 refpatch->write(
"REF_PATCH.RAS");
309 refpatch->computeMinMaxPix(
min,
max);
310 if (
min.size() &&
max.size())
311 CINFO<<
" REF min, max: "<<(
int)
min[0]<<
", "<<(int)
max[0]<<endl;
318 CINFO<<MODULE <<
"REF patch contained a null pixel. Skipping this point..."<<endl;
323 if (!cmppatch.valid())
325 CWARN << MODULE <<
"Error getting cmp patch image data." << endl;
328 if (cmppatch->getDataObjectStatus() !=
OSSIM_FULL)
331 CINFO<<MODULE <<
"CMP patch contained a null pixel. Skipping this point..."<<endl;
337 cmppatch->write(
"CMP_PATCH.RAS");
339 cmppatch->computeMinMaxPix(
min,
max);
340 if (
min.size() &&
max.size())
341 CINFO <<
" CMP min, max: " << (
int)
min[0] <<
", " << (int)
max[0]<<
"\n" << endl;
347 int numMatches = atp->getNumMatches();
357 atp->getConfidenceMeasure(corr_value);
358 CINFO<<MODULE<<
"Match found for TP "<<atp->getTiePointId()<<
" = "<<corr_value<<endl;
361 CINFO<<MODULE<<
"No match found for TP "<<atp->getTiePointId()<<endl;
366 CWARN << MODULE <<
"Error encountered during correlation. Aborting correlation." << endl;
372 ossimDpt cmpimgpt,refimgpt,refviewpt,cmpviewpt;
374 atp->getRefImagePoint(refimgpt);
375 atp->getRefViewPoint(refviewpt);
376 atp->getCmpImagePoint(cmpimgpt);
377 atp->getCmpViewPoint(cmpviewpt);
378 atp->getRefGroundPoint(refGpt);
383 atp->getConfidenceMeasure(val);
384 atp->getVectorResidual(residual);
385 CINFO<<
"AutoTiePoint: ("<<atp->getTiePointId()<<
") has "<<numMatches<<
" matches,\n" 386 <<
" best: (" << val <<
") residual: " << residual <<
"\n" 387 <<
" ref gpt: "<<refGpt<<
"\n" 388 <<
" cmpimg center: "<<cmpimgpt<<
"\n" 389 <<
" refimg center: "<<refimgpt<<
"\n" 390 <<
" cmpview center: "<<cmpviewpt<<
"\n" 391 <<
" refview center: "<<refviewpt<<endl;
395 CINFO<<
"AutoTiePoint: (" << atp->getTiePointId() <<
") has no peaks.\n" 396 <<
" ref gpt: "<<refGpt<<
"\n" 397 <<
" refimg center: "<<refimgpt<<
"\n" 398 <<
" refview center: "<<refviewpt<<endl;
411 static const char* MODULE =
"ossimCorrelationSource::OpenCVCorrelation() -- ";
413 int ref_patch_size = refpatch->
getWidth();
414 int refPatchOffset = ref_patch_size / 2;
416 IplImage *cmpimage, *refimage, *result;
422 if (!cmpimage || !refimage)
424 CWARN << MODULE <<
"Error encountered creating IPL image tiles. Aborting..." << endl;
433 resdim.height = cmpimage->height - refimage->height + 1;
434 resdim.width = cmpimage->width - refimage->width + 1;
435 result = cvCreateImage(resdim, IPL_DEPTH_32F, 1);
438 CWARN << MODULE <<
"Error encountered creating IPL image tile (result). Aborting..." << endl;
444 cvMatchTemplate(cmpimage, refimage, result, (
int) corrMethod);
454 resultPatch->
write(
"CORR.RAS");
460 multimap<
float ,
ossimIpt , greater<float> > peaks_map;
462 for (
int dy = 0; dy < result->height; dy++)
464 for (
int dx = 0; dx < result->width; dx++)
467 corrCoef = ((
float*) (result->imageData + result->widthStep * dy))[dx];
468 if (corrCoef >= peak_threshold)
470 cmpPeakLocV.
x = cmpPatchLocV.x + refPatchOffset + dx;
471 cmpPeakLocV.
y = cmpPatchLocV.y + refPatchOffset + dy;
472 peaks_map.insert(pair<float, ossimIpt>(corrCoef, cmpPeakLocV));
477 if (peaks_map.size() > 0)
480 multimap<float, ossimIpt, greater<float> >::iterator peak = peaks_map.begin();
484 for (
unsigned int i = 0; (i < maxNumPeaks) && (peak != peaks_map.end()); i++)
486 cmpPeakLocV = peak->second;
487 corrCoef = peak->first;
488 atp->addViewMatch(cmpPeakLocV, corrCoef);
493 cvReleaseImage(&result);
494 cvReleaseImage(&refimage);
495 cvReleaseImage(&cmpimage);
virtual ossim_uint32 getWidth() const
virtual const double & getNominalPosError() const
Returns the estimated Absolute horizontal position error (CE90) of the sensor model.
JsonParam & getParameter(const char *paramName)
Returns a parameter (might be a null parameter if paramName not found in the configuration.
virtual void setImageRectangle(const ossimIrect &rect)
Base class for all automatic tiepoints.
IplImage * convertToIpl32(const ossimImageData *data)
std::shared_ptr< AtpGenerator > m_generator
bool OpenCVCorrelation(std::shared_ptr< AutoTiePoint > atp, const ossimImageData *refpatch, const ossimImageData *cmppatch)
unsigned int m_nominalCmpPatchSize
unsigned int asUint() const
const ossimIpt & ul() const
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &origin, ossim_uint32 rLevel=0)
Derived classes implement their particular tiepoint matching algorithms for the requested tile...
virtual ossimDataObjectStatus getDataObjectStatus() const
Base class for tile sources performing auto tie point extraction.
virtual ossim_float64 getPix(const ossimIpt &position, ossim_uint32 band=0) const
Will return the pixel at location position.
bool paramExists(const char *paramName) const
virtual void initialize()
Initialize the data buffer.
void copyIpl32ToOid(IplImage *ipl, ossimImageData *oid)
virtual bool write(const ossimFilename &f) const
Writes tile to stream.
virtual void initialize()
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
static ossimImageDataFactory * instance()
Base class for OSSIM-based ATP generators.
unsigned int ossim_uint32
virtual const ossim_float64 * getNullPix() const
virtual ossimIrect getImageRectangle() const
const ossimIpt & lr() const
virtual ossimRefPtr< ossimImageData > create(ossimSource *owner, ossimScalarType scalar, ossim_uint32 bands=1) const
THESE FUNCTIONS REQUIRE OPENCV.
ossimRefPtr< ossimImageData > m_tile
bool diagnosticLevel(unsigned int level) const
Convenience method returns TRUE if the currently set diagnostic level is <= level.
bool correlate(std::shared_ptr< AutoTiePoint > atp)
void findFeatures(const ossimImageData *data, std::vector< ossimIpt > &featurePts)
Given an image tile, locates prominent features in that tile. Use.
IplImage * convertToIpl(const ossimImageData *data)
Converts an ossimImageData pointer to an IplImage for use in OpenCV.
virtual ossim_uint32 getNumberOfInputs() const
Returns the number of input objects.
static AtpConfig & instance()
Singleton implementation.
virtual void initialize()
ossimDataObjectStatus
Definitions for data object status.
Singleton class maintaining parameters affecting the automatic tie point generation.
virtual ~ossimCorrelationSource()