EstimateRPCSensorModelExample.cxx 4.93 KB
 Sébastien Dinot committed Mar 08, 2017 1 /*  Julien Michel committed Jan 14, 2019 2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)  Sébastien Dinot committed Mar 08, 2017 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */  Manuel Grizonnet committed Jan 12, 2010 20 21 22 23 24 25 26 27 28  // \index{otb::GCPsToRPCSensorModelImageFilter} // \index{otb::GCPsToRPCSensorModelImageFilter!header} // // // The following example illustrates the application of estimation // of a sensor model to an image (limited to a RPC sensor model for now).  Julien Malik committed Jul 08, 2010 29 // The \doxygen{otb}{GCPsToRPCSensorModelImageFilter} estimates a RPC  OTB Bot committed Apr 01, 2010 30 31 // sensor model from a list of user defined GCPs. Internally, it uses // an ossimRpcSolver, which performs the estimation using the well  Manuel Grizonnet committed Jan 12, 2010 32 33 34 35 36 // known least-square method. // Let's look at the minimal code required to use this // algorithm. First, the following header defining the // \doxygen{otb}{GCPsToRPCSensorModelImageFilter} class must be  OTB Bot committed Apr 01, 2010 37 // included.  Manuel Grizonnet committed Jan 12, 2010 38   Emmanuel Christophe committed Apr 23, 2011 39 #include  Manuel Grizonnet committed Jan 12, 2010 40 41 42 43 #include "otbImage.h" #include "otbImageFileReader.h" #include "otbGCPsToRPCSensorModelImageFilter.h"  OTB Bot committed Apr 01, 2010 44 int main(int argc, char* argv[])  Manuel Grizonnet committed Jan 12, 2010 45 {  OTB Bot committed Apr 01, 2010 46  if (argc < 3)  Victor Poughon committed Feb 20, 2019 47 48  { std::cerr << "Usage: " << argv[0] << " infname outfname a1x a1y b1x b1y b1z ... aNx aNy bNx bNy bNz" << std::endl;  Manuel Grizonnet committed Jan 12, 2010 49  return EXIT_FAILURE;  Victor Poughon committed Feb 20, 2019 50  }  OTB Bot committed Apr 01, 2010 51  else if ((argc - 3) % 5 != 0)  Victor Poughon committed Feb 20, 2019 52  {  OTB Bot committed Apr 01, 2010 53  std::cerr << "Inconsistent GCPs description!" << std::endl;  Manuel Grizonnet committed Jan 12, 2010 54  return EXIT_FAILURE;  Victor Poughon committed Feb 20, 2019 55  }  Manuel Grizonnet committed Jan 12, 2010 56   Victor Poughon committed Feb 20, 2019 57 58  const char* infname = argv[1]; const char* outfname = argv[2];  Manuel Grizonnet committed Jan 12, 2010 59 60 61 62  // We declare the image type based on a particular pixel type and // dimension. In this case the \code{float} type is used for the pixels.  Victor Poughon committed May 16, 2019 63 64  using ImageType = otb::Image; using ReaderType = otb::ImageFileReader;  OTB Bot committed Apr 01, 2010 65   Victor Poughon committed May 16, 2019 66  using GCPsToSensorModelFilterType = otb::GCPsToRPCSensorModelImageFilter;  OTB Bot committed Apr 01, 2010 67   Victor Poughon committed May 16, 2019 68 69  using Point2DType = GCPsToSensorModelFilterType::Point2DType; using Point3DType = GCPsToSensorModelFilterType::Point3DType;  Manuel Grizonnet committed Jan 12, 2010 70 71 72 73 74 75 76  // We instantiate reader and writer types ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(infname); // The \doxygen{otb}{GCPsToRPCSensorModelImageFilter} is instantiated.  Victor Poughon committed Feb 20, 2019 77  GCPsToSensorModelFilterType::Pointer rpcEstimator = GCPsToSensorModelFilterType::New();  Manuel Grizonnet committed Jan 12, 2010 78  rpcEstimator->SetInput(reader->GetOutput());  OTB Bot committed Apr 01, 2010 79   Manuel Grizonnet committed Jan 12, 2010 80  // We retrieve the command line parameters and put them in the  OTB Bot committed Apr 01, 2010 81  // correct variables. Firstly, We determine the number of GCPs  Manuel Grizonnet committed Jan 12, 2010 82 83 84  // set from the command line parameters and they are stored in: // \begin{itemize} // \item \doxygen{otb}{Point3DType} : Store the sensor point (3D ground point)  Manuel Grizonnet committed Sep 15, 2016 85  // \item \doxygen{otb}{Point2DType} : Pixel associated in the image (2D physical coordinates)  Manuel Grizonnet committed Jan 12, 2010 86 87 88 89 90 91  // Here we do not use DEM or MeanElevation. It is also possible to give a 2D // ground point and use the DEM or MeanElevation to get // the corresponding elevation. // \end{itemize}  OTB Bot committed Apr 01, 2010 92 93 94 95 96  unsigned int nbGCPs = (argc - 3) / 5; std::cout << "Receiving " << nbGCPs << " from command line." << std::endl; for (unsigned int gcpId = 0; gcpId < nbGCPs; ++gcpId)  Victor Poughon committed Feb 20, 2019 97  {  Manuel Grizonnet committed Jan 12, 2010 98  Point2DType sensorPoint;  OTB Bot committed Apr 01, 2010 99 100  sensorPoint[0] = atof(argv[3 + gcpId * 5]); sensorPoint[1] = atof(argv[4 + gcpId * 5]);  Manuel Grizonnet committed Jan 12, 2010 101 102  Point3DType geoPoint;  OTB Bot committed Apr 01, 2010 103 104 105 106  geoPoint[0] = atof(argv[5 + 5 * gcpId]); geoPoint[1] = atof(argv[6 + 5 * gcpId]); geoPoint[2] = atof(argv[7 + 5 * gcpId]);  Victor Poughon committed Feb 20, 2019 107  std::cout << "Adding GCP sensor: " << sensorPoint << " <-> geo: " << geoPoint << std::endl;  Manuel Grizonnet committed Jan 12, 2010 108   OTB Bot committed Apr 01, 2010 109  rpcEstimator->AddGCP(sensorPoint, geoPoint);  Victor Poughon committed Feb 20, 2019 110  }  Manuel Grizonnet committed Jan 12, 2010 111   OTB Bot committed Apr 01, 2010 112  // Note that the \doxygen{otb}{GCPsToRPCSensorModelImageFilter} needs  Guillaume Pasero committed Aug 26, 2014 113  // at least 20 GCPs to estimate a proper RPC sensor model,  OTB Bot committed Apr 01, 2010 114  // although no warning will be reported to the user if  Guillaume Pasero committed Aug 26, 2014 115  // the number of GCPs is lower than 20.  Manuel Grizonnet committed Jan 12, 2010 116  // Actual estimation of the sensor model takes place in the  OTB Bot committed Apr 01, 2010 117  // \code{GenerateOutputInformation()} method.  Manuel Grizonnet committed Jan 12, 2010 118 119  rpcEstimator->GetOutput()->UpdateOutputInformation();  OTB Bot committed Apr 01, 2010 120 121 122 123  // The result of the RPC model estimation and the residual ground // error is then save in a txt file. Note that This filter does // not modify the image buffer, but only the metadata.  Manuel Grizonnet committed Jan 12, 2010 124 125 126 127 128  std::ofstream ofs; ofs.open(outfname); // Set floatfield to format properly  Emmanuel Christophe committed Apr 23, 2011 129  ofs.setf(std::ios::fixed, std::ios::floatfield);  Manuel Grizonnet committed Jan 12, 2010 130 131  ofs.precision(10);  Victor Poughon committed Feb 20, 2019 132 133  ofs << (ImageType::Pointer)rpcEstimator->GetOutput() << std::endl; ofs << "Residual ground error: " << rpcEstimator->GetRMSGroundError() << std::endl;  Manuel Grizonnet committed Jan 12, 2010 134 135  ofs.close();  Manuel Grizonnet committed Jan 12, 2010 136 137  // The output image can be now given to the \doxygen{otb}{orthorectificationFilter}. // Note that this filter allows also to import GCPs from the image  OTB Bot committed Apr 01, 2010 138  // metadata, if any.  Manuel Grizonnet committed Jan 12, 2010 139 140 141  return EXIT_SUCCESS; }