Moved to Visual Studio 2015, OpenCV 3.2.0, x64

This commit is contained in:
MarekKowalski
2017-02-28 11:30:27 +01:00
parent 44f9a1da22
commit 98bfe298ab
244 changed files with 56126 additions and 68481 deletions
+27 -6
View File
@@ -40,26 +40,47 @@
//
//M*/
#ifndef __OPENCV_STITCHING_AUTOCALIB_HPP__
#define __OPENCV_STITCHING_AUTOCALIB_HPP__
#ifndef OPENCV_STITCHING_AUTOCALIB_HPP
#define OPENCV_STITCHING_AUTOCALIB_HPP
#include "opencv2/core/core.hpp"
#include "opencv2/core.hpp"
#include "matchers.hpp"
namespace cv {
namespace detail {
// See "Construction of Panoramic Image Mosaics with Global and Local Alignment"
// by Heung-Yeung Shum and Richard Szeliski.
//! @addtogroup stitching_autocalib
//! @{
/** @brief Tries to estimate focal lengths from the given homography under the assumption that the camera
undergoes rotations around its centre only.
@param H Homography.
@param f0 Estimated focal length along X axis.
@param f1 Estimated focal length along Y axis.
@param f0_ok True, if f0 was estimated successfully, false otherwise.
@param f1_ok True, if f1 was estimated successfully, false otherwise.
See "Construction of Panoramic Image Mosaics with Global and Local Alignment"
by Heung-Yeung Shum and Richard Szeliski.
*/
void CV_EXPORTS focalsFromHomography(const Mat &H, double &f0, double &f1, bool &f0_ok, bool &f1_ok);
/** @brief Estimates focal lengths for each given camera.
@param features Features of images.
@param pairwise_matches Matches between all image pairs.
@param focals Estimated focal lengths for each camera.
*/
void CV_EXPORTS estimateFocal(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<double> &focals);
bool CV_EXPORTS calibrateRotatingCamera(const std::vector<Mat> &Hs, Mat &K);
//! @} stitching_autocalib
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_AUTOCALIB_HPP__
#endif // OPENCV_STITCHING_AUTOCALIB_HPP
+58 -28
View File
@@ -40,16 +40,25 @@
//
//M*/
#ifndef __OPENCV_STITCHING_BLENDERS_HPP__
#define __OPENCV_STITCHING_BLENDERS_HPP__
#ifndef OPENCV_STITCHING_BLENDERS_HPP
#define OPENCV_STITCHING_BLENDERS_HPP
#include "opencv2/core/core.hpp"
#if defined(NO)
# warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers.
#endif
#include "opencv2/core.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching_blend
//! @{
// Simple blender which puts one image over another
/** @brief Base class for all blenders.
Simple blender which puts one image over another
*/
class CV_EXPORTS Blender
{
public:
@@ -58,17 +67,35 @@ public:
enum { NO, FEATHER, MULTI_BAND };
static Ptr<Blender> createDefault(int type, bool try_gpu = false);
/** @brief Prepares the blender for blending.
@param corners Source images top-left corners
@param sizes Source image sizes
*/
void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);
/** @overload */
virtual void prepare(Rect dst_roi);
virtual void feed(const Mat &img, const Mat &mask, Point tl);
virtual void blend(Mat &dst, Mat &dst_mask);
/** @brief Processes the image.
@param img Source image
@param mask Source image mask
@param tl Source image top-left corners
*/
virtual void feed(InputArray img, InputArray mask, Point tl);
/** @brief Blends and returns the final pano.
@param dst Final pano
@param dst_mask Final pano mask
*/
virtual void blend(InputOutputArray dst, InputOutputArray dst_mask);
protected:
Mat dst_, dst_mask_;
UMat dst_, dst_mask_;
Rect dst_roi_;
};
/** @brief Simple blender which mixes images at its borders.
*/
class CV_EXPORTS FeatherBlender : public Blender
{
public:
@@ -78,23 +105,24 @@ public:
void setSharpness(float val) { sharpness_ = val; }
void prepare(Rect dst_roi);
void feed(const Mat &img, const Mat &mask, Point tl);
void blend(Mat &dst, Mat &dst_mask);
void feed(InputArray img, InputArray mask, Point tl);
void blend(InputOutputArray dst, InputOutputArray dst_mask);
// Creates weight maps for fixed set of source images by their masks and top-left corners.
// Final image can be obtained by simple weighting of the source images.
Rect createWeightMaps(const std::vector<Mat> &masks, const std::vector<Point> &corners,
std::vector<Mat> &weight_maps);
//! Creates weight maps for fixed set of source images by their masks and top-left corners.
//! Final image can be obtained by simple weighting of the source images.
Rect createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
std::vector<UMat> &weight_maps);
private:
float sharpness_;
Mat weight_map_;
Mat dst_weight_map_;
UMat weight_map_;
UMat dst_weight_map_;
};
inline FeatherBlender::FeatherBlender(float _sharpness) { setSharpness(_sharpness); }
/** @brief Blender which uses multi-band blending algorithm (see @cite BA83).
*/
class CV_EXPORTS MultiBandBlender : public Blender
{
public:
@@ -104,13 +132,13 @@ public:
void setNumBands(int val) { actual_num_bands_ = val; }
void prepare(Rect dst_roi);
void feed(const Mat &img, const Mat &mask, Point tl);
void blend(Mat &dst, Mat &dst_mask);
void feed(InputArray img, InputArray mask, Point tl);
void blend(InputOutputArray dst, InputOutputArray dst_mask);
private:
int actual_num_bands_, num_bands_;
std::vector<Mat> dst_pyr_laplace_;
std::vector<Mat> dst_band_weights_;
std::vector<UMat> dst_pyr_laplace_;
std::vector<UMat> dst_band_weights_;
Rect dst_roi_final_;
bool can_use_gpu_;
int weight_type_; //CV_32F or CV_16S
@@ -120,18 +148,20 @@ private:
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
void CV_EXPORTS normalizeUsingWeightMap(const Mat& weight, Mat& src);
void CV_EXPORTS normalizeUsingWeightMap(InputArray weight, InputOutputArray src);
void CV_EXPORTS createWeightMap(const Mat& mask, float sharpness, Mat& weight);
void CV_EXPORTS createWeightMap(InputArray mask, float sharpness, InputOutputArray weight);
void CV_EXPORTS createLaplacePyr(const Mat &img, int num_levels, std::vector<Mat>& pyr);
void CV_EXPORTS createLaplacePyrGpu(const Mat &img, int num_levels, std::vector<Mat>& pyr);
void CV_EXPORTS createLaplacePyr(InputArray img, int num_levels, std::vector<UMat>& pyr);
void CV_EXPORTS createLaplacePyrGpu(InputArray img, int num_levels, std::vector<UMat>& pyr);
// Restores source image
void CV_EXPORTS restoreImageFromLaplacePyr(std::vector<Mat>& pyr);
void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector<Mat>& pyr);
void CV_EXPORTS restoreImageFromLaplacePyr(std::vector<UMat>& pyr);
void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector<UMat>& pyr);
//! @}
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_BLENDERS_HPP__
#endif // OPENCV_STITCHING_BLENDERS_HPP
+13 -4
View File
@@ -40,14 +40,21 @@
//
//M*/
#ifndef __OPENCV_STITCHING_CAMERA_HPP__
#define __OPENCV_STITCHING_CAMERA_HPP__
#ifndef OPENCV_STITCHING_CAMERA_HPP
#define OPENCV_STITCHING_CAMERA_HPP
#include "opencv2/core/core.hpp"
#include "opencv2/core.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching
//! @{
/** @brief Describes camera parameters.
@note Translation is assumed to be zero during the whole stitching pipeline. :
*/
struct CV_EXPORTS CameraParams
{
CameraParams();
@@ -63,7 +70,9 @@ struct CV_EXPORTS CameraParams
Mat t; // Translation
};
//! @}
} // namespace detail
} // namespace cv
#endif // #ifndef __OPENCV_STITCHING_CAMERA_HPP__
#endif // #ifndef OPENCV_STITCHING_CAMERA_HPP
@@ -40,14 +40,23 @@
//
//M*/
#ifndef __OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP__
#define __OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP__
#ifndef OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP
#define OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP
#include "opencv2/core/core.hpp"
#if defined(NO)
# warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers.
#endif
#include "opencv2/core.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching_exposure
//! @{
/** @brief Base class for all exposure compensators.
*/
class CV_EXPORTS ExposureCompensator
{
public:
@@ -56,51 +65,72 @@ public:
enum { NO, GAIN, GAIN_BLOCKS };
static Ptr<ExposureCompensator> createDefault(int type);
void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
const std::vector<Mat> &masks);
virtual void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
const std::vector<std::pair<Mat,uchar> > &masks) = 0;
virtual void apply(int index, Point corner, Mat &image, const Mat &mask) = 0;
/**
@param corners Source image top-left corners
@param images Source images
@param masks Image masks to update (second value in pair specifies the value which should be used
to detect where image is)
*/
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<UMat> &masks);
/** @overload */
virtual void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) = 0;
/** @brief Compensate exposure in the specified image.
@param index Image index
@param corner Image top-left corner
@param image Image to process
@param mask Image mask
*/
virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0;
};
/** @brief Stub exposure compensator which does nothing.
*/
class CV_EXPORTS NoExposureCompensator : public ExposureCompensator
{
public:
void feed(const std::vector<Point> &/*corners*/, const std::vector<Mat> &/*images*/,
const std::vector<std::pair<Mat,uchar> > &/*masks*/) {};
void apply(int /*index*/, Point /*corner*/, Mat &/*image*/, const Mat &/*mask*/) {};
void feed(const std::vector<Point> &/*corners*/, const std::vector<UMat> &/*images*/,
const std::vector<std::pair<UMat,uchar> > &/*masks*/) { }
void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) { }
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image
intensities, see @cite BL07 and @cite WJ10 for details.
*/
class CV_EXPORTS GainCompensator : public ExposureCompensator
{
public:
void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
const std::vector<std::pair<Mat,uchar> > &masks);
void apply(int index, Point corner, Mat &image, const Mat &mask);
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks);
void apply(int index, Point corner, InputOutputArray image, InputArray mask);
std::vector<double> gains() const;
private:
Mat_<double> gains_;
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block
intensities, see @cite UES01 for details.
*/
class CV_EXPORTS BlocksGainCompensator : public ExposureCompensator
{
public:
BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
: bl_width_(bl_width), bl_height_(bl_height) {}
void feed(const std::vector<Point> &corners, const std::vector<Mat> &images,
const std::vector<std::pair<Mat,uchar> > &masks);
void apply(int index, Point corner, Mat &image, const Mat &mask);
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks);
void apply(int index, Point corner, InputOutputArray image, InputArray mask);
private:
int bl_width_, bl_height_;
std::vector<Mat_<float> > gain_maps_;
std::vector<UMat> gain_maps_;
};
//! @}
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP__
#endif // OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP
+195 -29
View File
@@ -40,43 +40,89 @@
//
//M*/
#ifndef __OPENCV_STITCHING_MATCHERS_HPP__
#define __OPENCV_STITCHING_MATCHERS_HPP__
#ifndef OPENCV_STITCHING_MATCHERS_HPP
#define OPENCV_STITCHING_MATCHERS_HPP
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/opencv_modules.hpp"
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
#include "opencv2/nonfree/gpu.hpp"
#ifdef HAVE_OPENCV_XFEATURES2D
# include "opencv2/xfeatures2d/cuda.hpp"
#endif
namespace cv {
namespace detail {
//! @addtogroup stitching_match
//! @{
/** @brief Structure containing image keypoints and descriptors. */
struct CV_EXPORTS ImageFeatures
{
int img_idx;
Size img_size;
std::vector<KeyPoint> keypoints;
Mat descriptors;
UMat descriptors;
};
/** @brief Feature finders base class */
class CV_EXPORTS FeaturesFinder
{
public:
virtual ~FeaturesFinder() {}
void operator ()(const Mat &image, ImageFeatures &features);
void operator ()(const Mat &image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
/** @overload */
void operator ()(InputArray image, ImageFeatures &features);
/** @brief Finds features in the given image.
@param image Source image
@param features Found features
@param rois Regions of interest
@sa detail::ImageFeatures, Rect_
*/
void operator ()(InputArray image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
/** @brief Finds features in the given images in parallel.
@param images Source images
@param features Found features for each image
@param rois Regions of interest for each image
@sa detail::ImageFeatures, Rect_
*/
void operator ()(InputArrayOfArrays images, std::vector<ImageFeatures> &features,
const std::vector<std::vector<cv::Rect> > &rois);
/** @overload */
void operator ()(InputArrayOfArrays images, std::vector<ImageFeatures> &features);
/** @brief Frees unused memory allocated before if there is any. */
virtual void collectGarbage() {}
/* TODO OpenCV ABI 4.x
reimplement this as public method similar to FeaturesMatcher and remove private function hack
@return True, if it's possible to use the same finder instance in parallel, false otherwise
bool isThreadSafe() const { return is_thread_safe_; }
*/
protected:
virtual void find(const Mat &image, ImageFeatures &features) = 0;
/** @brief This method must implement features finding logic in order to make the wrappers
detail::FeaturesFinder::operator()_ work.
@param image Source image
@param features Found features
@sa detail::ImageFeatures */
virtual void find(InputArray image, ImageFeatures &features) = 0;
/** @brief uses dynamic_cast to determine thread-safety
@return True, if it's possible to use the same finder instance in parallel, false otherwise
*/
bool isThreadSafe() const;
};
/** @brief SURF features finder.
@sa detail::FeaturesFinder, SURF
*/
class CV_EXPORTS SurfFeaturesFinder : public FeaturesFinder
{
public:
@@ -84,27 +130,51 @@ public:
int num_octaves_descr = /*4*/3, int num_layers_descr = /*2*/4);
private:
void find(const Mat &image, ImageFeatures &features);
void find(InputArray image, ImageFeatures &features);
Ptr<FeatureDetector> detector_;
Ptr<DescriptorExtractor> extractor_;
Ptr<Feature2D> surf;
};
/** @brief ORB features finder. :
@sa detail::FeaturesFinder, ORB
*/
class CV_EXPORTS OrbFeaturesFinder : public FeaturesFinder
{
public:
OrbFeaturesFinder(Size _grid_size = Size(3,1), int nfeatures=1500, float scaleFactor=1.3f, int nlevels=5);
private:
void find(const Mat &image, ImageFeatures &features);
void find(InputArray image, ImageFeatures &features);
Ptr<ORB> orb;
Size grid_size;
};
/** @brief AKAZE features finder. :
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
@sa detail::FeaturesFinder, AKAZE
*/
class CV_EXPORTS AKAZEFeaturesFinder : public detail::FeaturesFinder
{
public:
AKAZEFeaturesFinder(int descriptor_type = AKAZE::DESCRIPTOR_MLDB,
int descriptor_size = 0,
int descriptor_channels = 3,
float threshold = 0.001f,
int nOctaves = 4,
int nOctaveLayers = 4,
int diffusivity = KAZE::DIFF_PM_G2);
private:
void find(InputArray image, detail::ImageFeatures &features);
Ptr<AKAZE> akaze;
};
#ifdef HAVE_OPENCV_XFEATURES2D
class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder
{
public:
@@ -114,62 +184,107 @@ public:
void collectGarbage();
private:
void find(const Mat &image, ImageFeatures &features);
void find(InputArray image, ImageFeatures &features);
gpu::GpuMat image_;
gpu::GpuMat gray_image_;
gpu::SURF_GPU surf_;
gpu::GpuMat keypoints_;
gpu::GpuMat descriptors_;
cuda::GpuMat image_;
cuda::GpuMat gray_image_;
cuda::SURF_CUDA surf_;
cuda::GpuMat keypoints_;
cuda::GpuMat descriptors_;
int num_octaves_, num_layers_;
int num_octaves_descr_, num_layers_descr_;
};
#endif
/** @brief Structure containing information about matches between two images.
It's assumed that there is a transformation between those images. Transformation may be
homography or affine transformation based on selected matcher.
@sa detail::FeaturesMatcher
*/
struct CV_EXPORTS MatchesInfo
{
MatchesInfo();
MatchesInfo(const MatchesInfo &other);
const MatchesInfo& operator =(const MatchesInfo &other);
int src_img_idx, dst_img_idx; // Images indices (optional)
int src_img_idx, dst_img_idx; //!< Images indices (optional)
std::vector<DMatch> matches;
std::vector<uchar> inliers_mask; // Geometrically consistent matches mask
int num_inliers; // Number of geometrically consistent matches
Mat H; // Estimated homography
double confidence; // Confidence two images are from the same panorama
std::vector<uchar> inliers_mask; //!< Geometrically consistent matches mask
int num_inliers; //!< Number of geometrically consistent matches
Mat H; //!< Estimated transformation
double confidence; //!< Confidence two images are from the same panorama
};
/** @brief Feature matchers base class. */
class CV_EXPORTS FeaturesMatcher
{
public:
virtual ~FeaturesMatcher() {}
/** @overload
@param features1 First image features
@param features2 Second image features
@param matches_info Found matches
*/
void operator ()(const ImageFeatures &features1, const ImageFeatures &features2,
MatchesInfo& matches_info) { match(features1, features2, matches_info); }
void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
const cv::Mat &mask = cv::Mat());
/** @brief Performs images matching.
@param features Features of the source images
@param pairwise_matches Found pairwise matches
@param mask Mask indicating which image pairs must be matched
The function is parallelized with the TBB library.
@sa detail::MatchesInfo
*/
void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
const cv::UMat &mask = cv::UMat());
/** @return True, if it's possible to use the same matcher instance in parallel, false otherwise
*/
bool isThreadSafe() const { return is_thread_safe_; }
/** @brief Frees unused memory allocated before if there is any.
*/
virtual void collectGarbage() {}
protected:
FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {}
/** @brief This method must implement matching logic in order to make the wrappers
detail::FeaturesMatcher::operator()_ work.
@param features1 first image features
@param features2 second image features
@param matches_info found matches
*/
virtual void match(const ImageFeatures &features1, const ImageFeatures &features2,
MatchesInfo& matches_info) = 0;
bool is_thread_safe_;
};
/** @brief Features matcher which finds two best matches for each feature and leaves the best one only if the
ratio between descriptor distances is greater than the threshold match_conf
@sa detail::FeaturesMatcher
*/
class CV_EXPORTS BestOf2NearestMatcher : public FeaturesMatcher
{
public:
/** @brief Constructs a "best of 2 nearest" matcher.
@param try_use_gpu Should try to use GPU or not
@param match_conf Match distances ration threshold
@param num_matches_thresh1 Minimum number of matches required for the 2D projective transform
estimation used in the inliers classification step
@param num_matches_thresh2 Minimum number of matches required for the 2D projective transform
re-estimation on inliers
*/
BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
int num_matches_thresh2 = 6);
@@ -183,7 +298,58 @@ protected:
Ptr<FeaturesMatcher> impl_;
};
class CV_EXPORTS BestOf2NearestRangeMatcher : public BestOf2NearestMatcher
{
public:
BestOf2NearestRangeMatcher(int range_width = 5, bool try_use_gpu = false, float match_conf = 0.3f,
int num_matches_thresh1 = 6, int num_matches_thresh2 = 6);
void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
const cv::UMat &mask = cv::UMat());
protected:
int range_width_;
};
/** @brief Features matcher similar to cv::detail::BestOf2NearestMatcher which
finds two best matches for each feature and leaves the best one only if the
ratio between descriptor distances is greater than the threshold match_conf.
Unlike cv::detail::BestOf2NearestMatcher this matcher uses affine
transformation (affine trasformation estimate will be placed in matches_info).
@sa cv::detail::FeaturesMatcher cv::detail::BestOf2NearestMatcher
*/
class CV_EXPORTS AffineBestOf2NearestMatcher : public BestOf2NearestMatcher
{
public:
/** @brief Constructs a "best of 2 nearest" matcher that expects affine trasformation
between images
@param full_affine whether to use full affine transformation with 6 degress of freedom or reduced
transformation with 4 degrees of freedom using only rotation, translation and uniform scaling
@param try_use_gpu Should try to use GPU or not
@param match_conf Match distances ration threshold
@param num_matches_thresh1 Minimum number of matches required for the 2D affine transform
estimation used in the inliers classification step
@sa cv::estimateAffine2D cv::estimateAffinePartial2D
*/
AffineBestOf2NearestMatcher(bool full_affine = false, bool try_use_gpu = false,
float match_conf = 0.3f, int num_matches_thresh1 = 6) :
BestOf2NearestMatcher(try_use_gpu, match_conf, num_matches_thresh1, num_matches_thresh1),
full_affine_(full_affine) {}
protected:
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
bool full_affine_;
};
//! @} stitching_match
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_MATCHERS_HPP__
#endif // OPENCV_STITCHING_MATCHERS_HPP
@@ -40,10 +40,10 @@
//
//M*/
#ifndef __OPENCV_STITCHING_MOTION_ESTIMATORS_HPP__
#define __OPENCV_STITCHING_MOTION_ESTIMATORS_HPP__
#ifndef OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
#define OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
#include "opencv2/core/core.hpp"
#include "opencv2/core.hpp"
#include "matchers.hpp"
#include "util.hpp"
#include "camera.hpp"
@@ -51,21 +51,50 @@
namespace cv {
namespace detail {
//! @addtogroup stitching_rotation
//! @{
/** @brief Rotation estimator base class.
It takes features of all images, pairwise matches between all images and estimates rotations of all
cameras.
@note The coordinate system origin is implementation-dependent, but you can always normalize the
rotations in respect to the first camera, for instance. :
*/
class CV_EXPORTS Estimator
{
public:
virtual ~Estimator() {}
void operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
/** @brief Estimates camera parameters.
@param features Features of images
@param pairwise_matches Pairwise matches of images
@param cameras Estimated camera parameters
@return True in case of success, false otherwise
*/
bool operator ()(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
{ estimate(features, pairwise_matches, cameras); }
{ return estimate(features, pairwise_matches, cameras); }
protected:
virtual void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
/** @brief This method must implement camera parameters estimation logic in order to make the wrapper
detail::Estimator::operator()_ work.
@param features Features of images
@param pairwise_matches Pairwise matches of images
@param cameras Estimated camera parameters
@return True in case of success, false otherwise
*/
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) = 0;
};
/** @brief Homography based rotation estimator.
*/
class CV_EXPORTS HomographyBasedEstimator : public Estimator
{
public:
@@ -73,13 +102,30 @@ public:
: is_focals_estimated_(is_focals_estimated) {}
private:
void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
bool is_focals_estimated_;
};
/** @brief Affine transformation based estimator.
This estimator uses pairwise tranformations estimated by matcher to estimate
final transformation for each camera.
@sa cv::detail::HomographyBasedEstimator
*/
class CV_EXPORTS AffineBasedEstimator : public Estimator
{
private:
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
};
/** @brief Base class for all camera parameters refinement methods.
*/
class CV_EXPORTS BundleAdjusterBase : public Estimator
{
public:
@@ -93,27 +139,49 @@ public:
double confThresh() const { return conf_thresh_; }
void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
CvTermCriteria termCriteria() { return term_criteria_; }
void setTermCriteria(const CvTermCriteria& term_criteria) { term_criteria_ = term_criteria; }
TermCriteria termCriteria() { return term_criteria_; }
void setTermCriteria(const TermCriteria& term_criteria) { term_criteria_ = term_criteria; }
protected:
/** @brief Construct a bundle adjuster base instance.
@param num_params_per_cam Number of parameters per camera
@param num_errs_per_measurement Number of error terms (components) per match
*/
BundleAdjusterBase(int num_params_per_cam, int num_errs_per_measurement)
: num_params_per_cam_(num_params_per_cam),
num_errs_per_measurement_(num_errs_per_measurement)
{
setRefinementMask(Mat::ones(3, 3, CV_8U));
setConfThresh(1.);
setTermCriteria(cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 1000, DBL_EPSILON));
setTermCriteria(TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 1000, DBL_EPSILON));
}
// Runs bundle adjustment
virtual void estimate(const std::vector<ImageFeatures> &features,
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
/** @brief Sets initial camera parameter to refine.
@param cameras Camera parameters
*/
virtual void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) = 0;
/** @brief Gets the refined camera parameters.
@param cameras Refined camera parameters
*/
virtual void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const = 0;
/** @brief Calculates error vector.
@param err Error column-vector of length total_num_matches \* num_errs_per_measurement
*/
virtual void calcError(Mat &err) = 0;
/** @brief Calculates the cost function jacobian.
@param jac Jacobian matrix of dimensions
(total_num_matches \* num_errs_per_measurement) x (num_images \* num_params_per_cam)
*/
virtual void calcJacobian(Mat &jac) = 0;
// 3x3 8U mask, where 0 means don't refine respective parameter, != 0 means refine
@@ -132,7 +200,7 @@ protected:
double conf_thresh_;
//Levenberg–Marquardt algorithm termination criteria
CvTermCriteria term_criteria_;
TermCriteria term_criteria_;
// Camera parameters matrix (CV_64F)
Mat cam_params_;
@@ -142,9 +210,32 @@ protected:
};
// Minimizes reprojection error.
// It can estimate focal length, aspect ratio, principal point.
// You can affect only on them via the refinement mask.
/** @brief Stub bundle adjuster that does nothing.
*/
class CV_EXPORTS NoBundleAdjuster : public BundleAdjusterBase
{
public:
NoBundleAdjuster() : BundleAdjusterBase(0, 0) {}
private:
bool estimate(const std::vector<ImageFeatures> &, const std::vector<MatchesInfo> &,
std::vector<CameraParams> &)
{
return true;
}
void setUpInitialCameraParams(const std::vector<CameraParams> &) {}
void obtainRefinedCameraParams(std::vector<CameraParams> &) const {}
void calcError(Mat &) {}
void calcJacobian(Mat &) {}
};
/** @brief Implementation of the camera parameters refinement algorithm which minimizes sum of the reprojection
error squares
It can estimate focal length, aspect ratio, principal point.
You can affect only on them via the refinement mask.
*/
class CV_EXPORTS BundleAdjusterReproj : public BundleAdjusterBase
{
public:
@@ -160,8 +251,11 @@ private:
};
// Minimizes sun of ray-to-ray distances.
// It can estimate focal length. It ignores the refinement mask for now.
/** @brief Implementation of the camera parameters refinement algorithm which minimizes sum of the distances
between the rays passing through the camera center and a feature. :
It can estimate focal length. It ignores the refinement mask for now.
*/
class CV_EXPORTS BundleAdjusterRay : public BundleAdjusterBase
{
public:
@@ -177,12 +271,65 @@ private:
};
/** @brief Bundle adjuster that expects affine transformation
represented in homogeneous coordinates in R for each camera param. Implements
camera parameters refinement algorithm which minimizes sum of the reprojection
error squares
It estimates all transformation parameters. Refinement mask is ignored.
@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffinePartial
*/
class CV_EXPORTS BundleAdjusterAffine : public BundleAdjusterBase
{
public:
BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras);
void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const;
void calcError(Mat &err);
void calcJacobian(Mat &jac);
Mat err1_, err2_;
};
/** @brief Bundle adjuster that expects affine transformation with 4 DOF
represented in homogeneous coordinates in R for each camera param. Implements
camera parameters refinement algorithm which minimizes sum of the reprojection
error squares
It estimates all transformation parameters. Refinement mask is ignored.
@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffine
*/
class CV_EXPORTS BundleAdjusterAffinePartial : public BundleAdjusterBase
{
public:
BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras);
void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const;
void calcError(Mat &err);
void calcJacobian(Mat &jac);
Mat err1_, err2_;
};
enum WaveCorrectKind
{
WAVE_CORRECT_HORIZ,
WAVE_CORRECT_VERT
};
/** @brief Tries to make panorama more horizontal (or vertical).
@param rmats Camera rotation matrices.
@param kind Correction kind, see detail::WaveCorrectKind.
*/
void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind);
@@ -190,16 +337,21 @@ void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind);
// Auxiliary functions
// Returns matches graph representation in DOT language
std::string CV_EXPORTS matchesGraphAsString(std::vector<std::string> &pathes, std::vector<MatchesInfo> &pairwise_matches,
String CV_EXPORTS matchesGraphAsString(std::vector<String> &pathes, std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
std::vector<int> CV_EXPORTS leaveBiggestComponent(std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
std::vector<int> CV_EXPORTS leaveBiggestComponent(
std::vector<ImageFeatures> &features,
std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
void CV_EXPORTS findMaxSpanningTree(int num_images, const std::vector<MatchesInfo> &pairwise_matches,
Graph &span_tree, std::vector<int> &centers);
void CV_EXPORTS findMaxSpanningTree(
int num_images, const std::vector<MatchesInfo> &pairwise_matches,
Graph &span_tree, std::vector<int> &centers);
//! @} stitching_rotation
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_MOTION_ESTIMATORS_HPP__
#endif // OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
@@ -40,54 +40,76 @@
//
//M*/
#ifndef __OPENCV_STITCHING_SEAM_FINDERS_HPP__
#define __OPENCV_STITCHING_SEAM_FINDERS_HPP__
#ifndef OPENCV_STITCHING_SEAM_FINDERS_HPP
#define OPENCV_STITCHING_SEAM_FINDERS_HPP
#include <set>
#include "opencv2/core/core.hpp"
#include "opencv2/core.hpp"
#include "opencv2/opencv_modules.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching_seam
//! @{
/** @brief Base class for a seam estimator.
*/
class CV_EXPORTS SeamFinder
{
public:
virtual ~SeamFinder() {}
virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
std::vector<Mat> &masks) = 0;
/** @brief Estimates seams.
@param src Source images
@param corners Source image top-left corners
@param masks Source image masks to update
*/
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) = 0;
};
/** @brief Stub seam estimator which does nothing.
*/
class CV_EXPORTS NoSeamFinder : public SeamFinder
{
public:
void find(const std::vector<Mat>&, const std::vector<Point>&, std::vector<Mat>&) {}
void find(const std::vector<UMat>&, const std::vector<Point>&, std::vector<UMat>&) {}
};
/** @brief Base class for all pairwise seam estimators.
*/
class CV_EXPORTS PairwiseSeamFinder : public SeamFinder
{
public:
virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
std::vector<Mat> &masks);
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks);
protected:
void run();
/** @brief Resolves masks intersection of two specified images in the given ROI.
@param first First image index
@param second Second image index
@param roi Region of interest
*/
virtual void findInPair(size_t first, size_t second, Rect roi) = 0;
std::vector<Mat> images_;
std::vector<UMat> images_;
std::vector<Size> sizes_;
std::vector<Point> corners_;
std::vector<Mat> masks_;
std::vector<UMat> masks_;
};
/** @brief Voronoi diagram-based seam estimator.
*/
class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder
{
public:
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks);
virtual void find(const std::vector<Size> &size, const std::vector<Point> &corners,
std::vector<Mat> &masks);
std::vector<UMat> &masks);
private:
void findInPair(size_t first, size_t second, Rect roi);
};
@@ -103,8 +125,8 @@ public:
CostFunction costFunction() const { return costFunc_; }
void setCostFunction(CostFunction val) { costFunc_ = val; }
virtual void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
std::vector<Mat> &masks);
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks);
private:
enum ComponentState
@@ -154,7 +176,7 @@ private:
};
void process(
const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
void findComponents();
@@ -201,14 +223,16 @@ private:
std::set<std::pair<int, int> > edges_;
};
/** @brief Base class for all minimum graph-cut-based seam estimators.
*/
class CV_EXPORTS GraphCutSeamFinderBase
{
public:
enum { COST_COLOR, COST_COLOR_GRAD };
enum CostType { COST_COLOR, COST_COLOR_GRAD };
};
/** @brief Minimum graph cut-based seam estimator. See details in @cite V03 .
*/
class CV_EXPORTS GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
{
public:
@@ -217,8 +241,8 @@ public:
~GraphCutSeamFinder();
void find(const std::vector<Mat> &src, const std::vector<Point> &corners,
std::vector<Mat> &masks);
void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks);
private:
// To avoid GCGraph dependency
@@ -227,7 +251,7 @@ private:
};
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
#ifdef HAVE_OPENCV_CUDALEGACY
class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
{
public:
@@ -236,8 +260,8 @@ public:
: cost_type_(cost_type), terminal_cost_(terminal_cost),
bad_region_penalty_(bad_region_penalty) {}
void find(const std::vector<cv::Mat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::Mat> &masks);
void find(const std::vector<cv::UMat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::UMat> &masks);
void findInPair(size_t first, size_t second, Rect roi);
private:
@@ -253,7 +277,9 @@ private:
};
#endif
//! @}
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_SEAM_FINDERS_HPP__
#endif // OPENCV_STITCHING_SEAM_FINDERS_HPP
@@ -0,0 +1,91 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 Intel Corporation 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.
//
//M*/
#ifndef OPENCV_STITCHING_TIMELAPSERS_HPP
#define OPENCV_STITCHING_TIMELAPSERS_HPP
#include "opencv2/core.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching
//! @{
// Base Timelapser class, takes a sequence of images, applies appropriate shift, stores result in dst_.
class CV_EXPORTS Timelapser
{
public:
enum {AS_IS, CROP};
virtual ~Timelapser() {}
static Ptr<Timelapser> createDefault(int type);
virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
virtual void process(InputArray img, InputArray mask, Point tl);
virtual const UMat& getDst() {return dst_;}
protected:
virtual bool test_point(Point pt);
UMat dst_;
Rect dst_roi_;
};
class CV_EXPORTS TimelapserCrop : public Timelapser
{
public:
virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
};
//! @}
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_TIMELAPSERS_HPP
+11 -52
View File
@@ -40,62 +40,18 @@
//
//M*/
#ifndef __OPENCV_STITCHING_UTIL_HPP__
#define __OPENCV_STITCHING_UTIL_HPP__
#ifndef OPENCV_STITCHING_UTIL_HPP
#define OPENCV_STITCHING_UTIL_HPP
#include <list>
#include "opencv2/core/core.hpp"
#define ENABLE_LOG 0
// TODO remove LOG macros, add logging class
#if ENABLE_LOG
#ifdef ANDROID
#include <iostream>
#include <sstream>
#include <android/log.h>
#define LOG_STITCHING_MSG(msg) \
do { \
std::stringstream _os; \
_os << msg; \
__android_log_print(ANDROID_LOG_DEBUG, "STITCHING", "%s", _os.str().c_str()); \
} while(0);
#else
#include <iostream>
#define LOG_STITCHING_MSG(msg) for(;;) { std::cout << msg; std::cout.flush(); break; }
#endif
#else
#define LOG_STITCHING_MSG(msg)
#endif
#define LOG_(_level, _msg) \
for(;;) \
{ \
if ((_level) >= ::cv::detail::stitchingLogLevel()) \
{ \
LOG_STITCHING_MSG(_msg); \
} \
break; \
}
#define LOG(msg) LOG_(1, msg)
#define LOG_CHAT(msg) LOG_(0, msg)
#define LOGLN(msg) LOG(msg << std::endl)
#define LOGLN_CHAT(msg) LOG_CHAT(msg << std::endl)
//#if DEBUG_LOG_CHAT
// #define LOG_CHAT(msg) LOG(msg)
// #define LOGLN_CHAT(msg) LOGLN(msg)
//#else
// #define LOG_CHAT(msg) do{}while(0)
// #define LOGLN_CHAT(msg) do{}while(0)
//#endif
#include "opencv2/core.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching
//! @{
class CV_EXPORTS DisjointSets
{
public:
@@ -145,8 +101,9 @@ private:
// Auxiliary functions
CV_EXPORTS bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi);
CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<Mat> &images);
CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images);
CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS Rect resultRoiIntersection(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS Point resultTl(const std::vector<Point> &corners);
// Returns random 'count' element subset of the {0,1,...,size-1} set
@@ -154,9 +111,11 @@ CV_EXPORTS void selectRandomSubset(int count, int size, std::vector<int> &subset
CV_EXPORTS int& stitchingLogLevel();
//! @}
} // namespace detail
} // namespace cv
#include "util_inl.hpp"
#endif // __OPENCV_STITCHING_UTIL_HPP__
#endif // OPENCV_STITCHING_UTIL_HPP
@@ -40,13 +40,15 @@
//
//M*/
#ifndef __OPENCV_STITCHING_UTIL_INL_HPP__
#define __OPENCV_STITCHING_UTIL_INL_HPP__
#ifndef OPENCV_STITCHING_UTIL_INL_HPP
#define OPENCV_STITCHING_UTIL_INL_HPP
#include <queue>
#include "opencv2/core/core.hpp"
#include "opencv2/core.hpp"
#include "util.hpp" // Make your IDE see declarations
//! @cond IGNORED
namespace cv {
namespace detail {
@@ -124,4 +126,6 @@ static inline double sqr(double x) { return x * x; }
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_UTIL_INL_HPP__
//! @endcond
#endif // OPENCV_STITCHING_UTIL_INL_HPP
+170 -69
View File
@@ -40,46 +40,92 @@
//
//M*/
#ifndef __OPENCV_STITCHING_WARPERS_HPP__
#define __OPENCV_STITCHING_WARPERS_HPP__
#ifndef OPENCV_STITCHING_WARPERS_HPP
#define OPENCV_STITCHING_WARPERS_HPP
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core.hpp"
#include "opencv2/core/cuda.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv_modules.hpp"
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
# include "opencv2/gpu/gpu.hpp"
#endif
namespace cv {
namespace detail {
//! @addtogroup stitching_warp
//! @{
/** @brief Rotation-only model image warper interface.
*/
class CV_EXPORTS RotationWarper
{
public:
virtual ~RotationWarper() {}
virtual Point2f warpPoint(const Point2f &pt, const Mat &K, const Mat &R) = 0;
/** @brief Projects the image point.
virtual Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap) = 0;
@param pt Source point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Projected point
*/
virtual Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) = 0;
virtual Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst) = 0;
/** @brief Builds the projection maps according to the given camera data.
virtual void warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Size dst_size, Mat &dst) = 0;
@param src_size Source image size
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@param xmap Projection map for the x axis
@param ymap Projection map for the y axis
@return Projected image minimum bounding box
*/
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) = 0;
virtual Rect warpRoi(Size src_size, const Mat &K, const Mat &R) = 0;
/** @brief Projects the image.
float getScale() const { return 1.f; }
void setScale(float) {}
@param src Source image
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@param interp_mode Interpolation mode
@param border_mode Border extrapolation mode
@param dst Projected image
@return Project image top-left corner
*/
virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst) = 0;
/** @brief Projects the image backward.
@param src Projected image
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@param interp_mode Interpolation mode
@param border_mode Border extrapolation mode
@param dst_size Backward-projected image size
@param dst Backward-projected image
*/
virtual void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, OutputArray dst) = 0;
/**
@param src_size Source image bounding box
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Projected image minimum bounding box
*/
virtual Rect warpRoi(Size src_size, InputArray K, InputArray R) = 0;
virtual float getScale() const { return 1.f; }
virtual void setScale(float) {}
};
/** @brief Base class for warping logic implementation.
*/
struct CV_EXPORTS ProjectorBase
{
void setCameraParams(const Mat &K = Mat::eye(3, 3, CV_32F),
const Mat &R = Mat::eye(3, 3, CV_32F),
const Mat &T = Mat::zeros(3, 1, CV_32F));
void setCameraParams(InputArray K = Mat::eye(3, 3, CV_32F),
InputArray R = Mat::eye(3, 3, CV_32F),
InputArray T = Mat::zeros(3, 1, CV_32F));
float scale;
float k[9];
@@ -89,22 +135,23 @@ struct CV_EXPORTS ProjectorBase
float t[3];
};
/** @brief Base class for rotation-based warper using a detail::ProjectorBase_ derived class.
*/
template <class P>
class CV_EXPORTS RotationWarperBase : public RotationWarper
{
public:
Point2f warpPoint(const Point2f &pt, const Mat &K, const Mat &R);
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst);
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst);
void warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Size dst_size, Mat &dst);
void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, OutputArray dst);
Rect warpRoi(Size src_size, const Mat &K, const Mat &R);
Rect warpRoi(Size src_size, InputArray K, InputArray R);
float getScale() const { return projector_.scale; }
void setScale(float val) { projector_.scale = val; }
@@ -128,28 +175,64 @@ struct CV_EXPORTS PlaneProjector : ProjectorBase
void mapBackward(float u, float v, float &x, float &y);
};
/** @brief Warper that maps an image onto the z = 1 plane.
*/
class CV_EXPORTS PlaneWarper : public RotationWarperBase<PlaneProjector>
{
public:
/** @brief Construct an instance of the plane warper class.
@param scale Projected image scale multiplier
*/
PlaneWarper(float scale = 1.f) { projector_.scale = scale; }
void setScale(float scale) { projector_.scale = scale; }
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T);
Point2f warpPoint(const Point2f &pt, const Mat &K, const Mat &R, const Mat &T);
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, Mat &xmap, Mat &ymap);
Point warp(InputArray src, InputArray K, InputArray R,
int interp_mode, int border_mode, OutputArray dst);
virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
OutputArray dst);
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
Mat &dst);
Rect warpRoi(Size src_size, const Mat &K, const Mat &R, const Mat &T);
Rect warpRoi(Size src_size, InputArray K, InputArray R);
Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T);
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
};
/** @brief Affine warper that uses rotations and translations
Uses affine transformation in homogeneous coordinates to represent both rotation and
translation in camera rotation matrix.
*/
class CV_EXPORTS AffineWarper : public PlaneWarper
{
public:
/** @brief Construct an instance of the affine warper class.
@param scale Projected image scale multiplier
*/
AffineWarper(float scale = 1.f) : PlaneWarper(scale) {}
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
Point warp(InputArray src, InputArray K, InputArray R,
int interp_mode, int border_mode, OutputArray dst);
Rect warpRoi(Size src_size, InputArray K, InputArray R);
protected:
/** @brief Extracts rotation and translation matrices from matrix H representing
affine transformation in homogeneous coordinates
*/
void getRTfromHomogeneous(InputArray H, Mat &R, Mat &T);
};
struct CV_EXPORTS SphericalProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
@@ -157,13 +240,24 @@ struct CV_EXPORTS SphericalProjector : ProjectorBase
};
// Projects image onto unit sphere with origin at (0, 0, 0).
// Poles are located at (0, -1, 0) and (0, 1, 0) points.
/** @brief Warper that maps an image onto the unit sphere located at the origin.
Projects image onto unit sphere with origin at (0, 0, 0) and radius scale, measured in pixels.
A 360° panorama would therefore have a resulting width of 2 * scale * PI pixels.
Poles are located at (0, -1, 0) and (0, 1, 0) points.
*/
class CV_EXPORTS SphericalWarper : public RotationWarperBase<SphericalProjector>
{
public:
/** @brief Construct an instance of the spherical warper class.
@param scale Radius of the projected sphere, in pixels. An image spanning the
whole sphere will have a width of 2 * scale * PI pixels.
*/
SphericalWarper(float scale) { projector_.scale = scale; }
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
};
@@ -176,12 +270,19 @@ struct CV_EXPORTS CylindricalProjector : ProjectorBase
};
// Projects image onto x * x + z * z = 1 cylinder
/** @brief Warper that maps an image onto the x\*x + z\*z = 1 cylinder.
*/
class CV_EXPORTS CylindricalWarper : public RotationWarperBase<CylindricalProjector>
{
public:
/** @brief Construct an instance of the cylindrical warper class.
@param scale Projected image scale multiplier
*/
CylindricalWarper(float scale) { projector_.scale = scale; }
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
{
@@ -331,13 +432,12 @@ public:
};
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
{
public:
PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
{
Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
@@ -345,7 +445,7 @@ public:
return result;
}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, Mat &xmap, Mat &ymap)
Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap)
{
Rect result = buildMaps(src_size, K, R, T, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
@@ -353,8 +453,8 @@ public:
return result;
}
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst)
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
@@ -362,8 +462,8 @@ public:
return result;
}
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
Mat &dst)
Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
OutputArray dst)
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, T, interp_mode, border_mode, d_dst_);
@@ -371,18 +471,18 @@ public:
return result;
}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
gpu::GpuMat &dst);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
cuda::GpuMat & dst);
Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
gpu::GpuMat &dst);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
cuda::GpuMat & dst);
private:
gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
};
@@ -391,7 +491,7 @@ class CV_EXPORTS SphericalWarperGpu : public SphericalWarper
public:
SphericalWarperGpu(float scale) : SphericalWarper(scale) {}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
{
Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
@@ -399,8 +499,8 @@ public:
return result;
}
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst)
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
@@ -408,13 +508,13 @@ public:
return result;
}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
gpu::GpuMat &dst);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
cuda::GpuMat & dst);
private:
gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
};
@@ -423,7 +523,7 @@ class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper
public:
CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
{
Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
@@ -431,8 +531,8 @@ public:
return result;
}
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst)
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
@@ -440,15 +540,14 @@ public:
return result;
}
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Point warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
gpu::GpuMat &dst);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
cuda::GpuMat & dst);
private:
gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
};
#endif
struct SphericalPortraitProjector : ProjectorBase
@@ -507,9 +606,11 @@ protected:
}
};
//! @} stitching_warp
} // namespace detail
} // namespace cv
#include "warpers_inl.hpp"
#endif // __OPENCV_STITCHING_WARPERS_HPP__
#endif // OPENCV_STITCHING_WARPERS_HPP
@@ -40,17 +40,20 @@
//
//M*/
#ifndef __OPENCV_STITCHING_WARPERS_INL_HPP__
#define __OPENCV_STITCHING_WARPERS_INL_HPP__
#ifndef OPENCV_STITCHING_WARPERS_INL_HPP
#define OPENCV_STITCHING_WARPERS_INL_HPP
#include "opencv2/core/core.hpp"
#include "opencv2/core.hpp"
#include "warpers.hpp" // Make your IDE see declarations
#include <limits>
//! @cond IGNORED
namespace cv {
namespace detail {
template <class P>
Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, const Mat &K, const Mat &R)
Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, InputArray K, InputArray R)
{
projector_.setCameraParams(K, R);
Point2f uv;
@@ -60,15 +63,17 @@ Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, const Mat &K, const
template <class P>
Rect RotationWarperBase<P>::buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)
{
projector_.setCameraParams(K, R);
Point dst_tl, dst_br;
detectResultRoi(src_size, dst_tl, dst_br);
xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
_xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
_ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
float x, y;
for (int v = dst_tl.y; v <= dst_br.y; ++v)
@@ -86,10 +91,10 @@ Rect RotationWarperBase<P>::buildMaps(Size src_size, const Mat &K, const Mat &R,
template <class P>
Point RotationWarperBase<P>::warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst)
{
Mat xmap, ymap;
UMat xmap, ymap;
Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
@@ -100,14 +105,16 @@ Point RotationWarperBase<P>::warp(const Mat &src, const Mat &K, const Mat &R, in
template <class P>
void RotationWarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Size dst_size, Mat &dst)
void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, OutputArray dst)
{
projector_.setCameraParams(K, R);
Point src_tl, src_br;
detectResultRoi(dst_size, src_tl, src_br);
CV_Assert(src_br.x - src_tl.x + 1 == src.cols && src_br.y - src_tl.y + 1 == src.rows);
Size size = src.size();
CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);
Mat xmap(dst_size, CV_32F);
Mat ymap(dst_size, CV_32F);
@@ -129,7 +136,7 @@ void RotationWarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat
template <class P>
Rect RotationWarperBase<P>::warpRoi(Size src_size, const Mat &K, const Mat &R)
Rect RotationWarperBase<P>::warpRoi(Size src_size, InputArray K, InputArray R)
{
projector_.setCameraParams(K, R);
@@ -143,10 +150,10 @@ Rect RotationWarperBase<P>::warpRoi(Size src_size, const Mat &K, const Mat &R)
template <class P>
void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
{
float tl_uf = std::numeric_limits<float>::max();
float tl_vf = std::numeric_limits<float>::max();
float br_uf = -std::numeric_limits<float>::max();
float br_vf = -std::numeric_limits<float>::max();
float tl_uf = (std::numeric_limits<float>::max)();
float tl_vf = (std::numeric_limits<float>::max)();
float br_uf = -(std::numeric_limits<float>::max)();
float br_vf = -(std::numeric_limits<float>::max)();
float u, v;
for (int y = 0; y < src_size.height; ++y)
@@ -154,8 +161,8 @@ void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point
for (int x = 0; x < src_size.width; ++x)
{
projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
}
}
@@ -169,31 +176,31 @@ void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point
template <class P>
void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
{
float tl_uf = std::numeric_limits<float>::max();
float tl_vf = std::numeric_limits<float>::max();
float br_uf = -std::numeric_limits<float>::max();
float br_vf = -std::numeric_limits<float>::max();
float tl_uf = (std::numeric_limits<float>::max)();
float tl_vf = (std::numeric_limits<float>::max)();
float br_uf = -(std::numeric_limits<float>::max)();
float br_vf = -(std::numeric_limits<float>::max)();
float u, v;
for (float x = 0; x < src_size.width; ++x)
{
projector_.mapForward(static_cast<float>(x), 0, u, v);
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
}
for (int y = 0; y < src_size.height; ++y)
{
projector_.mapForward(0, static_cast<float>(y), u, v);
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
}
dst_tl.x = static_cast<int>(tl_uf);
@@ -762,4 +769,6 @@ void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
} // namespace detail
} // namespace cv
#endif // __OPENCV_STITCHING_WARPERS_INL_HPP__
//! @endcond
#endif // OPENCV_STITCHING_WARPERS_INL_HPP
-174
View File
@@ -1,174 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's 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.
//
// * The name of the copyright holders may not 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 Intel Corporation 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.
//
//M*/
#ifndef __OPENCV_STITCHING_STITCHER_HPP__
#define __OPENCV_STITCHING_STITCHER_HPP__
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/stitching/warpers.hpp"
#include "opencv2/stitching/detail/matchers.hpp"
#include "opencv2/stitching/detail/motion_estimators.hpp"
#include "opencv2/stitching/detail/exposure_compensate.hpp"
#include "opencv2/stitching/detail/seam_finders.hpp"
#include "opencv2/stitching/detail/blenders.hpp"
#include "opencv2/stitching/detail/camera.hpp"
namespace cv {
class CV_EXPORTS Stitcher
{
public:
enum { ORIG_RESOL = -1 };
enum Status { OK, ERR_NEED_MORE_IMGS };
// Creates stitcher with default parameters
static Stitcher createDefault(bool try_use_gpu = false);
double registrationResol() const { return registr_resol_; }
void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
double seamEstimationResol() const { return seam_est_resol_; }
void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; }
double compositingResol() const { return compose_resol_; }
void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; }
double panoConfidenceThresh() const { return conf_thresh_; }
void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
bool waveCorrection() const { return do_wave_correct_; }
void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
Ptr<detail::FeaturesFinder> featuresFinder() { return features_finder_; }
const Ptr<detail::FeaturesFinder> featuresFinder() const { return features_finder_; }
void setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)
{ features_finder_ = features_finder; }
Ptr<detail::FeaturesMatcher> featuresMatcher() { return features_matcher_; }
const Ptr<detail::FeaturesMatcher> featuresMatcher() const { return features_matcher_; }
void setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)
{ features_matcher_ = features_matcher; }
const cv::Mat& matchingMask() const { return matching_mask_; }
void setMatchingMask(const cv::Mat &mask)
{
CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
matching_mask_ = mask.clone();
}
Ptr<detail::BundleAdjusterBase> bundleAdjuster() { return bundle_adjuster_; }
const Ptr<detail::BundleAdjusterBase> bundleAdjuster() const { return bundle_adjuster_; }
void setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
{ bundle_adjuster_ = bundle_adjuster; }
Ptr<WarperCreator> warper() { return warper_; }
const Ptr<WarperCreator> warper() const { return warper_; }
void setWarper(Ptr<WarperCreator> creator) { warper_ = creator; }
Ptr<detail::ExposureCompensator> exposureCompensator() { return exposure_comp_; }
const Ptr<detail::ExposureCompensator> exposureCompensator() const { return exposure_comp_; }
void setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)
{ exposure_comp_ = exposure_comp; }
Ptr<detail::SeamFinder> seamFinder() { return seam_finder_; }
const Ptr<detail::SeamFinder> seamFinder() const { return seam_finder_; }
void setSeamFinder(Ptr<detail::SeamFinder> seam_finder) { seam_finder_ = seam_finder; }
Ptr<detail::Blender> blender() { return blender_; }
const Ptr<detail::Blender> blender() const { return blender_; }
void setBlender(Ptr<detail::Blender> b) { blender_ = b; }
Status estimateTransform(InputArray images);
Status estimateTransform(InputArray images, const std::vector<std::vector<Rect> > &rois);
Status composePanorama(OutputArray pano);
Status composePanorama(InputArray images, OutputArray pano);
Status stitch(InputArray images, OutputArray pano);
Status stitch(InputArray images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
std::vector<int> component() const { return indices_; }
std::vector<detail::CameraParams> cameras() const { return cameras_; }
double workScale() const { return work_scale_; }
private:
Stitcher() {}
Status matchImages();
void estimateCameraParams();
double registr_resol_;
double seam_est_resol_;
double compose_resol_;
double conf_thresh_;
Ptr<detail::FeaturesFinder> features_finder_;
Ptr<detail::FeaturesMatcher> features_matcher_;
cv::Mat matching_mask_;
Ptr<detail::BundleAdjusterBase> bundle_adjuster_;
bool do_wave_correct_;
detail::WaveCorrectKind wave_correct_kind_;
Ptr<WarperCreator> warper_;
Ptr<detail::ExposureCompensator> exposure_comp_;
Ptr<detail::SeamFinder> seam_finder_;
Ptr<detail::Blender> blender_;
std::vector<cv::Mat> imgs_;
std::vector<std::vector<cv::Rect> > rois_;
std::vector<cv::Size> full_img_sizes_;
std::vector<detail::ImageFeatures> features_;
std::vector<detail::MatchesInfo> pairwise_matches_;
std::vector<cv::Mat> seam_est_imgs_;
std::vector<int> indices_;
std::vector<detail::CameraParams> cameras_;
double work_scale_;
double seam_scale_;
double seam_work_aspect_;
double warped_image_scale_;
};
} // namespace cv
#endif // __OPENCV_STITCHING_STITCHER_HPP__
+40 -20
View File
@@ -40,13 +40,18 @@
//
//M*/
#ifndef __OPENCV_STITCHING_WARPER_CREATORS_HPP__
#define __OPENCV_STITCHING_WARPER_CREATORS_HPP__
#ifndef OPENCV_STITCHING_WARPER_CREATORS_HPP
#define OPENCV_STITCHING_WARPER_CREATORS_HPP
#include "opencv2/stitching/detail/warpers.hpp"
namespace cv {
//! @addtogroup stitching_warp
//! @{
/** @brief Image warper factories base class.
*/
class WarperCreator
{
public:
@@ -54,37 +59,50 @@ public:
virtual Ptr<detail::RotationWarper> create(float scale) const = 0;
};
/** @brief Plane warper factory class.
@sa detail::PlaneWarper
*/
class PlaneWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PlaneWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PlaneWarper>(scale); }
};
/** @brief Affine warper factory class.
@sa detail::AffineWarper
*/
class AffineWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::AffineWarper>(scale); }
};
/** @brief Cylindrical warper factory class.
@sa detail::CylindricalWarper
*/
class CylindricalWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CylindricalWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CylindricalWarper>(scale); }
};
/** @brief Spherical warper factory class */
class SphericalWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::SphericalWarper>(scale); }
};
class FisheyeWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::FisheyeWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::FisheyeWarper>(scale); }
};
class StereographicWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::StereographicWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::StereographicWarper>(scale); }
};
class CompressedRectilinearWarper: public WarperCreator
@@ -95,7 +113,7 @@ public:
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CompressedRectilinearWarper(scale, a, b); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CompressedRectilinearWarper>(scale, a, b); }
};
class CompressedRectilinearPortraitWarper: public WarperCreator
@@ -106,7 +124,7 @@ public:
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CompressedRectilinearPortraitWarper(scale, a, b); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CompressedRectilinearPortraitWarper>(scale, a, b); }
};
class PaniniWarper: public WarperCreator
@@ -117,7 +135,7 @@ public:
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PaniniWarper(scale, a, b); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PaniniWarper>(scale, a, b); }
};
class PaniniPortraitWarper: public WarperCreator
@@ -128,45 +146,47 @@ public:
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PaniniPortraitWarper(scale, a, b); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PaniniPortraitWarper>(scale, a, b); }
};
class MercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::MercatorWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::MercatorWarper>(scale); }
};
class TransverseMercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::TransverseMercatorWarper(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::TransverseMercatorWarper>(scale); }
};
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
#ifdef HAVE_OPENCV_CUDAWARPING
class PlaneWarperGpu: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PlaneWarperGpu(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PlaneWarperGpu>(scale); }
};
class CylindricalWarperGpu: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CylindricalWarperGpu(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CylindricalWarperGpu>(scale); }
};
class SphericalWarperGpu: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarperGpu(scale); }
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::SphericalWarperGpu>(scale); }
};
#endif
//! @} stitching_warp
} // namespace cv
#endif // __OPENCV_STITCHING_WARPER_CREATORS_HPP__
#endif // OPENCV_STITCHING_WARPER_CREATORS_HPP