53#include <hugin_config.h>
63#define TRACE_IMG(X) {if (_panoDetector.getVerbose() == 1) {TRACE_INFO("i" << _imgData._number << " : " << X << std::endl);}}
64#define TRACE_PAIR(X) {if (_panoDetector.getVerbose() == 1){ TRACE_INFO("i" << _matchData._i1->_number << " <> " \
65 "i" << _matchData._i2->_number << " : " << X << std::endl);}}
102 _writeAllKeyPoints(
false), _verbose(1),
103 _sieve1Width(10), _sieve1Height(10), _sieve1Size(100),
104 _kdTreeSearchSteps(200), _kdTreeSecondDistance(0.25),
105 _minimumMatches(6), _ransacMode(
HuginBase::RANSACOptimizer::AUTO), _ransacIters(1000), _ransacDistanceThres(50),
106 _sieve2Width(5), _sieve2Height(5), _sieve2Size(1),
107 _matchingStrategy(MULTIROW), _linearMatchLen(1),
109 _celeste(
false), _celesteThreshold(0.5), _celesteRadius(20),
110 _keypath(
""), _outputFile(
"default.pto"), _outputGiven(
false), svmModel(
NULL)
125 std::cout <<
"Linear match length must be at least 1." << std::endl;
134 std::cout <<
"In test mode you must provide exactly 2 images." << std::endl;
144 std::cout <<
"Input file : " <<
_inputFile << std::endl;
147 std::cout <<
"Output file(s) : keyfile(s) for images";
157 std::cout <<
"Output file(s) : keyfiles for all images in project" << std::endl;
161 std::cout <<
"Output file : " <<
_outputFile << std::endl;
166 std::cout <<
"Path to keyfiles : " <<
_keypath << std::endl;
170 std::cout <<
"Cleanup temporary files." << std::endl;
174 std::cout <<
"Automatically cache keypoints files to disc." << std::endl;
176 std::cout <<
"Input image options" << std::endl;
177 std::cout <<
" Downscale to half-size : " << (
_downscale?
"yes":
"no") << std::endl;
180 std::cout <<
"Celeste options" << std::endl;
184 std::cout <<
"Sieve 1 Options" << std::endl;
187 std::cout <<
" Size : " <<
_sieve1Size << std::endl;
189 std::cout <<
"KDTree Options" << std::endl;
192 std::cout <<
"Matching Options" << std::endl;
196 std::cout <<
" Mode : All pairs" << std::endl;
199 std::cout <<
" Mode : Linear match with length of " <<
_linearMatchLen <<
" image" << std::endl;
202 std::cout <<
" Mode : Multi row" << std::endl;
205 std::cout <<
" Mode : Prealigned positions" << std::endl;
209 std::cout <<
"RANSAC Options" << std::endl;
210 std::cout <<
" Mode : ";
214 std::cout <<
"auto" << std::endl;
217 std::cout <<
"homography" << std::endl;
220 std::cout <<
"roll, pitch, yaw" << std::endl;
223 std::cout <<
"roll, pitch, yaw, fov" << std::endl;
226 std::cout <<
"roll, pitch, yaw, fov, distortion" << std::endl;
229 std::cout <<
" Iterations : " <<
_ransacIters << std::endl;
231 std::cout <<
"Minimum matches per image pair: " <<
_minimumMatches << std::endl;
232 std::cout <<
"Sieve 2 Options" << std::endl;
235 std::cout <<
" Size : " <<
_sieve2Size << std::endl;
241 std::cout << std::endl <<
"Project contains the following images:" << std::endl;
247 name=name.substr(
_prefix.length(),name.length()-
_prefix.length());
249 std::cout <<
"Image " <<
i << std::endl <<
" Imagefile: " << name << std::endl;
263 name=name.substr(
_prefix.length(),name.length()-
_prefix.length());
265 std::cout <<
" Keyfile : " << name;
268 std::cout <<
" (will be generated)" << std::endl;
272 std::cout << (
_filesData[
i]._hasakeyfile?
" (will be loaded)":
" (will be generated)") << std::endl;
275 std::cout <<
" Remapped : " << (
_filesData[
i].NeedsRemapping()?
"yes":
"no") << std::endl;
391 std::cout << std::endl <<
"Couldn't open SVM model file " <<
model_file << std::endl;
409#pragma omp parallel for schedule(dynamic)
410 for (
int i = 0;
i < queue.size(); ++
i)
415 while (!queue.empty())
451 if(!
aB->second._hasakeyfile)
454 if(
aB->second.NeedsRemapping())
493 std::cout <<
"\nThe available memory does not allow running " <<
_cores <<
" threads parallel.\n"
494 <<
"Running cpfind with " <<
maxCores <<
" threads.\n";
500 std::cout <<
"Using " <<
_cores <<
" threads" << std::endl;
506 TRACE_INFO(
"\nLoading Celeste model file...\n");
524 std::string
s=vigra::impexListExtensions();
530 TRACE_INFO(std::endl <<
"--- Analyze Images ---" << std::endl);
539 TRACE_INFO(std::endl <<
"--- Analyze Images ---" << std::endl);
566 if (
aB->second._hasakeyfile)
587 TRACE_INFO(
"One or more images failed to load. Exiting.");
593 TRACE_INFO(std::endl <<
"--- Cache keyfiles to disc ---" << std::endl);
596 if (!
aB->second._hasakeyfile)
598 TRACE_INFO(
"i" <<
aB->second._number <<
" : Caching keypoints..." << std::endl);
630 for(HuginBase::CPVector::const_iterator
it=cps.begin();
it!=cps.end(); ++
it)
658 TRACE_INFO(std::endl<<
"--- Write Keyfiles output ---" << std::endl << std::endl);
665 std::cout << std::endl <<
"Warning: You have given the --output switch." << std::endl
666 <<
"This switch is not compatible with the --writekeyfile or --kall switch." << std::endl
667 <<
"If you want to generate the keyfiles and" << std::endl
668 <<
"do the matching in the same run use the --cache switch instead." << std::endl << std::endl;
674 TRACE_INFO(std::endl<<
"--- Write Project output ---" << std::endl);
696 for (
unsigned int i1 = 0; i1 <
_filesData.size(); ++i1)
704 for (
unsigned int i2 = (i1+1); i2 <
aEnd; ++i2)
722 TRACE_INFO(std::endl<<
"--- Find pair-wise matches ---" << std::endl);
733 for (
size_t j = 0;
j <
aM._matches.size(); ++
j)
737 aM._i2->_number,
aPM->_img2_x,
aPM->_img2_y));
751#define getcwd _getcwd
780 for (
unsigned int imgNr = 0; imgNr <
nImg; ++imgNr)
811 _filesData[imgNr]._detectWidth = std::max(img.getSize().width(),img.getSize().height());
812 _filesData[imgNr]._detectHeight = std::max(img.getSize().width(),img.getSize().height());
817 _filesData[imgNr]._detectWidth = img.getSize().width();
818 _filesData[imgNr]._detectHeight = img.getSize().height();
822 if (
_downscale && std::min(img.getSize().width(), img.getSize().height()) > 2000)
911 if (
aB->second._hasakeyfile)
913 remove(
aB->second._keyfilename.c_str());
922 for (
size_t i = 0;
i < stacks.size(); ++
i)
927 index = stacks[
i].size() / 2;
930 if (stacks[
i].size()>1)
975 const size_t img1 = *
it;
976 HuginBase::UIntSet::const_iterator
it2 =
it;
980 const size_t img2 = *
it2;
998 TRACE_INFO(std::endl<<
"--- Find matches ---" << std::endl);
1009 for (
size_t j = 0;
j <
aM._matches.size(); ++
j)
1013 aM._i2->_number,
aPM->_img2_x,
aPM->_img2_y));
1023 const size_t n =
comps.size();
1027 for(
size_t i=0;
i<
n;
i++)
1066 TRACE_INFO(std::endl<<
"--- Find matches in images groups ---" << std::endl);
1076 for (
size_t j = 0;
j <
aM._matches.size(); ++
j)
1080 aM._i2->_number,
aPM->_img2_x,
aPM->_img2_y));
1120 for (
unsigned i=0;
i <
optPano.getNrOfImages();
i++)
1122 std::set<std::string>
imgopt;
1133 optvars.push_back(
imgopt);
1135 optPano.setOptimizeVector(optvars);
1140 for (HuginBase::CPVector::const_iterator
it = cps.begin();
it != cps.end(); ++
it)
1195 switch (
tempPano.getImage(
i).getProjection())
1211 for(
size_t i=0;
i<
tempPano.getNrOfImages()-1;
i++)
1231 TRACE_INFO(std::endl<<
"--- Find matches for overlapping images ---" << std::endl);
1242 for (
size_t j = 0;
j <
aM._matches.size(); ++
j)
1246 aM._i2->_number,
aPM->_img2_x,
aPM->_img2_y));
definitions of classes to calculate overlap between different images
declaration of functions to handle stacks and layers
!! from PTOptimise.h 1951
std::string includeTrailingPathSep(std::string path)
std::vector< Runnable * > RunnableVector
std::string getKeyfilenameFor(std::string keyfilesPath, std::string filename)
returns the filename for the keyfile for a given image
void RunQueue(std::vector< Runnable * > &queue)
static int ptProgress(int command, char *argument)
static int ptinfoDlg(int command, char *argument)
std::string getKeyfilenameFor(std::string keyfilesPath, std::string filename)
returns the filename for the keyfile for a given image
Contains functions to transform whole images.
Somewhere to specify what variables belong to what.
static void autoOptimise(PanoramaData &pano, bool optRoll=true)
class for calculating overlap of images
static double calcOptimalScale(PanoramaData &panorama)
represents a control point
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
unsigned int optimizeReferenceImage
void setHeight(unsigned int h)
set panorama height
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
unsigned int getWidth() const
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
void setImage(std::size_t nr, const SrcPanoImage &img)
set a panorama image, counting starts with 0
void updateMasks(bool convertPosMaskToNeg=false)
updates all active masks
bool ReadPTOFile(const std::string &filename, const std::string &prefix="")
read pto file from the given filename into Panorama object it does some checks on the file and issues...
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
unsigned int addCtrlPoint(const ControlPoint &point)
add a new control point.
VariableMapVector getVariables() const
get variables of this panorama
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Panorama getSubset(const UIntSet &imgs) const
get a subset of the panorama
Panorama duplicate() const
duplicate the panorama
std::size_t getNrOfImages() const
number of images.
All variables of a source image.
a variable has a value and a name.
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
std::vector< HuginBase::UIntSet > Components
stores the components of the graph
const PanoDetector & _panoDetector
ImgDataRunnable(PanoDetector::ImgData &iImageData, const PanoDetector &iPanoDetector)
PanoDetector::ImgData & _imgData
LoadKeypointsDataRunnable(PanoDetector::ImgData &iImageData, const PanoDetector &iPanoDetector)
PanoDetector::ImgData & _imgData
const PanoDetector & _panoDetector
PanoDetector::MatchData & _matchData
const PanoDetector & _panoDetector
MatchDataRunnable(PanoDetector::MatchData &iMatchData, const PanoDetector &iPanoDetector)
double _kdTreeSecondDistance
static bool AnalyzeImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
static bool MakeKeyPointDescriptorsInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
void writeKeyfile(ImgData &imgInfo)
static bool FindMatchesInPair(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
static bool FindKeyPointsInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
void buildMultiRowImageSets()
search for image layer and image stacks for the multirow matching step
MatchingStrategy getMatchingStrategy() const
struct celeste::svm_model * svmModel
HuginBase::Panorama * _panoramaInfo
static bool FilterKeyPointsInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
std::vector< HuginBase::UIntVector > _image_stacks
vector with image numbers of all stacks, contains only the unlinked stacks
std::vector< int > _keyPointsIdx
std::map< int, ImgData >::iterator ImgDataIt_t
bool match(std::vector< HuginBase::UIntSet > &checkedPairs)
static bool BuildKDTreesInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
bool matchPrealigned(HuginBase::Panorama *pano, std::vector< HuginBase::UIntSet > &connectedImages, std::vector< size_t > imgMap, bool exactOverlap=true)
does only matches image pairs which overlaps and don't have control points
std::vector< MatchData > MatchData_t
HuginBase::RANSACOptimizer::Mode _ransacMode
static bool FreeMemoryInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
static bool RansacMatchesInPair(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
HuginBase::Panorama _panoramaInfoCopy
static bool LoadKeypoints(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
void setCores(int iCores)
HuginBase::UIntSet _image_layer
image set contains only the images with the median exposure of each stack
void setCeleste(bool iCeleste)
std::set< std::string > _cpsHashSet
MatchingStrategy _matchingStrategy
static bool RemapBackKeypoints(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
static bool FilterMatchesInPair(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
const PanoDetector & _panoDetector
WriteKeyPointsRunnable(PanoDetector::ImgData &iImageData, const PanoDetector &iPanoDetector)
PanoDetector::ImgData & _imgData
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
std::vector< VariableMap > VariableMapVector
std::vector< ControlPoint > CPVector
std::vector< std::set< std::string > > OptimizeVector
std::vector< HuginBase::UIntVector > getSortedStacks(const HuginBase::Panorama *pano)
returns vector of UIntVector with image numbers of each stack sorted by exposure
std::set< unsigned int > UIntSet
void destroySVMmodel(struct svm_model *&model)
frees the resource of model
bool loadSVMmodel(struct svm_model *&model, std::string &model_file)
loads the SVM model from file
std::string stripExtension(const std::string &basename2)
remove extension of a filename
std::string GetDataDir()
returns the full path to the data directory
bool FileExists(const std::string &filename)
checks if file exists
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
std::shared_ptr< PointMatch > PointMatchPtr
unsigned long long getTotalMemory()
returns the total memory in byte
unsigned int GetPhysicalCPUCount()
return the number of physical cpu cores
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Map::mapped_type & map_get(Map &m, const typename Map::key_type &key)
get a map element.
lfeat::KeyPointVect_t _kp
lfeat::PointMatchVector_t _matches
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.