27 #include <vigra/distancetransform.hxx>
52 #define TRACE_IMG(X) {if (iPanoDetector.getVerbose() > 1) { TRACE_INFO("i" << ioImgInfo._number << " : " << X << std::endl);} }
53 #define TRACE_PAIR(X) {if (iPanoDetector.getVerbose() > 1){ TRACE_INFO("i" << ioMatchData._i1->_number << " <> " \
54 "i" << ioMatchData._i2->_number << " : " << X << std::endl)}}
123 template <
class SrcImageIterator,
class SrcAccessor>
126 vigra::Diff2D imgSize = img.second - img.first;
129 SrcImageIterator yd(img.first);
131 for(
int y=0; y < imgSize.y; ++y, ++yd.y)
134 SrcImageIterator xd(yd);
135 for(
int x=0; x < imgSize.x; ++x, ++xd.x)
137 if(!SrcImg.
isInside(vigra::Point2D(x,y)))
163 template <
class T2,
class A>
177 template <
class ImageType,
class PixelTransform>
179 size_t detectWidth,
size_t detectHeight,
181 const PixelTransform& pixelTransform,
182 ImageType*& finalImage, vigra::BImage*& finalMask)
187 finalImage =
new ImageType(detectWidth, detectHeight);
188 finalMask =
new vigra::BImage(detectWidth, detectHeight, vigra::UInt8(0));
194 mask =
new vigra::BImage(image->size(), vigra::UInt8(255));
216 template <
class ImageType>
218 size_t detectWidth,
size_t detectHeight,
bool downscale,
219 ImageType*& finalImage, vigra::BImage*& finalMask)
226 mask =
new vigra::BImage(image->size(), vigra::UInt8(255));
234 finalImage =
new ImageType(detectWidth, detectHeight);
241 finalMask =
new vigra::BImage(detectWidth, detectHeight);
262 vigra::DImage* final_img = NULL;
263 vigra::BImage* final_mask = NULL;
270 vigra::ImageImportInfo aImageInfo(ioImgInfo.
_name.c_str());
271 if (aImageInfo.numExtraBands() > 1)
273 TRACE_INFO(
"Image with multiple alpha channels are not supported");
282 if (aImageInfo.isGrayscale())
285 vigra::DImage* image =
new vigra::DImage(aImageInfo.size());
286 vigra::BImage* mask = NULL;
288 if (aImageInfo.numExtraBands() == 1)
290 mask=
new vigra::BImage(aImageInfo.size());
300 if (aImageInfo.getPixelType() == std::string(
"FLOAT") || aImageInfo.getPixelType() == std::string(
"DOUBLE") ||
301 aImageInfo.getPixelType() == std::string(
"UINT32") || aImageInfo.getPixelType() == std::string(
"INT32"))
303 vigra::FindAverageAndVariance<float> mean;
305 minVal =
std::max(mean.average() - 3 * sqrt(mean.variance()), 1e-6f);
306 maxVal = mean.average() + 3 * sqrt(mean.variance());;
312 bool range255 = (fabs(maxVal - 255) < 0.01 && fabs(minVal) < 0.01);
313 if (aImageInfo.getICCProfile().empty())
320 vigra::linearRangeMapping(minVal, maxVal, 0.0, 255.0));
330 vigra::linearRangeMapping(minVal, maxVal, 0.0, 1.0));
342 final_img, final_mask);
349 final_img, final_mask);
356 TRACE_IMG(
"Downscale and transform to suitable grayscale...");
359 final_img, final_mask);
363 TRACE_IMG(
"Transform to suitable grayscale...");
366 final_img, final_mask);
372 TRACE_IMG(
"Celeste does not work with grayscale images. Skipping...");
377 if (aImageInfo.isColor())
394 switch (aImageInfo.pixelType())
396 case vigra::ImageImportInfo::UINT8:
399 vigra::BRGBImage* rgbImage=
new vigra::BRGBImage(aImageInfo.size());
400 vigra::BImage* mask = NULL;
402 if (aImageInfo.numExtraBands() == 1)
404 mask=
new vigra::BImage(aImageInfo.size());
412 if (!aImageInfo.getICCProfile().empty())
417 vigra::BRGBImage* scaled = NULL;
440 vigra::UInt16RGBImage* image16=
new vigra::UInt16RGBImage(scaled->size());
442 vigra::linearIntensityTransform<vigra::RGBValue<vigra::UInt16> >(255));
444 #ifdef DEBUG_LOADING_REMAPPING
446 std::ostringstream maskfilename;
447 maskfilename << ioImgInfo.
_name <<
"_celeste_mask.JPG";
448 vigra::ImageExportInfo maskexinfo(maskfilename.str().c_str());
458 final_mask = celeste_mask;
462 TRACE_IMG(
"Convert to greyscale double...");
463 final_img =
new vigra::DImage(scaled->size());
469 case vigra::ImageImportInfo::UINT16:
472 vigra::UInt16RGBImage* rgbImage =
new vigra::UInt16RGBImage(aImageInfo.size());
473 vigra::BImage* mask = NULL;
475 if (aImageInfo.numExtraBands() == 1)
477 mask =
new vigra::BImage(aImageInfo.size());
485 if (!aImageInfo.getICCProfile().empty())
490 vigra::UInt16RGBImage* scaled = NULL;
514 #ifdef DEBUG_LOADING_REMAPPING
516 std::ostringstream maskfilename;
517 maskfilename << ioImgInfo.
_name <<
"_celeste_mask.JPG";
518 vigra::ImageExportInfo maskexinfo(maskfilename.str().c_str());
527 final_mask = celeste_mask;
531 TRACE_IMG(
"Convert to greyscale double...");
532 final_img =
new vigra::DImage(scaled->size());
535 vigra::destImage(*final_img), vigra::functor::Arg1() / vigra::functor::Param(255.0));
542 vigra::DRGBImage* rgbImage =
new vigra::DRGBImage(aImageInfo.size());
543 vigra::BImage* mask = NULL;
545 if (aImageInfo.numExtraBands() == 1)
547 mask =
new vigra::BImage(aImageInfo.size());
557 const bool isDouble = aImageInfo.getPixelType() == std::string(
"FLOAT") || aImageInfo.getPixelType() == std::string(
"DOUBLE") ||
558 aImageInfo.getPixelType() == std::string(
"UINT32") || aImageInfo.getPixelType() == std::string(
"INT32");
561 vigra::FindAverageAndVariance<float> mean;
562 vigra::inspectImage(
vigra::srcImageRange(*rgbImage, vigra::RGBToGrayAccessor<vigra::RGBValue<double> >()), mean);
563 minVal =
std::max(mean.average() - 3 * sqrt(mean.variance()), 1e-6f);
564 maxVal = mean.average() + 3 * sqrt(mean.variance());;
570 bool range255 = (fabs(maxVal - 255) < 0.01 && fabs(minVal) < 0.01);
571 if (aImageInfo.getICCProfile().empty())
597 vigra::DRGBImage* scaled;
608 TRACE_IMG(
"Transform to suitable grayscale...");
616 vigra::UInt16RGBImage* image16 =
new vigra::UInt16RGBImage(scaled->size());
620 vigra::linearIntensityTransform<vigra::RGBValue<vigra::UInt16> >(255));
625 vigra::linearIntensityTransform<vigra::RGBValue<vigra::UInt16> >(65535));
628 #ifdef DEBUG_LOADING_REMAPPING
630 std::ostringstream maskfilename;
631 maskfilename << ioImgInfo.
_name <<
"_celeste_mask.JPG";
632 vigra::ImageExportInfo maskexinfo(maskfilename.str().c_str());
642 final_mask = celeste_mask;
646 TRACE_IMG(
"Convert to greyscale double...");
647 final_img =
new vigra::DImage(scaled->size());
656 vigra::destImage(*final_img), vigra::functor::Arg1() * vigra::functor::Param(255.0));
665 TRACE_INFO(
"Cpfind works only with grayscale or RGB images");
671 #ifdef DEBUG_LOADING_REMAPPING
673 std::ostringstream filename;
674 filename << ioImgInfo.
_name <<
"_grey.JPG";
675 vigra::ImageExportInfo exinfo(filename.str().c_str());
681 ioImgInfo.
_ii.
init(*final_img);
690 vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType>(1, 255, 0, 255));
691 ioImgInfo.
_distancemap.resize(final_mask->width(), final_mask->height(), 0);
693 #ifdef DEBUG_LOADING_REMAPPING
694 std::ostringstream maskfilename;
695 maskfilename << ioImgInfo.
_name <<
"_mask.JPG";
696 vigra::ImageExportInfo maskexinfo(maskfilename.str().c_str());
698 std::ostringstream distfilename;
699 distfilename << ioImgInfo.
_name <<
"_distancemap.JPG";
700 vigra::ImageExportInfo distexinfo(distfilename.str().c_str());
706 catch (std::exception& e)
708 TRACE_INFO(
"An error happened while loading image : caught exception: " << e.what() << std::endl);
728 TRACE_IMG(
"Found "<< ioImgInfo.
_kp.size() <<
" interest points.");
746 for (
size_t i = 0; i < ioImgInfo.
_kp.size(); ++i)
752 && ioImgInfo.
_distancemap((
int)(aK->_x),(
int)(aK->_y)) >aK->_scale*8)
755 aSieve.insert(aK, (
int)(aK->_x * aXF), (
int)(aK->_y * aYF));
760 aSieve.insert(aK, (
int)(aK->_x * aXF), (
int)(aK->_y * aYF));
765 ioImgInfo.
_kp.clear();
769 aSieve.extract(aSieveExt);
771 TRACE_IMG(
"Kept " << ioImgInfo.
_kp.size() <<
" interest points.");
779 TRACE_IMG(
"Make keypoint descriptors...");
786 for (
size_t j = 0; j < ioImgInfo.
_kp.size(); ++j)
791 for (
int i=0; i < nAngles; i++)
795 aKn->_ori = angles[i];
796 kp_new_ori.push_back(aKn);
799 ioImgInfo.
_kp.insert(ioImgInfo.
_kp.end(), kp_new_ori.begin(), kp_new_ori.end());
801 for (
size_t i = 0; i < ioImgInfo.
_kp.size(); ++i)
814 for (
size_t i = 0; i < ioImgInfo.
_kp.size(); ++i)
826 TRACE_IMG(
"Remapping back keypoints...");
834 for (
size_t i = 0; i < ioImgInfo.
_kp.size(); ++i)
855 if(ioImgInfo.
_kp.empty())
864 for (
size_t i = 0; i < ioImgInfo.
_kp.size(); ++i)
892 flann::Index<flann::L2<double> > * index2 = ioMatchData.
_i2->
_flann_index;
899 flann::Matrix<int> indices(
new int[query.rows*nn], query.rows, nn);
900 flann::Matrix<double> dists(
new double[query.rows*nn], query.rows, nn);
903 index2->knnSearch(query, indices, dists, nn, flann::SearchParams(iPanoDetector.
getKDTreeSearchSteps()));
911 std::set<int> aAlreadyMatched;
912 std::set<int> aBadMatch;
915 typedef std::pair<lfeat::KeyPointPtr, int> TmpPair_t;
916 std::vector<TmpPair_t> aUnfilteredMatches;
921 for (
unsigned aKIt = 0; aKIt < query.rows; ++aKIt)
931 if (aAlreadyMatched.find(indices[aKIt][0]) != aAlreadyMatched.end())
934 aBadMatch.insert(indices[aKIt][0]);
941 aAlreadyMatched.insert(indices[aKIt][0]);
944 aUnfilteredMatches.push_back(TmpPair_t(ioMatchData.
_i1->
_kp[aKIt], indices[aKIt][0]));
948 for (
size_t i = 0; i < aUnfilteredMatches.size(); ++i)
950 TmpPair_t& aP = aUnfilteredMatches[i];
952 if (aBadMatch.find(aP.second) != aBadMatch.end())
961 delete[] indices.ptr();
962 delete[] dists.ptr();
986 TRACE_PAIR(
"RANSAC Filtering with Panorama model...");
990 TRACE_PAIR(
"Too few matches ... removing all of them.");
995 if (ioMatchData.
_matches.size() < 6)
997 TRACE_PAIR(
"Not enough matches for RANSAC filtering.");
1006 imgs.insert(pano_i1);
1007 imgs.insert(pano_i2);
1008 int pano_local_i1 = 0;
1009 int pano_local_i2 = 1;
1010 if (pano_i1 > pano_i2)
1018 std::vector<int> inliers;
1019 #pragma omp critical
1025 for (
size_t i = 0; i < ioMatchData.
_matches.size(); ++i)
1029 pano_local_i2, aM->_img2_x, aM->_img2_y);
1047 PT_setProgressFcn(NULL);
1048 PT_setInfoDlgFcn(NULL);
1052 TRACE_PAIR(
"Removed " << ioMatchData.
_matches.size() - inliers.size() <<
" matches. " << inliers.size() <<
" remaining.");
1053 if (inliers.size() < 0.5 * ioMatchData.
_matches.size())
1056 TRACE_PAIR(
"RANSAC found more than 50% outliers, removing all matches");
1064 TRACE_PAIR(
"Too few matches ... removing all of them.");
1071 aInlierMatches.reserve(inliers.size());
1073 for (
size_t i = 0; i < inliers.size(); ++i)
1075 aInlierMatches.push_back(ioMatchData.
_matches[inliers[i]]);
1077 ioMatchData.
_matches = aInlierMatches;
1095 TRACE_PAIR(
"Too few matches ... removing all of them.");
1100 if (ioMatchData.
_matches.size() < 6)
1102 TRACE_PAIR(
"Not enough matches for RANSAC filtering.");
1115 thresholdDistance*=5;
1121 TRACE_PAIR(
"Removed " << aRemovedMatches.size() <<
" matches. " << ioMatchData.
_matches.size() <<
" remaining.");
1123 if (aRemovedMatches.size() > ioMatchData.
_matches.size())
1126 TRACE_PAIR(
"More than 50% outliers, removing all matches");
1133 aRemovedMatches, aRansacFilter, iPanoDetector.
getDownscale());
1144 if (ioMatchData.
_matches.size() < 2)
1156 for (
size_t i = 0; i < ioMatchData.
_matches.size(); ++i)
1159 if (aM->_img1_x < aMinX)
1161 aMinX = aM->_img1_x;
1163 if (aM->_img1_x > aMaxX)
1165 aMaxX = aM->_img1_x;
1168 if (aM->_img1_y < aMinY)
1170 aMinY = aM->_img1_y;
1172 if (aM->_img1_y > aMaxY)
1174 aMaxY = aM->_img1_y;
1178 double aSizeX = aMaxX - aMinX + 2;
1179 double aSizeY = aMaxY - aMinY + 2;
1190 for (
size_t i = 0; i < ioMatchData.
_matches.size(); ++i)
1194 ioMatchData.
_i2->
_number, aM->_img2_x, aM->_img2_y);
1200 aSieve.insert(aM, (
int)((aM->_img1_x - aMinX) * aXF), (
int)((aM->_img1_y - aMinY) * aYF));
1208 aSieve.extract(aSieveExt);
1219 std::cerr <<
"ERROR couldn't write to output file '" <<
_outputFile <<
"'!" << std::endl;
1227 std::ofstream aOut(imgInfo.
_keyfilename.c_str(), std::ios_base::trunc);
1236 writer.writeHeader ( img_info, imgInfo.
_kp.size(), imgInfo.
_descLength );
1238 for(
size_t i=0; i<imgInfo.
_kp.size(); ++i)
1241 writer.writeKeypoint ( aK->_x, aK->_y, aK->_scale, aK->_ori, aK->_score,
1244 writer.writeFooter();
int getSieve2Width() const
int getRansacIterations() const
Dummy progress display, without output.
double getMaxValForPixelType(const std::string &v)
int getSieve2Size() const
std::vector< PointMatchPtr > PointMatchVector_t
void HandleDownscaleImage(const HuginBase::SrcPanoImage &srcImage, ImageType *&image, vigra::BImage *&mask, size_t detectWidth, size_t detectHeight, bool downscale, ImageType *&finalImage, vigra::BImage *&finalMask)
downscale image if requested, optimized code for non-downscale version to prevent unnecessary copying...
vigra::BImage _distancemap
std::vector< KeyPointPtr > KeyPointVect_t
void setHeight(unsigned int h)
set panorama height
void transformImage(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform an image into the panorama.
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
virtual void setCtrlPoints(const CPVector &points)=0
set all control points (Ippei: Is this supposed to be 'add' method?)
vigra::BImage * getCelesteMask(struct svm_model *model, vigra::UInt16RGBImage &input, int radius, float threshold, int resize_dimension, bool adaptThreshold, bool verbose)
calculates the mask using SVM
PanoramaData * getNewSubset(const UIntSet &imgs) const
int getMinimumMatches() const
void copyImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
static const double A(-0.75)
static bool LoadKeypoints(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
static bool MakeKeyPointDescriptorsInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
void makeDescriptor(KeyPoint &ioKeyPoint) const
HuginBase::PanoramaOptions _projOpts
bool hasActiveMasks() const
returns true, if image has active masks
static std::vector< int > findInliers(PanoramaData &pano, int i1, int i2, double maxError, Mode mode=RPY)
T2 operator()(const T2 &a, const hugin_utils::FDiff2D &p) const
void setDistanceThreshold(int iDT)
Contains functions to transform whole images.
static int ptinfoDlg(int command, char *argument)
bool set_contains(const _Container &c, const typename _Container::key_type &key)
static int ptProgress(int command, char *argument)
int getHeight() const
Get the height of the image in pixels.
void setIterations(int iIters)
bool isInside(vigra::Point2D p, bool ignoreMasks=false) const
check if a coordinate is inside the source image
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
void applyMapping(vigra::triple< SrcIterator, SrcIterator, SrcAccessor > img, vigra::pair< DestIterator, DestAccessor > dest, T min, T max, int mapping)
represents a control point
functor to scale image on the fly during other operations
std::set< unsigned int > UIntSet
const std::string getCPString() const
returns string which contains all features of a control point used for detecting duplicate control po...
static bool RansacMatchesInPairCam(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
const vigra::Rect2D & getROI() const
static bool FilterKeyPointsInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
int getSieve1Height() const
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
int getSieve1Size() const
void filter(std::vector< PointMatchPtr > &ioMatches, std::vector< PointMatchPtr > &ioRemovedMatches)
vigra::FRGBImage ImageType
std::set< std::string > _cpsHashSet
int getWidth() const
Get the width of the image in pixels.
static bool FindMatchesInPair(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
lfeat::KeyPointVect_t & _v
static bool RansacMatchesInPair(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
void RemapImage(const HuginBase::SrcPanoImage &srcImage, const HuginBase::PanoramaOptions &options, size_t detectWidth, size_t detectHeight, ImageType *&image, vigra::BImage *&mask, const PixelTransform &pixelTransform, ImageType *&finalImage, vigra::BImage *&finalMask)
helper function to remap image to given projection, you can supply a pixelTransform, which will be applied during remapping, this is intended for scaling a image during remapping, but this means also, that no photometric corrections are applied, if this is wanted you need to supply a suitable pixelTransform
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
static bool RemapBackKeypoints(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
void init(vigra::DImage &img)
static void drawRansacMatches(std::string &i1, std::string &i2, lfeat::PointMatchVector_t &iOK, lfeat::PointMatchVector_t &iNOK, lfeat::Ransac &iRansac, bool iHalf)
bool NeedsRemapping() const
static bool FreeMemoryInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages
!! from PTOptimise.h 1951
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.
ScaleFunctor(double scale)
flann::Matrix< double > _flann_descriptors
void importImageAlpha(const ImageImportInfo &import_info, ImageIterator image_iterator, ImageAccessor image_accessor, AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor)
Read the image specified by the given vigra::ImageImportInfo object including its alpha channel...
HuginBase::Panorama _panoramaInfoCopy
T operator()(const T &a) const
struct celeste::svm_model * svmModel
HuginBase::RANSACOptimizer::Mode _ransacMode
int getKDTreeSearchSteps() const
static bool FilterMatchesInPair(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
lfeat::KeyPointVect_t _kp
void transformImageAlpha(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, std::pair< SrcAlphaIterator, SrcAlphaAccessor > srcAlpha, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform image, and respect a possible alpha channel.
static bool AnalyzeImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
KeyPointVectInsertor(lfeat::KeyPointVect_t &iVect)
int getDescriptorLength() const
bool getDownscale() const
flann::Index< flann::L2< double > > * _flann_index
double getCelesteThreshold() const
int getSieve2Height() const
void applyMaskAndCrop(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > img, const HuginBase::SrcPanoImage &SrcImg)
apply the mask and the crop of the given SrcImg to given mask image
std::shared_ptr< KeyPoint > KeyPointPtr
std::vector< ControlPoint > CPVector
double getKDTreeSecondDistance() const
vigra::triple< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImageRange(ROIImage< Image, Alpha > &img)
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
int assignOrientation(KeyPoint &ioKeyPoint, double angles[4]) const
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
static void info(const char *fmt,...)
HuginBase::Panorama * _panoramaInfo
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
virtual void operator()(const lfeat::KeyPoint &k)
int getCelesteRadius() const
A hdrWeight(T2 v, A a) const
void writeKeyfile(ImgData &imgInfo)
int getSieve1Width() const
All variables of a source image.
std::shared_ptr< PointMatch > PointMatchPtr
functions to handle icc profiles in images
ImageInfo loadKeypoints(const std::string &filename, KeyPointVect_t &vec)
void detectKeypoints(Image &iImage, KeyPointInsertor &iInsertor)
static bool FindKeyPointsInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
void ApplyICCProfile(ImageType &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsUInt32Number imageFormat)
converts given image with iccProfile to sRGB/gray space, need to give pixel type in lcms2 format work...
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
static bool BuildKDTreesInImage(ImgData &ioImgInfo, const PanoDetector &iPanoDetector)
static bool RansacMatchesInPairHomography(MatchData &ioMatchData, const PanoDetector &iPanoDetector)
int getRansacDistanceThreshold() const