OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimAutRegUtil.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // File: ossimAutRegUtil.cpp
4 //
5 // License: LGPL
6 //
7 // License: See top level LICENSE.txt file.
8 //
9 // Author: David Hicks
10 //
11 // Description: Utility class for autonomous registration operations.
12 //
13 //----------------------------------------------------------------------------
14 // $Id$
15 
17 
21 #include <ossim/base/ossimDate.h>
24 #include <ossim/base/ossimIrect.h>
27 #include <ossim/base/ossimNotify.h>
32 #include <ossim/base/ossimTrace.h>
35 #include <ossim/base/ossimString.h>
36 #include <ossim/base/ossimNotify.h>
42 
47 #include <ossim/init/ossimInit.h>
48 
49 #include <iostream>
50 
51 static ossimTrace traceDebug ("ossimAutRegUtil:debug");
52 static ossimTrace traceLog("ossimAutRegUtil:log");
53 static ossimTrace traceOptions("ossimAutRegUtil:options");
54 
55 static const std::string APPLICATION_NAME_KW = "application_name";
56 static const std::string ADJ_DESC_LABEL_KW = "adj_desc_label";
57 static const std::string FALSE_KW = "false";
58 static const std::string IMG_1_KW = "img_1";
59 static const std::string IMG_2_KW = "img_2";
60 static const std::string IMG_M_KW = "img_m"; // master
61 static const std::string IMG_S_KW = "img_s"; // slave
62 static const std::string OP_KW = "operation";
63 static const std::string SRC_FILE_KW = "src_file";
64 static const std::string TRUE_KW = "true";
65 static const std::string ROI_CENTER_LAT_KW = "roi_center_lat";
66 static const std::string ROI_CENTER_LON_KW = "roi_center_lon";
67 static const std::string ROI_RADIUS_KW = "roi_radius"; // meters
68 static const std::string ROI_HEIGHT_KW = "roi_height"; // pixels
69 static const std::string ROI_MAX_LAT_KW = "roi_max_lat";
70 static const std::string ROI_MAX_LON_KW = "roi_max_lon";
71 static const std::string ROI_MIN_LAT_KW = "roi_min_lat";
72 static const std::string ROI_MIN_LON_KW = "roi_min_lon";
73 static const std::string ROI_WIDTH_KW = "roi_width"; // pixels
74 static const std::string REPORT_FILE_KW = "report_file";
75 
76 static const std::string FILE_KW = "file";
77 static const std::string IMG_KW = "image";
78 static const std::string READER_PROPERTY_KW = "reader_property";
79 
80 static const std::string OCV_CONFIG_FILE_KW = "ocv_config_file";
81 static const std::string OCV_DETECTOR_NAME_KW = "ocv_detector_name";
82 static const std::string OCV_DRAW_MATCHES_FLAG_KW = "ocv_draw_matches_flag";
83 static const std::string OCV_EXTRACTOR_NAME_KW = "ocv_extractor_name";
84 static const std::string OCV_MATCHER_NAME_KW = "ocv_matcher_name";
85 static const std::string OCV_MAX_MATCHES_KW = "ocv_max_matches";
86 static const std::string OCV_USE_CROSS_CHECK_KW = "ocv_use_cross_check";
87 static const std::string OCV_USE_GRID_ADAPTED_DETECT_KW = "ocv_use_grid_adapted_detect";
88 static const std::string OCV_RESULTS_WINDOW_SHOW_KW = "ocv_results_window_show";//????
89 
90 static const std::string OAX_CONFIG_FILE_KW = "oax_config_file";
91 static const std::string OAX_CONVERGENCE_CRITERIA_KW = "oax_convergence_criteria";
92 static const std::string OAX_GROUND_SIGMA_KW = "oax_ground_sigma";
93 static const std::string OAX_LAT_SIGMA_KW = "oax_lat_sigma";
94 static const std::string OAX_LON_SIGMA_KW = "oax_lon_sigma";
95 static const std::string OAX_HGT_SIGMA_KW = "oax_hgt_sigma";
96 static const std::string OAX_CONTROL_SIGMA_KW = "oax_control_sigma";
97 static const std::string OAX_MAX_ITERATIONS_KW = "oax_max_iterations";
98 
99 
100 //*****************************************************************************
101 // METHOD: ossimAutRegUtil::ossimAutRegUtil()
102 //
103 // Constructor.
104 //*****************************************************************************
106  : ossimReferenced(),
107  m_tGen(0),
108  m_tGenObj(0),
109  m_roiRects(),
110  m_showMatchWindow(false),
111  m_adjExec(0),
112  m_obsSet(0),
113  m_LatLonHgtSigmas(),
114  m_LatLonHgtControlSigmas(),
115  m_rep(0),
116  m_imgLayer(0),
117  m_kwl(new ossimKeywordlist()),
118  m_ocvKwl(0),
119  m_oaxKwl(0),
120  m_srcKwl(0),
121  m_operation(OSSIM_AUTREG_OP_UNKNOWN)
122 {
123  // traceDebug.setTraceFlag(true);
124  if (traceDebug())
125  {
127  << "\nossimAutRegUtil::ossimAutRegUtil 1 DEBUG:" << std::endl;
128  }
129 
130  // Default tie point ground sigmas
131  m_LatLonHgtSigmas[0] = 50.0;
132  m_LatLonHgtSigmas[1] = 50.0;
133  m_LatLonHgtSigmas[2] = 50.0;
134 
135  // Default control point ground sigmas
136  m_LatLonHgtControlSigmas[0] = 1.0;
137  m_LatLonHgtControlSigmas[1] = 1.0;
138  m_LatLonHgtControlSigmas[2] = 1.0;
139 
140  // ossimImageGeometry
141  m_geom[0] = 0;
142  m_geom[1] = 0;
143 
144  // Default control image flags
145  m_controlImage[0] = false;
146  m_controlImage[1] = false;
147 
148 
150 
151 }
152 
153 // Private/hidden
155 {
156 }
157 
158 // Private/hidden
160 {
161  return *this;
162 }
163 
164 
165 //*****************************************************************************
166 // DESTRUCTOR: ~ossimAutRegUtil()
167 //*****************************************************************************
169 {
170 
171  if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
172  << "DEBUG: ~ossimAutRegUtil(): entered..." << std::endl;
173 
174  clear();
175 
176  *m_rep << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
177  *m_rep << endl;
178 
179  if (traceDebug()) ossimNotify(ossimNotifyLevel_DEBUG)
180  << "DEBUG: ~ossimAutRegUtil(): returning..." << std::endl;
181 }
182 
183 
185 {
186  ossimString usageString = ap.getApplicationName();
187  usageString += " [option]... [input-option]... -img_1 <input-file 1> -img_2 <input-file 2>\n\nAvailable traces:\n-T \"ossimAutRegUtil:debug\" - General debug trace to standard out.\n-T \"ossimAutRegUtil:log\" - Writes a log file to output-file.log.\n-T \"ossimAutRegUtil:options\" - Writes the options to output-file-options.kwl.";
188 
190 
191  au->setCommandLineUsage(usageString);
192 
193  au->setDescription(ap.getApplicationName()+": Utility application for autonomous image registration.");
194 
195  au->addCommandLineOption("-h or --help", "Display this help and exit.");
196 
197  au->addCommandLineOption("--quality", "<quality>\nNOT WORKING... Desired quality of tiepoint collection.\nRange: 1 to 5, Default = 3");
198 
199  au->addCommandLineOption("--roi-center-llwh","<latitude> <longitude> <width> <height>\nSpecify the center ROI in latitude longitude space with width and height in pixels.");
200 
201  au->addCommandLineOption("--roi-center-llr","<latitude> <longitude> <radius_in_meters>\nSpecify the center ROI in latitude longitude space with radius in meters.");
202 
203  au->addCommandLineOption("--ocv_config_file","<file_path>\nSpecify a keyword list OpenCV configuration file.");
204 
205  au->addCommandLineOption("--oax_config_file","<file_path>\nSpecify a keyword list oax configuration file.");
206 
207 
208 } // End: ossimAutRegUtil::addArguments
209 
210 
212 {
213  // Must disconnect chains so that they destroy.
214  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator i = m_imgLayer.begin();
215  while ( i != m_imgLayer.end() )
216  {
217  (*i)->disconnect();
218  (*i) = 0;
219  ++i;
220  }
221  m_imgLayer.clear();
222 
223  // i = m_demLayer.begin();
224  // while ( i != m_demLayer.end() )
225  // {
226  // (*i)->disconnect();
227  // (*i) = 0;
228  // ++i;
229  // }
230  // m_demLayer.clear();
231 }
232 
234 {
235  static const char MODULE[] = "ossimAutRegUtil::initialize(ossimArgumentParser&)";
236 
237  if ( traceDebug() )
238  {
239  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
240  }
241 
242  clear();
243  if( ap.read("-h") || ap.read("--help") || (ap.argc() == 1) )
244  {
245  usage(ap);
246 
247  return false; // Indicates process should be terminated to caller.
248  }
249 
250  // Start with clean options keyword list.
251  m_kwl->clear();
252 
253  std::string tempString1;
254  ossimArgumentParser::ossimParameter stringParam1(tempString1);
255  std::string tempString2;
256  ossimArgumentParser::ossimParameter stringParam2(tempString2);
257  std::string tempString3;
258  ossimArgumentParser::ossimParameter stringParam3(tempString3);
259  std::string tempString4;
260  ossimArgumentParser::ossimParameter stringParam4(tempString4);
261 
262  double tempDouble1;
263  ossimArgumentParser::ossimParameter doubleParam1(tempDouble1);
264  double tempDouble2;
265  ossimArgumentParser::ossimParameter doubleParam2(tempDouble2);
266 
267  ossimString key = "";
268 
269  // Extract arguments and stuff them in a keyword list.
270  if( ap.read("--report_file", stringParam1) )
271  {
272  m_kwl->addPair( std::string(REPORT_FILE_KW), tempString1 );
273  }
274 
275  // report file
276  if( ap.read("--quality", stringParam1) )
277  {
278  m_kwl->addPair( std::string(ossimKeywordNames::QUALITY_KW), tempString1 );
279  }
280 
281  // operation
282  if( ap.read("--op", stringParam1) )
283  {
284  m_kwl->addPair( OP_KW, tempString1 );
285  }
286 
287  // image 1
288  if( ap.read("--img_1", stringParam1))
289  {
290  m_kwl->addPair( std::string(IMG_1_KW), tempString1 );
291  }
292 
293  // image 2
294  if( ap.read("--img_2", stringParam1))
295  {
296  m_kwl->addPair( std::string(IMG_2_KW), tempString1 );
297  }
298 
299  // master image
300  if( ap.read("--img_m", stringParam1))
301  {
302  m_kwl->addPair( std::string(IMG_M_KW), tempString1 );
303  }
304 
305  // slave image
306  if( ap.read("--img_s", stringParam1))
307  {
308  m_kwl->addPair( std::string(IMG_S_KW), tempString1 );
309  }
310 
311  // OpenCV config
312  if( ap.read("--ocv_config_file", stringParam1))
313  {
314  m_kwl->addPair( std::string(OCV_CONFIG_FILE_KW), tempString1 );
315  }
316 
317  // oax config
318  if( ap.read("--oax_config_file", stringParam1))
319  {
320  m_kwl->addPair( std::string(OAX_CONFIG_FILE_KW), tempString1 );
321  }
322 
323  // llwh chipping parameters
324  if( ap.read("--roi-center-llwh", stringParam1, stringParam2, stringParam3, stringParam4) )
325  {
326  m_kwl->addPair( ROI_CENTER_LAT_KW, tempString1 );
327  m_kwl->addPair( ROI_CENTER_LON_KW, tempString2 );
328  m_kwl->addPair( ROI_WIDTH_KW, tempString3 );
329  m_kwl->addPair( ROI_HEIGHT_KW, tempString4 );
330  }
331 
332  // llr chipping parameters
333  if( ap.read("--roi-center-llr", stringParam1, stringParam2, stringParam3) )
334  {
335  m_kwl->addPair( ROI_CENTER_LAT_KW, tempString1 );
336  m_kwl->addPair( ROI_CENTER_LON_KW, tempString2 );
337  m_kwl->addPair( ROI_RADIUS_KW, tempString3 );
338  }
339 
340  // TODO Necessary???
341  if( ap.read("--input-src", stringParam1) )
342  {
343  m_kwl->addPair( SRC_FILE_KW, tempString1 );
344  }
345 
346  // TODO For now, just an example of using ossimKeywordNames content
347  if( ap.read("--quality", stringParam1) )
348  {
349  m_kwl->addPair( std::string(ossimKeywordNames::QUALITY_KW), tempString1 );
350  }
351 
352  //---
353  // Deprecated: "--options-keyword-list"
354  //---
355  if( ap.read("--options", stringParam1) )
356  {
357  ossimFilename optionsKwl = tempString1;
358  if ( optionsKwl.exists() )
359  {
360  if ( m_kwl->addFile(optionsKwl) == false )
361  {
362  std::string errMsg = "ERROR could not open options keyword list file: ";
363  errMsg += optionsKwl.string();
364  throw ossimException(errMsg);
365  }
366  }
367  else
368  {
369  std::string errMsg = "ERROR options keyword list file does not exists: ";
370  errMsg += optionsKwl.string();
371  throw ossimException(errMsg);
372  }
373  }
374 
375 
376  // End of arg parsing.
377 
378 
380  if ( ap.errors() )
381  {
383  std::string errMsg = "Unknown option...";
384  throw ossimException(errMsg);
385  }
386 
387 
388  if ( ap.argc() >= 2 )
389  {
390  // Output file is last arg:
392  }
393  else
394  {
396  {
398  std::string errMsg = "Must supply an output file.";
399  throw ossimException(errMsg);
400  }
401  }
402 
403  if ( ap.argc() > 2 ) // User passed inputs in front of output file.
404  {
405  int pos = 1; // ap.argv[0] is application name.
406  while ( pos < (ap.argc()-1) )
407  {
408  ossimFilename file = ap[pos];
409  if ( traceDebug() )
410  {
412  << "argv[" << pos << "]: " << file << "\n";
413  }
414 
415  if ( isSrcFile(file) )
416  {
417  if ( m_kwl->find( SRC_FILE_KW.c_str() ) ) // --input-src used also
418  {
419  std::string errMsg = MODULE;
420  errMsg += "ERROR Multiple src files passed in. Please combine into one.";
421  throw ossimException(errMsg);
422  }
423 
424  m_kwl->addPair( SRC_FILE_KW, file.string() );
425  }
426  else // Add as an input image.
427  {
428  // key = IMG_KW;
429  // key += ossimString::toString(imgIdx);
430  // key += ".";
431  // key += FILE_KW;
432  // m_kwl->addPair(key.string(), file.string() );
433  // ++imgIdx;
434  }
435 
436  ++pos; // Go to next arg...
437 
438  } // End: while ( pos < (ap.argc()-1) )
439 
440  } // End: if ( ap.argc() > 2 )
441 
442  initialize();
443 
444  if ( traceDebug() )
445  {
446  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited..." << std::endl;
447  }
448  return true;
449 
450 } // End: void ossimAutRegUtil::initialize(ossimArgumentParser& ap)
451 
452 
454 {
455  clear();
456 
457  // Start with clean options keyword list.
458  m_kwl->clear();
459 
460  m_kwl->addList( kwl, true );
461 
462  initialize();
463 }
464 
465 
466 
468 {
469  static const char MODULE[] = "ossimAutRegUtil::initialize()";
470 
471  if ( traceDebug() )
472  {
473  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
474  }
475 
476  if ( traceOptions() )
477  {
478  ossimFilename optionsFile;
479  getOutputFilename(optionsFile);
480  optionsFile = optionsFile.noExtension();
481  optionsFile += "-options.kwl";
482  ossimString comment = " Can be use for --options argument.";
483  m_kwl->write( optionsFile.c_str(), comment.c_str() );
484  }
485 
486  // Determine the operation to do.
487  std::string op = m_kwl->findKey( OP_KW );
488  if ( op.size() )
489  {
490  ossimString s = op;
491  s.downcase();
492 
493  if ( s == "coreg" )
494  {
496  }
497  else if ( s == "masreg" )
498  {
500  }
501  else
502  {
503  std::string errMsg = "unknown operation: ";
504  errMsg += s.string();
505  throw ossimException(errMsg);
506  }
507  }
508  else
509  {
510  std::string errMsg = "keyword not found: ";
511  errMsg += OP_KW;
512  errMsg += "\nUse --op option to specify operation.\n";
513  throw ossimException(errMsg);
514  }
515 
516  //---
517  // Report file
518  //---
519  ossimFilename repFile = m_kwl->findKey( REPORT_FILE_KW );
520 
521  if (repFile.size())
522  {
523  m_rep = new ofstream( repFile.c_str(), ios::out );
524  }
525  else
526  {
527  m_rep = &std::cout;
528  }
529  *m_rep << "\n ossimAutRegUtil Summary..."<<std::endl;
530  ossimString ts;
531  ossim::getFormattedTime("%a %m.%d.%y %H:%M:%S", false, ts);
532  *m_rep << "\n" << ts;
533  *m_rep << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
534  *m_rep << endl;
535 
536 
537  //---
538  // Populate the m_srcKwl if --src option was set.
539  // Note do this before creating chains.
540  //---
542 
543  //---
544  // Load OpenCV config if --ocv_config_file option was set.
545  //---
547 
548  //---
549  // Load oax config if --oax_config_file option was set.
550  //---
552 
553 
554  //---
555  // Load input image pair
556  //---
557  if (!loadImages())
558  {
559  throw ossimException("loadImages() failed...");
560  }
561 
562 //=========================================================
563 // TODO... Is there a possibility of ortho image input?
564 // What about associated geometry/adjustbale parameters?
565 //=========================================================
566  //--
567  // Raw image input
568  //--
571 
572 
573  //---
574  // Determine overlap ROIs
575  //---
576  if (!delineateROIs())
577  {
578  throw ossimException("delineateROIs() failed...");
579  }
580 
581 
582  if ( traceLog() )
583  {
584  ossimKeywordlist logKwl;
585  // m_writer->saveStateOfAllInputs(logKwl);
586 
587  ossimFilename logFile;
588  getOutputFilename(logFile);
589  logFile.setExtension("log");
590 
591  logKwl.write( logFile.c_str() );
592  }
593 
594 
595  if ( traceDebug() )
596  {
598  << "options keyword list:\n"
599  << *(m_kwl.get()) << "\n";
600 
601  if ( m_srcKwl.valid() )
602  {
604  << "support record keyword list:\n"
605  << *(m_srcKwl.get()) << "\n";
606  }
607  }
608 
609  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
610  // Instantiate ossimTieMeasurementGenerator
611  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
613  createObject(ossimString("ossimTieMeasurementGenerator"));
614  if(m_tGenObj.valid())
615  {
617  }
618  else
619  {
620  throw ossimException("ossimTieMeasurementGenerator createObject failed...");
621  }
622 
623  if ( traceDebug() )
624  {
625  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
626  }
627 
628 } // End: void ossimAutRegUtil::initialize()
629 
630 
631 
632 //*****************************************************************************
633 // METHOD: ossimAutRegUtil::loadImages()
634 //
635 // Load image pair.
636 //
637 //*****************************************************************************
639 {
640  static const char MODULE[] = "ossimAutRegUtil::loadImages";
641 
642  if (traceDebug())
643  {
644  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
645  }
646 
647  bool isGoodLoad = false;
648  ossimFilename inputFile;
649 
650  ossimString key;
651 
652 
653  // Load 1st image
655  {
656  key = IMG_1_KW;
657  }
658  else // Load master image
659  {
660  key = IMG_M_KW;
661  m_controlImage[0] = true;
662  }
663  inputFile = m_kwl->findKey(key.string());
664  if (addImgSource(inputFile, 0 ))
665  {
666  ossimImageHandler *ih1 = m_imgLayer[0]->getImageHandler().get();
667  if (!ih1)
668  {
669  *m_rep << " open for image 1 failed..."<<std::endl;
670  }
671  else
672  {
673  int overviews = ih1->getNumberOfDecimationLevels();
674  ossimIrect bounds = ih1->getBoundingRect(0);
675  // ossimScalarType scalarType = ih1->getOutputScalarType();
677  *m_rep << "-----------------" << endl
678  << "filename = " << ih1->getFilename() << endl
679  << "width = " << bounds.width() << endl
680  << "height = " << bounds.height() << endl
681  << "overview count = " << (overviews-1) << endl
682  << "scalar type = " << lut->getEntryString(ih1->getOutputScalarType()) << endl
683  << "Handler used = " << ih1->getClassName() << endl;
684 
685 
686  // Load 2nd image
688  {
689  key = IMG_2_KW;
690  }
691  else // Load slave image
692  {
693  key = IMG_S_KW;
694  m_controlImage[1] = false;
695  }
696  inputFile = m_kwl->findKey(key.string());
697  if (addImgSource(inputFile, 0 ))
698  {
699  ossimImageHandler *ih2 = m_imgLayer[1]->getImageHandler().get();
700  if (!ih2)
701  {
702  *m_rep << " open for image 2 failed"<<std::endl;
703  }
704  else
705  {
706  int overviews = ih2->getNumberOfDecimationLevels();
707  ossimIrect bounds = ih2->getBoundingRect(0);
708  // ossimScalarType scalarType = ih2->getOutputScalarType();
710  *m_rep << "-----------------" << endl
711  << "filename = " << ih2->getFilename() << endl
712  << "width = " << bounds.width() << endl
713  << "height = " << bounds.height() << endl
714  << "overview count = " << (overviews-1) << endl
715  << "scalar type = " << lut->getEntryString(ih2->getOutputScalarType()) << endl
716  << "Handler used = " << ih2->getClassName() << endl;
717  *m_rep << "-----------------" << endl;
718  isGoodLoad = true;
719  }
720  }
721  }
722  }
723 
724  if (traceDebug())
725  {
726  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
727  }
728  return isGoodLoad;
729 }
730 
731 
732 //*****************************************************************************
733 // METHOD: ossimAutRegUtil::delineateROIs()
734 //
735 // Determine correlation region of interest.
736 //
737 //*****************************************************************************
739 {
740  static const char MODULE[] = "ossimAutRegUtil::delineateROIs";
741 
742  if (traceDebug())
743  {
744  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
745  }
746 
747  bool isGoodOp = false;
748 
749  for (int img=0; img<2; ++img)
750  {
751  ossimIrect rect;
752  rect.makeNan();
753 
754  ossimImageSource* source = m_imgLayer[img].get();
755 
756  if ( source )
757  {
758 
759  if ( m_geom[img].valid() )
760  {
761  if ( m_kwl->find( ROI_CENTER_LAT_KW.c_str() ) )
762  {
763  // "ROI Center" with: --roi-center-llwh or --roi-center-llr:
764  ossimString latStr = m_kwl->findKey( ROI_CENTER_LAT_KW );
765  ossimString lonStr = m_kwl->findKey( ROI_CENTER_LON_KW );
766  if ( latStr.size() && lonStr.size() )
767  {
768  ossimGpt centerGpt;
769 
770  //---
771  // Want the height nan going into worldToLocal call so it gets picked
772  // up by the elevation manager.
773  //---
774  centerGpt.makeNan();
775 
776  centerGpt.lat = latStr.toFloat64();
777  centerGpt.lon = lonStr.toFloat64();
778 
779  if ( !centerGpt.isLatNan() && !centerGpt.isLonNan() )
780  {
781  // Ground "cut center" to view:
782  ossimDpt centerDpt(0.0, 0.0);
783  m_geom[img]->worldToLocal(centerGpt, centerDpt);
784 
785  if ( !centerDpt.hasNans() )
786  {
787  // if ( isIdentity() && m_ivt.valid() ) // Chipping in image space.
788  if ( m_ivt[img].valid() ) // Chipping in image space.
789  {
790  // Transform image center point to view:
791  ossimDpt ipt = centerDpt;
792  m_ivt[img]->imageToView( ipt, centerDpt );
793  }
794 
795  // --roi-center-llwh:
796  ossimString widthStr = m_kwl->findKey( ROI_WIDTH_KW );
797  ossimString heightStr = m_kwl->findKey( ROI_HEIGHT_KW );
798  if ( widthStr.size() && heightStr.size() )
799  {
800  ossim_int32 width = widthStr.toInt32();
801  ossim_int32 height = heightStr.toInt32();
802  if ( width && height )
803  {
804  ossimIpt ul( ossim::round<int>(centerDpt.x - (width/2)),
805  ossim::round<int>(centerDpt.y - (height/2)) );
806  ossimIpt lr( (ul.x + width - 1), ul.y + height - 1);
807  rect = ossimIrect(ul, lr);
808  }
809  }
810  else // --roi-center-llr:
811  {
812  ossimString radiusStr = m_kwl->findKey( ROI_RADIUS_KW );
813  if ( radiusStr.size() )
814  {
815  ossim_float64 radius = radiusStr.toFloat64();
816  if ( radius )
817  {
818  ossimDpt mpp;
819  m_geom[0]->getMetersPerPixel( mpp );
820 
821  if ( !mpp.hasNans() )
822  {
823  ossim_float64 rx = radius/mpp.x;
824  ossim_float64 ry = radius/mpp.y;
825 
826  ossimIpt ul( ossim::round<int>( centerDpt.x - rx ),
827  ossim::round<int>( centerDpt.y - ry ) );
828  ossimIpt lr( ossim::round<int>( centerDpt.x + rx ),
829  ossim::round<int>( centerDpt.y + ry ) );
830  rect = ossimIrect(ul, lr);
831  }
832  }
833  }
834  }
835  }
836 
837  } // Matches: if ( !centerGpt.hasNans() )
838 
839  } // Matches: if ( latStr && lonStr )
840 
841  } // Matches: if ( m_kwl->find( ROI_CENTER_LAT_KW ) )
842 
843  } // if ( igeom.valid() )
844 
845  else
846  {
847  // Should never happen...
848  std::string errMsg = MODULE;
849  if ( !source )
850  {
851  errMsg += " image source null!";
852  }
853  throw( ossimException(errMsg) );
854  }
855 
856  // rect.print(*m_rep);
857  m_roiRects.push_back(rect);
858  } // if ( source )
859 
860  }
861 
862  isGoodOp = true;
863 
864 
865  if (traceDebug())
866  {
867  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
868  }
869  return isGoodOp;
870 }
871 
872 
873 //*****************************************************************************
874 // METHOD: ossimAutRegUtil::populateObsSet()
875 //
876 // Transfer tie points from generator to observation set.
877 //
878 //*****************************************************************************
880 {
881  static const char MODULE[] = "ossimAutRegUtil::populateObsSet";
882 
883  if (traceDebug())
884  {
885  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
886  }
887 
888  bool isGoodLoad = true;
889 
890  ossimString id;
891  ossimGpt gp;
892 
893 
894  for (int m=0; m<m_tGen->numMeasurements(); ++m)
895  {
896  id = ossimString::toString(m+1);
897 
898  // Initialize ground point
899  gp.makeNan();
901 
902  for (int img=0; img<2; ++img)
903  {
904  ossimDpt imgPt = m_tGen->pointIndexedAt(img,m);
905  // If control, set ground coordinates and reset sigmas
906  if (m_controlImage[img])
907  {
908  // Point drop to get control coordinates
909  ossimGpt worldPt;
910  m_geom[img]->localToWorld(imgPt, worldPt);
911  if (worldPt.isHgtNan())
912  {
913  ossim_float64 hgt =
915  worldPt.height(hgt);
916  }
917  pt->Gpt() = worldPt;
918 
919  // Set control sigmas
920  pt->setGroundSigmas
922  }
923  else
924  {
925  // Get image filename
926  ossimFilename filename = m_imgLayer[img]->getImageHandler()->getFilename();
927 
928  // Add measurement to point observation
929  pt->addMeasurement(imgPt, filename);
930  }
931  }
932  // Add point observation to set
933  if (pt->numMeas() > 0)
934  {
936  }
937  }
938 
939 
940  if (traceDebug())
941  {
942  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
943  }
944  return isGoodLoad;
945 }
946 
947 
948 //*****************************************************************************
949 // METHOD: ossimAutRegUtil::configureTieMeasGenerator()
950 //
951 // Configure the tie measurement generator using m_ocvKwl
952 //
953 //*****************************************************************************
955 {
956  static const char MODULE[] = "ossimAutRegUtil::configureTieMeasGenerator";
957 
958  if (traceDebug())
959  {
960  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
961  }
962 
963  if ( m_ocvKwl.valid() )
964  {
965 
966  // Draw OpenCV match window
967  m_showMatchWindow = keyIsTrue(m_ocvKwl, OCV_DRAW_MATCHES_FLAG_KW);
969 
970  // OpenCV detector
971  if (m_ocvKwl->find(OCV_DETECTOR_NAME_KW.c_str()))
972  {
973  m_tGen->setFeatureDetector(m_ocvKwl->findKey(OCV_DETECTOR_NAME_KW));
974  }
975 
976  // OpenCV descriptor/extractor
977  if (m_ocvKwl->find(OCV_EXTRACTOR_NAME_KW.c_str()))
978  {
979  m_tGen->setDescriptorExtractor(m_ocvKwl->findKey(OCV_EXTRACTOR_NAME_KW));
980  }
981 
982  // OpenCV matcher
983  if (m_ocvKwl->find(OCV_MATCHER_NAME_KW.c_str()))
984  {
985  m_tGen->setDescriptorMatcher(m_ocvKwl->findKey(OCV_MATCHER_NAME_KW));
986  }
987 
988  // OpenCV maximum number of matches
989  if (m_ocvKwl->find(OCV_MAX_MATCHES_KW.c_str()))
990  {
991  ossimString maxMatches = m_ocvKwl->findKey(OCV_MAX_MATCHES_KW);
992  if (maxMatches.size())
993  {
994  ossim_int32 max = maxMatches.toInt32();
996  }
997  }
998 
999  // TODO: set crossCheck currently commented out in ossimTieMeasurementGenerator
1000  // m_tGen->setUseCrossCheck(keyIsTrue(m_ocvKwl, OCV_USE_CROSS_CHECK_KW));
1001 
1002  // Use OpenCV GridAdaptedFeatureDetector
1003  m_tGen->setUseGrid(keyIsTrue(m_ocvKwl, OCV_USE_GRID_ADAPTED_DETECT_KW));
1004 
1005  }
1006 
1007  if (traceDebug())
1008  {
1009  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1010  }
1011 }
1012 
1013 
1014 //*****************************************************************************
1015 // METHOD: ossimAutRegUtil::configureAdjustmentExecutive()
1016 //
1017 // Configure the adjustment executive using m_oaxKwl
1018 //
1019 //*****************************************************************************
1021 {
1022  static const char MODULE[] = "ossimAutRegUtil::configureAdjustmentExecutive";
1023 
1024  if (traceDebug())
1025  {
1026  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1027  }
1028 
1029  if ( m_oaxKwl.valid() )
1030  {
1031 
1032  if (m_oaxKwl->find(OAX_MAX_ITERATIONS_KW.c_str()))
1033  {
1034  ossimString maxIter = m_oaxKwl->findKey(OAX_MAX_ITERATIONS_KW);
1035  if (maxIter.size())
1036  {
1037  ossim_int32 max = maxIter.toInt32();
1039  }
1040  }
1041 
1042  if (m_oaxKwl->find(OAX_CONVERGENCE_CRITERIA_KW.c_str()))
1043  {
1044  ossimString conv = m_oaxKwl->findKey(OAX_CONVERGENCE_CRITERIA_KW);
1045  if (conv.size())
1046  {
1047  ossim_float64 convPerc = conv.toFloat64();
1048  m_adjExec->setConvCriteria(convPerc);
1049  }
1050  }
1051 
1052  if (m_oaxKwl->find(OAX_GROUND_SIGMA_KW.c_str()))
1053  {
1054  ossimString conv = m_oaxKwl->findKey(OAX_GROUND_SIGMA_KW);
1055  if (conv.size())
1056  {
1057  ossim_float64 gndSigma = conv.toFloat64();
1058  m_LatLonHgtSigmas[0] = gndSigma;
1059  m_LatLonHgtSigmas[1] = gndSigma;
1060  m_LatLonHgtSigmas[2] = gndSigma;
1061  }
1062  }
1063 
1064  if (m_oaxKwl->find(OAX_CONTROL_SIGMA_KW.c_str()))
1065  {
1066  ossimString conv = m_oaxKwl->findKey(OAX_CONTROL_SIGMA_KW);
1067  if (conv.size())
1068  {
1069  ossim_float64 gndSigma = conv.toFloat64();
1070  m_LatLonHgtControlSigmas[0] = gndSigma;
1071  m_LatLonHgtControlSigmas[1] = gndSigma;
1072  m_LatLonHgtControlSigmas[2] = gndSigma;
1073  }
1074  }
1075 
1076  if (m_oaxKwl->find(OAX_LAT_SIGMA_KW.c_str()))
1077  {
1078  ossimString conv = m_oaxKwl->findKey(OAX_LAT_SIGMA_KW);
1079  if (conv.size())
1080  {
1081  ossim_float64 gndLatSigma = conv.toFloat64();
1082  m_LatLonHgtSigmas[0] = gndLatSigma;
1083  }
1084  }
1085 
1086  if (m_oaxKwl->find(OAX_LON_SIGMA_KW.c_str()))
1087  {
1088  ossimString conv = m_oaxKwl->findKey(OAX_LON_SIGMA_KW);
1089  if (conv.size())
1090  {
1091  ossim_float64 gndLonSigma = conv.toFloat64();
1092  m_LatLonHgtSigmas[1] = gndLonSigma;
1093  }
1094  }
1095 
1096  if (m_oaxKwl->find(OAX_HGT_SIGMA_KW.c_str()))
1097  {
1098  ossimString conv = m_oaxKwl->findKey(OAX_HGT_SIGMA_KW);
1099  if (conv.size())
1100  {
1101  ossim_float64 gndHgtSigma = conv.toFloat64();
1102  m_LatLonHgtSigmas[2] = gndHgtSigma;
1103  }
1104  }
1105 
1106  }
1107 
1108  if (traceDebug())
1109  {
1110  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1111  }
1112 }
1113 
1114 
1115 //*****************************************************************************
1116 // METHOD: ossimAutRegUtil::execute()
1117 //
1118 // Execute registration operation.
1119 //*****************************************************************************
1121 {
1122  static const char MODULE[] = "ossimAutRegUtil::execute";
1123 
1124  if (traceDebug())
1125  {
1126  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1127  }
1128 
1129 
1130  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1131  // Initialize the measurement generator
1132  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1133  *m_rep<<"\n\n >> Tie point collection follows...\n"<<endl;
1134  m_tGen->init(*m_rep);
1135 
1136  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1137  // Configure the measurement generator
1138  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1140 
1141 
1142  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1143  // Load ossimImageSource vector
1144  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1145  std::vector<ossimImageSource*> src;
1146  src.push_back(m_imgLayer[0].get());
1147  src.push_back(m_imgLayer[1].get());
1148 
1149 
1150  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1151  // Set correlation areas
1152  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1153  m_tGen->setImageList(src);
1155 
1156  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1157  // Run the OpenCV detector/extractor/matcher to collect tiepoints
1158  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1159  if (m_tGen->run())
1160  {
1161 
1162  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1163  // Close match window if active
1164  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1165  if (m_showMatchWindow)
1166  {
1167  bool waitKey = true;
1168  m_tGen->closeCvWindow(waitKey);
1169  }
1170 
1171  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1172  // Check for adjustable parameter interface before adjustment
1173  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1176 
1177  if (iface1 && iface2)
1178  {
1179 
1180  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1181  // Create observation set
1182  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1184 
1185  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1186  // Create adjustment executive
1187  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1189 
1190  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1191  // Configure adjustment executive
1192  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1194 
1195  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1196  // Load measurements into the observation set
1197  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1198  if (populateObsSet())
1199  {
1200 
1201  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1202  // Perform adjustment
1203  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1204  bool solutionOK = false;
1205 
1206  *m_rep<<"\n\n >> Adjustment summary follows...\n"<<endl;
1208  {
1209  solutionOK = m_adjExec->runSolution();
1211  if (solutionOK)
1212  {
1213  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1214  // Write updated geometry files
1215  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1216  saveAdjustment();
1217 
1218  if (traceDebug())
1219  {
1220  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << "Solution complete...\n";
1221  }
1222  }
1223  else
1224  {
1225  throw ossimException("m_adjExec->runSolution() failed...");
1226  } //end if m_adjExec->runSolution()
1227  }
1228  else
1229  {
1230  throw ossimException("m_adjExec->initializeSolution() failed...");
1231  } //end if m_adjExec->initializeSolution()
1232 
1233  }
1234  else
1235  {
1236  throw ossimException("populateObsSet() failed...");
1237  } //end if (populateObsSet())
1238 
1239  }
1240  else
1241  {
1242  throw ossimException("ossimAdjustableParameterInterface missing...");
1243  } //end if (iface1 && iface2)
1244 
1245  }
1246  else
1247  {
1248  throw ossimException( "m_tGen->run() failed...");
1249  } //end if (m_tGen->run())
1250 
1251  if (traceDebug())
1252  {
1253  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1254  }
1255 }
1256 
1257 
1259 {
1260  ossimString ts;
1261  ossim::getFormattedTime("ossim-autreg_%a_%m.%d.%y_%H:%M:%S", false, ts);
1262 
1264 
1265  for (int img=0; img<2; ++img)
1266  {
1267  if (!m_controlImage[img])
1268  {
1269  // Get the adjustment info from the bundle adjustment via m_obsSet
1270  ossimFilename filename = m_imgLayer[img]->getImageHandler()->getFilename();
1271 
1272  // Oscar, should this be a ref ptr? drb - 20160810
1273  ossimAdjustableParameterInterface* adjParIface = 0;
1274  for (ossim_uint32 ii=0; ii<m_obsSet->numImages(); ++ii)
1275  {
1276  if (filename == m_obsSet->imageFile(ii))
1278  }
1279 
1280  if ( adjParIface )
1281  {
1282  adjParIface->setAdjustmentDescription(ts);
1283  adjParIface->getAdjustment(*adjInfo);
1284 
1285  // Grab adjustable parameter interface and update it with the adjustment info
1287  if ( iface )
1288  {
1289  iface->setAdjustment(*adjInfo, true);
1290  ossimFilename fn = m_imgLayer[img]->getImageHandler()->createDefaultGeometryFilename();
1291 // TODO ***********
1292 // dirty flag????
1293 // fn += "_test";
1294 // TODO ***********
1295  ossimKeywordlist kwl;
1296  iface->getBaseObject()->saveState(kwl);
1297  kwl.write(fn);
1298  }
1299  }
1300  }
1301  }
1302 
1303  delete adjInfo;
1304 }
1305 
1306 
1308 {
1309  f.string() = m_kwl->findKey( std::string(ossimKeywordNames::OUTPUT_FILE_KW) );
1310 }
1311 
1312 
1314 {
1315  bool result = false;
1316  ossimString ext = file.ext();
1317  ext.downcase();
1318  if ( ext == "src" )
1319  {
1320  result = true;
1321  }
1322  return result;
1323 }
1324 
1325 
1327 {
1328  // Add global usage options.
1330 
1331  // Set app name.
1332  std::string appName = ap.getApplicationName();
1334 
1335  // Add options.
1336  addArguments(ap);
1337 
1338  // Write usage.
1340 
1341  // Keeping single line in tact for examples for cut and paste purposes.
1343  << "NOTES:\n"
1344  << "1) Note 1 content\n"
1345  << " Note 1 place holder continued...\n"
1346  << "2) Note 2 content\n"
1347  << " Note 2 place holder continued...\n"
1348 
1349  << "\nExample commands:\n"
1350 
1351  << "\n// Co-register image1 and image2 with 512x512 ROIs centered on point:\n"
1352  << appName << " --op coreg --img_1 image1.ntf --img_2 image2.ntf --roi-center-llwh 28.097255037664400 -80.630762190246145 512 512\n"
1353 
1354  << "\n// Register image2 to control image1 (master): (TBD... not working)\n"
1355  << appName << " --op masreg -img_m image1.ntf -img_s image2.ntf -cfg configFile.kwl\n"
1356 
1357  << "\n// Above command where all options are in a keyword list:\n"
1358  << appName << " --options autreg-options.kwl\n"
1359  << std::endl;
1360 }
1361 
1362 
1364 {
1365  static const char MODULE[] = "ossimAutRegUtil::initializeSrcKwl";
1366  if ( traceDebug() )
1367  {
1369  << MODULE << " entered...\n";
1370  }
1371 
1372  std::string value = m_kwl->findKey(std::string(SRC_FILE_KW));
1373  if ( value.size() )
1374  {
1375  m_srcKwl = new ossimKeywordlist();
1377  if ( m_srcKwl->addFile( value.c_str() ) == false )
1378  {
1379  m_srcKwl = 0;
1380  }
1381  }
1382  else
1383  {
1384  m_srcKwl = 0;
1385  }
1386 
1387  if ( traceDebug() )
1388  {
1389  if ( m_srcKwl.valid() )
1390  {
1392  << "src keyword list:\n" << *(m_srcKwl.get()) << "\n";
1393  }
1395  << MODULE << " exited...\n";
1396  }
1397 }
1398 
1399 
1401 {
1402  static const char MODULE[] = "ossimAutRegUtil::initializeOcvKwl";
1403  if ( traceDebug() )
1404  {
1406  << MODULE << " entered...\n";
1407  }
1408 
1409  std::string value = m_kwl->findKey(std::string(OCV_CONFIG_FILE_KW));
1410  if ( value.size() )
1411  {
1412  m_ocvKwl = new ossimKeywordlist();
1414  if ( m_ocvKwl->addFile( value.c_str() ) == false )
1415  {
1416  m_ocvKwl = 0;
1417  }
1418  }
1419  else
1420  {
1421  m_ocvKwl = 0;
1422  }
1423 
1424  if ( traceDebug() )
1425  {
1426  if ( m_ocvKwl.valid() )
1427  {
1429  << "ocv keyword list:\n" << *(m_ocvKwl.get()) << "\n";
1430  }
1432  << MODULE << " exited...\n";
1433  }
1434 }
1435 
1436 
1438 {
1439  static const char MODULE[] = "ossimAutRegUtil::initializeOaxKwl";
1440  if ( traceDebug() )
1441  {
1443  << MODULE << " entered...\n";
1444  }
1445 
1446  std::string value = m_kwl->findKey(std::string(OAX_CONFIG_FILE_KW));
1447  if ( value.size() )
1448  {
1449  m_oaxKwl = new ossimKeywordlist();
1451  if ( m_oaxKwl->addFile( value.c_str() ) == false )
1452  {
1453  m_oaxKwl = 0;
1454  }
1455  }
1456  else
1457  {
1458  m_oaxKwl = 0;
1459  }
1460 
1461  if ( traceDebug() )
1462  {
1463  if ( m_oaxKwl.valid() )
1464  {
1466  << "oax keyword list:\n" << *(m_oaxKwl.get()) << "\n";
1467  }
1469  << MODULE << " exited...\n";
1470  }
1471 }
1472 
1473 
1475 {
1476  static const char MODULE[] = "ossimAutRegUtil::addImgSource";
1477 
1478  bool addOK = false;
1479 
1480  if ( traceDebug() )
1481  {
1483  << MODULE << " entered...\nFile: " << file << "\n";
1484  }
1485 
1486  ossimRefPtr<ossimSingleImageChain> ic = createChain(file, entryIndex);
1487  if ( ic.valid() )
1488  {
1489  m_imgLayer.push_back(ic);
1490  addOK = true;
1491  }
1492 
1493  if ( traceDebug() )
1494  {
1495  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exiting...\n";
1496  }
1497 
1498  return addOK;
1499 }
1500 
1501 
1503 {
1504  if ( ih && m_kwl.valid() )
1505  {
1506  ossim_uint32 count = m_kwl->numberOf( READER_PROPERTY_KW.c_str() );
1507  for (ossim_uint32 i = 0; i < count; ++i)
1508  {
1509  ossimString key = READER_PROPERTY_KW;
1510  key += ossimString::toString(i);
1511  ossimString value = m_kwl->findKey( key.string() );
1512  if ( value.size() )
1513  {
1514  std::vector<ossimString> splitArray;
1515  value.split(splitArray, "=");
1516  if(splitArray.size() == 2)
1517  {
1519  new ossimStringProperty(splitArray[0], splitArray[1]);
1520 
1521  ih->setProperty( prop );
1522  }
1523  }
1524  }
1525  }
1526 }
1527 
1528 
1530  ossimRefPtr<ossimSingleImageChain>& chain, ossim_uint32 entryIndex ) const
1531 {
1532  bool result = false;
1533  if ( chain.valid() )
1534  {
1536  if ( ih.valid() )
1537  {
1538  result = ih->setCurrentEntry( entryIndex );
1539  }
1540  }
1541  return result;
1542 }
1543 
1545  ossim_uint32 entryIndex) const
1546 {
1547  static const char MODULE[] = "ossimAutRegUtil::createChain(const ossimFilename&";
1548 
1549  if ( traceDebug() )
1550  {
1552  << MODULE << " entered..."
1553  << "\nfile: " << file
1554  << "\nentry: " << entryIndex
1555  << "\n";
1556  }
1557 
1559 
1560  if ( file.size() )
1561  {
1562  if ( file.exists() )
1563  {
1564  ic = new ossimSingleImageChain;
1565  if ( ic->open( file ) )
1566  {
1567  // Set any reader props:
1568  setReaderProps( ic->getImageHandler().get() );
1569 
1570  // we can't guarantee the state of the image handler at this point so
1571  // let's make sure that the entry is always set to the requested location
1572  // On Cib/Cadrg we were having problems. Removed the compare for entry 0
1573  //
1574  if ( setChainEntry( ic, entryIndex ) == false )
1575  {
1576  std::ostringstream errMsg;
1577  errMsg << MODULE << " ERROR:\nEntry " << entryIndex << " out of range!"
1578  << std::endl;
1579  throw ossimException( errMsg.str() );
1580  }
1581 
1582 
1583  // Always have resampler cache.
1584  ic->setAddResamplerCacheFlag(true);
1585 
1586  //---
1587  // Don't need a chain cache as we're doing a sequential write. So the same tile
1588  // should never be visited more than once.
1589  //---
1590  ic->setAddChainCacheFlag(false);
1591 
1592 
1593  // // Brightness, contrast. Note in same filter.
1594  // if ( hasBrightnesContrastOperation() )
1595  // {
1596  // ic->setBrightnessContrastFlag(true);
1597  // }
1598 
1599  // std::string sharpnessMode = getSharpenMode();
1600  // if ( sharpnessMode.size() )
1601  // {
1602  // ic->setSharpenFlag(true);
1603  // }
1604 
1605  // Create the chain.
1606  ic->createRenderedChain();
1607 
1608 
1609  // // Histogram setup.
1610  // if ( hasHistogramOperation() )
1611  // {
1612  // setupChainHistogram( ic );
1613  // }
1614 
1615  // // Brightness contrast setup:
1616  // if ( hasBrightnesContrastOperation() )
1617  // {
1618  // // Assumption bright contrast filter in chain:
1619 
1620  // ossim_float64 value = getBrightness();
1621  // ic->getBrightnessContrast()->setBrightness( value );
1622 
1623  // value = getContrast();
1624  // ic->getBrightnessContrast()->setContrast( value );
1625  // }
1626 
1627  // // Sharpness:
1628  // if ( sharpnessMode.size() )
1629  // {
1630  // if ( sharpnessMode == "light" )
1631  // {
1632  // ic->getSharpenFilter()->setWidthAndSigma( 3, 0.5 );
1633  // }
1634  // else if ( sharpnessMode == "heavy" )
1635  // {
1636  // ic->getSharpenFilter()->setWidthAndSigma( 5, 1.0 );
1637  // }
1638  // }
1639  }
1640  }
1641  }
1642 
1643  if ( ic.valid() == false )
1644  {
1645  std::string errMsg = "Could not open: ";
1646  errMsg += file.string();
1647  throw ossimException(errMsg);
1648  }
1649 
1650  if ( traceDebug() )
1651  {
1652  ossimKeywordlist kwl;
1653  ic->saveState(kwl, 0);
1654 
1656  << "chain:\n" << kwl << "\n"
1657  << MODULE << " exiting...\n";
1658  }
1659 
1660  return ic;
1661 }
1662 
1663 
1665 {
1666  static const char MODULE[] = "ossimAutRegUtil::createIdentityProjection";
1667 
1668  if ( traceDebug() )
1669  {
1670  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1671  }
1672 
1673  // Get the singe image chain. Should be only one.
1675  if ( m_imgLayer.size() )
1676  {
1677  sic = m_imgLayer[idx];
1678  }
1679 
1680  if ( sic.valid() )
1681  {
1682  // Get the image handler.
1684 
1685  // Resampler:
1687 
1688  if ( ih.valid() )
1689  {
1690  //---
1691  // Get the geometry from the image handler. Since we're in "identity"
1692  // mode use the inputs for the outputs.
1693  //---
1694  m_geom[idx] = ih->getImageGeometry();
1695 
1696  if ( m_geom[idx].valid() )
1697  {
1698  // Get the image projection.
1700  if ( proj.valid() )
1701  {
1702  ossim_float64 rotation = 0.0;
1703 
1704  ossimDrect rect;
1705  m_geom[idx]->getBoundingRect(rect);
1706  ossimDpt midPt = rect.midPoint();
1707 
1708  if ( traceDebug() )
1709  {
1711  << MODULE
1712  << "\nAffine transform parameters:"
1713  << "\nrotation: " << rotation
1714  << "\nmid point: " << midPt << std::endl;
1715  }
1716 
1717  m_ivt[idx] = new ossimImageViewAffineTransform(-rotation,
1718  1.0, 1.0, // image space scale x and y
1719  1.0, 1.0, //scale x and y
1720  0.0, 0.0, // translate x,y
1721  midPt.x, midPt.y); // pivot point
1722 
1723  resampler->setImageViewTransform( m_ivt[idx].get() );
1724  }
1725 
1726  } // Matches: if ( m_geom.valid() )
1727 
1728  } // Matches: if ( ih.valid() )
1729 
1730  } // Matches: if ( sic.valid()
1731 
1732 } // End: createIdentityProjection()
1733 
1734 
1735 bool ossimAutRegUtil::keyIsTrue(ossimRefPtr<ossimKeywordlist> kwl, const std::string& key ) const
1736 {
1737  bool result = false;
1738  if ( kwl.valid() )
1739  {
1740  std::string value = kwl->findKey( key );
1741  if ( value.size() )
1742  {
1743  result = ossimString(value).toBool();
1744  }
1745  }
1746  return result;
1747 }
virtual bool setDescriptorExtractor(const ossimString &name)=0
ossimRefPtr< ossimKeywordlist > m_kwl
Hold all options passed into intialize.
void write(std::ostream &output, const UsageMap &um, unsigned int widthOfOutput=80)
ossimColumnVector3d m_LatLonHgtControlSigmas
std::string getApplicationName() const
return the application name, as specified by argv[0]
void addCommandLineOption(const ossimString &option, const ossimString &explanation)
void setAddResamplerCacheFlag(bool flag)
If flag is true a resampler cache will be added to the chain at create time.
ossimFilename noExtension() const
ossim_uint32 numberOf(const char *str) const
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
void clear()
Disconnects and clears the dem and image layers?????????????.
void getOutputFilename(ossimFilename &f) const
Gets the output file name.
static const char * OUTPUT_FILE_KW
bool addImgSource(const ossimFilename &file, ossim_uint32 entryIndex)
Method to create a chain and add to img layers from file.
void addArguments(ossimArgumentParser &ap)
Adds application arguments to the argument parser.
bool loadImages()
Internal load image pair method.
void setReaderProps(ossimImageHandler *ih) const
Passes reader properties to single image handler if any.
void configureAdjustmentExecutive()
Configures adjustment executive.
Represents serializable keyword/value map.
bool addFile(const char *file)
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
bool isLonNan() const
Definition: ossimGpt.h:140
void configureTieMeasGenerator()
Configures tie measurement generator.
ossimRefPtr< const ossimImageHandler > getImageHandler() const
void setMaxIter(const int maxIter)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
Will save the state of the chain.
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
void addOptions(ossimArgumentParser &parser)
Definition: ossimInit.cpp:100
ossimReferenced allows for shared object ref counting if the reference count ever gets to 0 or less i...
virtual ossimString getEntryString(ossim_int32 entry_number) const
ossimRefPtr< ossimImageViewAffineTransform > m_ivt[2]
Image view transform(IVT).
bool read(const std::string &str)
search for an occurance of a string in the argument list, on sucess remove that occurance from the li...
void getBoundingRect(ossimIrect &bounding_rect) const
Get the bounding rect of (0, 0) to (imageSize.x-1, imageSize.y-1).
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Definition: ossimObject.cpp:95
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual int numMeasurements() const =0
ossimImageGeometry * getImageGeom(const int index)
void addList(const ossimKeywordlist &src, bool overwrite=true)
void makeNan()
Definition: ossimGpt.h:130
void createRenderedChain()
Create a rendered image chain.
static ossimString toString(bool aValue)
Numeric to string methods.
std::vector< ossimRefPtr< ossimSingleImageChain > > m_imgLayer
Array of image source chains.
ossim_uint32 numImages() const
ossimRefPtr< ossimObject > m_tGenObj
virtual bool init(std::ostream &report=std::cout)=0
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
static ossimObjectFactoryRegistry * instance()
void addPair(const std::string &key, const std::string &value, bool overwrite=true)
virtual ossimString getClassName() const
Definition: ossimObject.cpp:64
void setAdjustmentDescription(const ossimString &description)
static ossimElevManager * instance()
METHOD: instance() Implements singelton pattern.
void setCommandLineUsage(const ossimString &explanation)
ossimRefPtr< ossimSingleImageChain > createChain(const ossimFilename &file, ossim_uint32 entryIndex) const
Creates a ossimSingleImageChain from file.
bool populateObsSet()
Internal observation set poplulate method.
ossimApplicationUsage * getApplicationUsage()
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual void imageToView(const ossimDpt &imagePoint, ossimDpt &viewPoint) const
virtual bool write(const char *file, const char *comment=0) const
Methods to dump the ossimKeywordlist to a file on disk.
bool isLatNan() const
Definition: ossimGpt.h:139
void initializeOcvKwl()
Initializes m_ocvKwl if option was set.
void setImageViewTransform(ossimImageViewTransform *transform)
virtual void setShowCvWindow(const bool showCvWindow)=0
bool isHgtNan() const
Definition: ossimGpt.h:143
virtual bool setFeatureDetector(const ossimString &name)=0
Single image chain class.
virtual ossim_uint32 getNumberOfDecimationLevels() const
This returns the total number of decimation levels.
virtual bool setDescriptorMatcher(const ossimString &name)=0
void setAdjustment(const ossimAdjustmentInfo &adj, bool notify=false)
ossim_int32 toInt32() const
void reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity=OSSIM_BENIGN)
for each remaining option report it as an unrecongnized.
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual ossimAdjustableParameterInterface * getAdjustableParameterInterface()
~ossimAutRegUtil()
virtual destructor
static ossimScalarTypeLut * instance()
Returns the static instance of an ossimScalarTypeLut object.
bool initializeSolution(ossimObservationSet &obsSet)
initialize adjustment solution
std::ostream * m_rep
Report stream pointer.
bool errors(ossimErrorSeverity severity=OSSIM_BENIGN) const
bool exists() const
ossim_float64 lon
Definition: ossimGpt.h:266
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
virtual const ossimFilename & getFilename() const
Returns the filename.
bool localToWorld(const ossimDpt &local_pt, ossimGpt &world_pt) const
Exposes the 3D projection from image to world coordinates.
OSSIM_DLL void getFormattedTime(const std::string &format, bool gmtFlag, std::string &result)
Gets the current time.
std::string::size_type size() const
Definition: ossimString.h:405
virtual double getHeightAboveEllipsoid(const ossimGpt &gpt)
ossimRefPtr< ossimKeywordlist > m_oaxKwl
Hold contents of oax config file if –oax_config_file is used.
bool toBool() const
String to numeric methods.
virtual void closeCvWindow(const bool waitKeyPress=false)=0
unsigned int ossim_uint32
ossimDpt getMetersPerPixel() const
Returns the GSD associated with this image in the active projection.
double height() const
Definition: ossimGpt.h:107
ossim_float64 toFloat64() const
void execute()
Execute method.
void setApplicationName(const ossimString &name)
void createIdentityProjection(int idx)
Sets the single image chain for identity operations view to an ossimImageViewAffineTransform.
void usage(ossimArgumentParser &ap)
Initializes arg parser and outputs usage.
ossimObject * createObject(const ossimString &objectType)
Definition: kwl.cpp:64
ossimRefPtr< ossimKeywordlist > m_srcKwl
Hold contents of src file if –src is used.
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
ossimRefPtr< ossimKeywordlist > m_ocvKwl
Hold contents of OpenCV config file if –ocv_config_file is used.
bool keyIsTrue(ossimRefPtr< ossimKeywordlist > kwl, const std::string &key) const
ossim_uint32 width() const
Definition: ossimIrect.h:500
bool hasNans() const
Definition: ossimDpt.h:67
ossimTieMeasurementGeneratorInterface * m_tGen
Tie point generator interface.
void setConvCriteria(const int convCriteria)
void setGroundSigmas(const double &latSig, const double &lonSig, const double &hgtSig)
std::vector< ossimIrect > m_roiRects
Correlation ROIs.
ossimAutRegOperation m_operation
Enumerated operation to perform.
bool runSolution()
run adjustment solution
ossimRefPtr< ossimAdjustmentExecutive > m_adjExec
Adjustment executive interface.
bool delineateROIs()
Internal correlation region determination.
void initializeOaxKwl()
Initializes m_oaxKwl if option was set.
void summarizeSolution() const
summarize solution
const ossimProjection * getProjection() const
Access methods for projection (may be NULL pointer).
virtual void setUseGrid(const bool useGrid)=0
void addMeasurement(const ossimDpt &meas, const ossimFilename &imgFile, const ossimDpt &measSigma=ossimDpt(1.0, 1.0))
void saveAdjustment()
saveAdjustment method
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
Used to convert from scalar type enumeration to strings and vice versa.
This class defines an abstract Handler which all image handlers(loaders) should derive from...
bool m_showMatchWindow
OpenCV match window display flag.
bool setChainEntry(ossimRefPtr< ossimSingleImageChain > &chain, ossim_uint32 entryIndex) const
Sets entry for a chain.
ossimDpt midPoint() const
Definition: ossimDrect.h:817
#define max(a, b)
Definition: auxiliary.h:76
ossim_int32 y
Definition: ossimIpt.h:142
void setDescription(const ossimString &desc)
void makeNan()
Definition: ossimIrect.h:329
void initialize()
Internal initialize method.
virtual ossimDpt pointIndexedAt(const ossim_uint32 imgIdx, const ossim_uint32 measIdx)=0
virtual bool setImageList(std::vector< ossimImageSource *> src)=0
void initializeSrcKwl()
Initializes m_srcKwl if option was set.
double x
Definition: ossimDpt.h:164
bool open(const ossimFilename &file, bool openOverview=true)
open method that takes an image file.
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
ossimFilename imageFile(const int index) const
virtual ossimObject * getBaseObject()=0
static ossimInit * instance()
Definition: ossimInit.cpp:89
ossimString ext() const
bool worldToLocal(const ossimGpt &world_pt, ossimDpt &local_pt) const
Exposes the 3D world-to-local image coordinate reverse projection.
unsigned int numMeas() const
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
ossim_int32 x
Definition: ossimIpt.h:141
ossim_float64 lat
Definition: ossimGpt.h:265
bool addObservation(ossimRefPtr< ossimPointObservation > obs)
operations
void getAdjustment(ossimAdjustmentInfo &adj) const
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
ossimRefPtr< const ossimImageRenderer > getImageRenderer() const
ossimAutRegUtil()
default constructor
virtual bool setMaxMatches(const int &maxMatches)=0
ossimAutRegUtil class.
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
virtual bool setCurrentEntry(ossim_uint32 entryIdx)
ossimRefPtr< ossimImageGeometry > m_geom[2]
The image geometry.
static const char * QUALITY_KW
const ossimAutRegUtil & operator=(const ossimAutRegUtil &rhs)
Hidden from use assignment operator.
virtual bool setROIs(std::vector< ossimIrect > roi)=0
bool isSrcFile(const ossimFilename &file) const
int & argc()
return the argument count.
void setExpandEnvVarsFlag(bool flag)
ossimColumnVector3d m_LatLonHgtSigmas
A priori tie point sigmas.
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
ossimRefPtr< ossimObservationSet > m_obsSet
Observation set.
int ossim_int32
void writeErrorMessages(std::ostream &output, ossimErrorSeverity sevrity=OSSIM_BENIGN)
write out error messages at an above specified .
const std::string & string() const
Definition: ossimString.h:414
bool m_controlImage[2]
Control image flags.
void setAddChainCacheFlag(bool flag)
If flag is true a chain cache will be added to the chain at create time.