diff --git a/examples/other/maptk_undistort_frames.conf b/examples/other/maptk_undistort_frames.conf new file mode 100644 index 000000000..998974a19 --- /dev/null +++ b/examples/other/maptk_undistort_frames.conf @@ -0,0 +1,9 @@ + +# Path to the input image list file. +image_list_file = framelist.txt + +# A directory containing the input KRTD files. +input_krtd_dir = output/krtd + +# A directory in which to write the output undistorted frames. +output_dir = undistorted_frames diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index e068de75a..54df2b87b 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -63,6 +63,7 @@ set(gui_moc_headers tools/BundleAdjustTool.h tools/CanonicalTransformTool.h tools/NeckerReversalTool.h + tools/UndistortFramesTool.h ) set(gui_sources @@ -90,6 +91,7 @@ set(gui_sources tools/BundleAdjustTool.cxx tools/CanonicalTransformTool.cxx tools/NeckerReversalTool.cxx + tools/UndistortFramesTool.cxx ) maptk_use_appdata( diff --git a/gui/MainWindow.cxx b/gui/MainWindow.cxx index 8affaa60b..3289ceae5 100644 --- a/gui/MainWindow.cxx +++ b/gui/MainWindow.cxx @@ -36,6 +36,7 @@ #include "tools/BundleAdjustTool.h" #include "tools/CanonicalTransformTool.h" #include "tools/NeckerReversalTool.h" +#include "tools/UndistortFramesTool.h" #include "AboutDialog.h" #include "MatchMatrixWindow.h" @@ -238,6 +239,8 @@ class MainWindowPrivate kwiver::vital::camera_map_sptr cameraMap() const; void updateCameras(kwiver::vital::camera_map_sptr const&); + QMap* frameMap() const; + void setActiveCamera(int); void updateCameraView(); @@ -391,6 +394,23 @@ kwiver::vital::camera_map_sptr MainWindowPrivate::cameraMap() const return std::make_shared(map); } +//----------------------------------------------------------------------------- +QMap *MainWindowPrivate::frameMap() const +{ + auto map = new QMap(); + + foreach (auto i, qtIndexRange(this->cameras.count())) + { + auto const& cd = this->cameras[i]; + if (!cd.imagePath.isEmpty()) + { + map->insert(static_cast(i), cd.imagePath); + } + } + + return map; +} + //----------------------------------------------------------------------------- void MainWindowPrivate::updateCameras( kwiver::vital::camera_map_sptr const& cameras) @@ -590,6 +610,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags) d->addTool(new BundleAdjustTool(this), this); d->addTool(new CanonicalTransformTool(this), this); d->addTool(new NeckerReversalTool(this), this); + d->addTool(new UndistortFramesTool(this), this); d->UI.menuView->addSeparator(); d->UI.menuView->addAction(d->UI.cameraViewDock->toggleViewAction()); @@ -1092,6 +1113,19 @@ void MainWindow::executeTool(QObject* object) tool->setCameras(d->cameraMap()); tool->setLandmarks(d->landmarks); + if (tool->inherits("UndistortFramesTool")) { + + QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), + "./", + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + UndistortFramesTool * t = qobject_cast(tool); + + t->setOutputDir(dir); + t->setFrames(d->frameMap()); + } + if (!tool->execute()) { d->setActiveTool(0); diff --git a/gui/tools/UndistortFramesTool.cxx b/gui/tools/UndistortFramesTool.cxx new file mode 100644 index 000000000..ad87a7964 --- /dev/null +++ b/gui/tools/UndistortFramesTool.cxx @@ -0,0 +1,141 @@ +/*ckwg +29 + * Copyright 2016 by Kitware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name Kitware, Inc. nor the names of any contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "UndistortFramesTool.h" + +#include "maptk/undistort_frame.h" + +#include + +//----------------------------------------------------------------------------- +class UndistortFramesToolPrivate +{ +public: + QMap frames; + QString dir; + +}; + +QTE_IMPLEMENT_D_FUNC(UndistortFramesTool) + +//----------------------------------------------------------------------------- +UndistortFramesTool::UndistortFramesTool(QObject* parent) + : AbstractTool(parent), d_ptr(new UndistortFramesToolPrivate) +{ + this->setText("&Undistort Frames"); + this->setToolTip( + "Undistort frames."); +} + +//----------------------------------------------------------------------------- +UndistortFramesTool::~UndistortFramesTool() +{ +} + +//----------------------------------------------------------------------------- +AbstractTool::Outputs UndistortFramesTool::outputs() const +{ + return Cameras | Landmarks; +} + +//----------------------------------------------------------------------------- +void UndistortFramesTool::setFrames(QMap * + const& newFrames) +{ + if (newFrames) + { + auto copiedFrames = QMap(); + + QMap::const_iterator i = + newFrames->constBegin(); + + while (i != newFrames->constEnd()) { + copiedFrames.insert(i.key(), i.value()); + ++i; + } + + this->updateFrames(copiedFrames); + } + else + { + this->updateFrames(QMap()); + } +} + +void UndistortFramesTool::setOutputDir(const QString &dir) +{ + QTE_D(); + + d->dir = dir; +} + +//----------------------------------------------------------------------------- +void UndistortFramesTool::updateFrames(QMap + const& newFrames) +{ + QTE_D(); + d->frames = newFrames; +} + +//----------------------------------------------------------------------------- +QMap UndistortFramesTool::frames() +{ + QTE_D(); + + return d->frames; +} + +//----------------------------------------------------------------------------- +bool UndistortFramesTool::execute(QWidget* window) +{ + return AbstractTool::execute(window); +} + +//----------------------------------------------------------------------------- +void UndistortFramesTool::run() +{ + QTE_D(); + + auto cp = this->cameras(); + auto frames = this->frames(); + + int nbCams = cp.get()->cameras().size(); + + std::vector frameList; + std::vector cameras; + + for (int i = 0; i < nbCams; ++i) + { + frameList.push_back(frames[i].toStdString()); + cameras.push_back(cp.get()->cameras().at(i)); + } + + kwiver::maptk::undistortFrames(frameList,cameras,d->dir.toStdString()); +} diff --git a/gui/tools/UndistortFramesTool.h b/gui/tools/UndistortFramesTool.h new file mode 100644 index 000000000..339c10986 --- /dev/null +++ b/gui/tools/UndistortFramesTool.h @@ -0,0 +1,68 @@ +/*ckwg +29 + * Copyright 2016 by Kitware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name Kitware, Inc. nor the names of any contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MAPTK_UNDISTORTFRAMESTOOL_H_ +#define MAPTK_UNDISTORTFRAMESTOOL_H_ + +#include "AbstractTool.h" + +class UndistortFramesToolPrivate; + +class UndistortFramesTool : public AbstractTool +{ + Q_OBJECT + +public: + explicit UndistortFramesTool(QObject* parent = 0); + virtual ~UndistortFramesTool(); + + virtual Outputs outputs() const QTE_OVERRIDE; + + virtual bool execute(QWidget* window = 0) QTE_OVERRIDE; + + void setFrames(QMap * const &newFrames); + + void setOutputDir(QString const &dir); + + void updateFrames(QMap const &newFrames); + + QMap frames(); + + +protected: + virtual void run() QTE_OVERRIDE; + +private: + QTE_DECLARE_PRIVATE_RPTR(UndistortFramesTool) + QTE_DECLARE_PRIVATE(UndistortFramesTool) + QTE_DISABLE_COPY(UndistortFramesTool) +}; + +#endif diff --git a/maptk/CMakeLists.txt b/maptk/CMakeLists.txt index 48e35e2ae..90f9d45ce 100644 --- a/maptk/CMakeLists.txt +++ b/maptk/CMakeLists.txt @@ -3,6 +3,9 @@ include(CheckCXXCompilerFlag) include_directories("${MAPTK_SOURCE_DIR}") include_directories("${MAPTK_BINARY_DIR}") +find_package(VTK 6.2 REQUIRED) +include(${VTK_USE_FILE}) + ### # Setting up main library @@ -19,6 +22,7 @@ set(maptk_public_headers match_matrix.h triangulate.h transform.h + undistort_frame.h plugin_interface/algorithm_plugin_interface.h plugin_interface/algorithm_plugin_interface_macros.h @@ -38,6 +42,7 @@ set(maptk_sources projected_track_set.cxx transform.cxx triangulate.cxx + undistort_frame.cxx ) kwiver_configure_file( version.h @@ -69,6 +74,9 @@ kwiver_add_library( target_link_libraries( maptk PUBLIC vital kwiversys + vtkCommonCore + vtksys + vtkIOImage ) diff --git a/maptk/undistort_frame.cxx b/maptk/undistort_frame.cxx new file mode 100644 index 000000000..a4f7eb4e1 --- /dev/null +++ b/maptk/undistort_frame.cxx @@ -0,0 +1,167 @@ +/*ckwg +29 + * Copyright 2016 by Kitware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither name of Kitware, Inc. nor the names of any contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * \brief projected_track_set implementation + */ + +#include "undistort_frame.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +namespace kwiver { +namespace maptk { + +using namespace kwiver::vital; + +vtkSmartPointer undistortFrame(std::string const framePath, + camera *cam) +{ + //Read the frame into an imageData + + auto const reader = vtkImageReader2Factory::CreateImageReader2(framePath.c_str()); + + reader->SetFileName(framePath.c_str()); + reader->Update(); + + auto const originalFrame = reader->GetOutput(); + + //Create an empty imageData + + vtkSmartPointer undistortedFrame = vtkSmartPointer::New(); + + undistortedFrame->SetSpacing(originalFrame->GetSpacing()); + undistortedFrame->SetOrigin(originalFrame->GetOrigin()); + undistortedFrame->SetDimensions(originalFrame->GetDimensions()); + + //Create an empty array for the undistorted values + + vtkNew undistortedValues; + + undistortedValues->SetName("Undistorted Values"); + undistortedValues->SetNumberOfComponents(3); + undistortedValues->SetNumberOfTuples(originalFrame->GetPointData()-> + GetScalars()->GetNumberOfTuples()); + + //Get old image as array + + vtkDataArray* scalars = originalFrame->GetPointData()->GetScalars(); + + double originalPixel[3], undistortedCoord[3]; + vtkIdType undistortedPixelId; + + //Create a perfect (i.e. with no distortion) camera for mapping + + simple_camera* perfectCam = new simple_camera(*cam); + + simple_camera_intrinsics* perfectIntrinsics = + new simple_camera_intrinsics(*cam->intrinsics()); + + Eigen::VectorXd noDist(1); + noDist(0) = 0; + + perfectIntrinsics->set_dist_coeffs(noDist); + + camera_intrinsics_sptr perfectIntSptr(perfectIntrinsics); + + perfectCam->set_intrinsics(perfectIntSptr); + + vector_2d normalizedCoord, newCoord; + + //Undistort each point and save it in the new array + + for (vtkIdType idPixel = 0; idPixel < originalFrame->GetNumberOfPoints(); ++idPixel) + { + originalFrame->GetPoint(idPixel,originalPixel); + + normalizedCoord = cam->intrinsics()->unmap(vector_2d(originalPixel[0], + originalPixel[1])); + + newCoord = perfectCam->intrinsics()->map(normalizedCoord); + + undistortedCoord[0] = newCoord[0]; + undistortedCoord[1] = newCoord[1]; + undistortedCoord[2] = originalPixel[2]; + + //Get id of undistorted pixel in original frame + + undistortedPixelId = originalFrame->FindPoint(undistortedCoord); + + undistortedValues->SetTuple(idPixel, + scalars->GetTuple(undistortedPixelId)); + } + + undistortedFrame->GetPointData()->SetScalars(undistortedValues.Get()); + + return undistortedFrame.GetPointer(); +} + +void undistortFrames(const std::vector framePathList, + const std::vector camList, + const std::string outputDir) +{ + vtkNew imageWriter; + vtkSmartPointer undistortedFrame; + + for (int i = 0; i < framePathList.size(); ++i) + { + + std::string originalFramePath = framePathList[i]; + auto const& camera = camList[i]; + + std::string filename = kwiversys::SystemTools::ConvertToOutputPath(outputDir + + "/" + + kwiversys::SystemTools::GetFilenameName(originalFramePath)); + + std::cerr << "Undistorting " << filename.c_str() << "... "; + + undistortedFrame = undistortFrame(originalFramePath, camera.get()); + + imageWriter->SetInputData(undistortedFrame); + imageWriter->SetFileName(filename.c_str()); + + std::cerr << "Done." << std::endl; + + imageWriter->Write(); + } +} + +} // end namespace maptk +} // end namespace kwiver diff --git a/maptk/undistort_frame.h b/maptk/undistort_frame.h new file mode 100644 index 000000000..656da0efd --- /dev/null +++ b/maptk/undistort_frame.h @@ -0,0 +1,41 @@ +#ifndef UNDISTORT_FRAME_H +#define UNDISTORT_FRAME_H + +#endif // UNDISTORT_FRAME_H + +#include + +#include + +template class vtkSmartPointer; +class vtkImageData; + +namespace kwiver { +namespace maptk { + + +/// Undistort the input frame using the distortion coeffiscients from the input camera +/** + * \param framePath path to the input distorted frame + * \param cam input camera for undistortion + * \return undistorted frame + */ + +MAPTK_EXPORT +vtkSmartPointer +undistortFrame(const std::string framePath, vital::camera_sptr cam); + + +/// Undistort the input frames using the distortion coeffiscients from the input cameras +/** + * \param framePathList input vector containing the paths to the distorted frames + * \param camList input vector contianing the cameras for undistortion + * \param outputDir path to the output undistorted frames directory + */ +MAPTK_EXPORT +void undistortFrames(const std::vector framePathList, + const std::vector camList, + const std::string outputDir); + +} // end namespace maptk +} // end namespace kwiver diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index cc8f8b879..3aa1a0da5 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -34,3 +34,8 @@ kwiver_add_executable(maptk_estimate_homography estimate_homography.cxx) target_link_libraries(maptk_estimate_homography PRIVATE maptk vital_apm kwiversys ) + +kwiver_add_executable(maptk_undistort_frames undistort_frames.cxx) +target_link_libraries(maptk_undistort_frames + PRIVATE maptk vital_apm kwiversys + ) diff --git a/tools/undistort_frames.cxx b/tools/undistort_frames.cxx new file mode 100644 index 000000000..674a167ef --- /dev/null +++ b/tools/undistort_frames.cxx @@ -0,0 +1,279 @@ +/*ckwg +29 + * Copyright 2016 by Kitware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither name of Kitware, Inc. nor the names of any contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * \brief Create undistorted frames from frames and KRTD files + */ + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +typedef kwiversys::SystemTools ST; +typedef kwiversys::CommandLineArguments argT; + +// ------------------------------------------------------------------ +// return a default configuration object +kwiver::vital::config_block_sptr +default_config() +{ + kwiver::vital::config_block_sptr config = kwiver::vital::config_block::empty_config(); + + // general options + config->set_value("image_list_file", "", + "Path to the input image list file."); + + config->set_value("input_krtd_dir", "", + "A directory containing the input KRTD files."); + + config->set_value("output_dir", "undistorted_frames", + "A directory in which to write the output undistorted frames."); + + return config; +} + + +// ------------------------------------------------------------------ +/// Check configuration options +bool +check_config(kwiver::vital::config_block_sptr config) +{ + bool config_valid = true; + +#define MAPTK_CHECK_FAIL(msg) \ + std::cerr << "Config Check Fail: " << msg << std::endl; \ + config_valid = false + + kwiver::vital::path_t input_frames, input_krtd, output_dir; + + if(config->has_value("image_list_file")) + { + input_frames = + config->get_value("image_list_file"); + } + + if(config->has_value("input_krtd_dir")) + { + input_krtd = + config->get_value("input_krtd_dir"); + } + + if(config->has_value("output_dir")) + { + output_dir = + config->get_value("output_dir"); + } + + if (input_frames == "") + { + MAPTK_CHECK_FAIL("Not given an input frame list file."); + } + else if ( ! ST::FileExists(input_frames)) + { + MAPTK_CHECK_FAIL("Path given for image_list_file doesn't exist."); + } + + if (input_krtd == "") + { + MAPTK_CHECK_FAIL("Not given an input KRTD files directory."); + } + else if ( ! ST::FileExists(input_krtd)) + { + MAPTK_CHECK_FAIL("Path given for input_krtd_dir doesn't exist."); + } + + if (output_dir == "") + { + MAPTK_CHECK_FAIL("Not given an output directory."); + } + else if (! ST::FileExists(output_dir)) + { + ST::MakeDirectory(output_dir); + } + // When we have a valid input path... + else if (config_valid) + { + if ( ST::FileExists(input_frames) && ST::FileIsDirectory(input_frames)) + { + MAPTK_CHECK_FAIL("image_list_file is a directory."); + } + else if (ST::FileExists(input_krtd) && !ST::FileIsDirectory(input_krtd)) + { + MAPTK_CHECK_FAIL("input_krtd_dir is not a directory."); + } + } + +#undef MAPTK_CHECK_FAIL + + return config_valid; +} + +// ------------------------------------------------------------------ +static int maptk_main(int argc, char const* argv[]) +{ + static bool opt_help(false); + static std::string opt_config; + static std::string opt_out_config; + + kwiversys::CommandLineArguments arg; + + arg.Initialize( argc, argv ); + typedef kwiversys::CommandLineArguments argT; + + arg.AddArgument( "--help", argT::NO_ARGUMENT, &opt_help, "Display usage information" ); + arg.AddArgument( "--config", argT::SPACE_ARGUMENT, &opt_config, "Configuration file for tool" ); + arg.AddArgument( "-c", argT::SPACE_ARGUMENT, &opt_config, "Configuration file for tool" ); + arg.AddArgument( "--output-config", argT::SPACE_ARGUMENT, &opt_out_config, + "Output a configuration. This may be seeded with a configuration file from -c/--config." ); + arg.AddArgument( "-o", argT::SPACE_ARGUMENT, &opt_out_config, + "Output a configuration. This may be seeded with a configuration file from -c/--config." ); + + if ( ! arg.Parse() ) + { + std::cerr << "Problem parsing arguments" << std::endl; + return EXIT_FAILURE; + } + + if ( opt_help ) + { + std::cout + << "USAGE: " << argv[0] << " [OPTS]\n\n" + << "Take a framelist and a krtd directory and return undistorted frames into specified output directory." + << std::endl + << "Options:" + << arg.GetHelp() << std::endl; + return EXIT_SUCCESS; + } + + // + // Initialize from configuration + // + kwiver::vital::config_block_sptr config = default_config(); + + if ( ! opt_config.empty()) + { + const std::string prefix = kwiver::vital::get_executable_path() + "/.."; + config->merge_config(kwiver::vital::read_config_file(opt_config, "maptk", + MAPTK_VERSION, prefix)); + } + + bool config_is_valid = check_config(config); + + if ( ! opt_out_config.empty() ) + { + kwiver::vital::path_t output_path = opt_out_config; + kwiver::vital::write_config_file(config, output_path); + + if (config_is_valid) + { + std::cerr << "INFO: Configuration valid for running." << std::endl; + } + else + { + std::cerr << "WARNING: Configuration needs revision." << std::endl; + } + return EXIT_SUCCESS; + } + else if (!config_is_valid) + { + std::cerr << "ERROR: Configuration invalid." << std::endl; + return EXIT_FAILURE; + } + + std::string image_list_file = config->get_value("image_list_file"); + std::string input_krtd_dir = config->get_value("input_krtd_dir"); + std::string output_dir= config->get_value("output_dir"); + + std::ifstream image_list_ifs(image_list_file.c_str()); + if (!image_list_ifs) + { + std::cerr << "Error: Could not open image list file!" << std::endl; + return EXIT_FAILURE; + } + + std::cerr << "Loading frames and cameras..." ; + + std::vector image_files; + std::vector cameras; + kwiver::vital::path_t krtd_file; + + for (std::string line; std::getline(image_list_ifs, line); ) + { + krtd_file = ST::ConvertToOutputPath(input_krtd_dir + "/" + + ST::GetFilenameWithoutLastExtension(line) + + ".krtd"); + + auto const& camera = kwiver::vital::read_krtd_file(krtd_file); + + image_files.push_back(line); + cameras.push_back(camera); + } + + std::cerr << " Done." << std::endl; + + kwiver::maptk::undistortFrames(image_files,cameras,output_dir); + + std::cerr << " Done." << std::endl; + + return EXIT_SUCCESS; +} + +// ------------------------------------------------------------------ +int main(int argc, char const* argv[]) +{ + try + { + return maptk_main(argc, argv); + } + catch (std::exception const& e) + { + std::cerr << "Exception caught: " << e.what() << std::endl; + + return EXIT_FAILURE; + } + catch (...) + { + std::cerr << "Unknown exception caught" << std::endl; + + return EXIT_FAILURE; + } +}