feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

@ -0,0 +1,357 @@
/*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.hpp"
#include "opencv2/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"
#if defined(Status)
# warning Detected X11 'Status' macro definition, it can cause build conflicts. Please, include this header before any X11 headers.
#endif
/**
@defgroup stitching Images stitching
This figure illustrates the stitching module pipeline implemented in the Stitcher class. Using that
class it's possible to configure/remove some steps, i.e. adjust the stitching pipeline according to
the particular needs. All building blocks from the pipeline are available in the detail namespace,
one can combine and use them separately.
The implemented stitching pipeline is very similar to the one proposed in @cite BL07 .
![stitching pipeline](StitchingPipeline.jpg)
Camera models
-------------
There are currently 2 camera models implemented in stitching pipeline.
- _Homography model_ expecting perspective transformations between images
implemented in @ref cv::detail::BestOf2NearestMatcher cv::detail::HomographyBasedEstimator
cv::detail::BundleAdjusterReproj cv::detail::BundleAdjusterRay
- _Affine model_ expecting affine transformation with 6 DOF or 4 DOF implemented in
@ref cv::detail::AffineBestOf2NearestMatcher cv::detail::AffineBasedEstimator
cv::detail::BundleAdjusterAffine cv::detail::BundleAdjusterAffinePartial cv::AffineWarper
Homography model is useful for creating photo panoramas captured by camera,
while affine-based model can be used to stitch scans and object captured by
specialized devices. Use @ref cv::Stitcher::create to get preconfigured pipeline for one
of those models.
@note
Certain detailed settings of @ref cv::Stitcher might not make sense. Especially
you should not mix classes implementing affine model and classes implementing
Homography model, as they work with different transformations.
@{
@defgroup stitching_match Features Finding and Images Matching
@defgroup stitching_rotation Rotation Estimation
@defgroup stitching_autocalib Autocalibration
@defgroup stitching_warp Images Warping
@defgroup stitching_seam Seam Estimation
@defgroup stitching_exposure Exposure Compensation
@defgroup stitching_blend Image Blenders
@}
*/
namespace cv {
//! @addtogroup stitching
//! @{
/** @example samples/cpp/stitching.cpp
A basic example on image stitching
*/
/** @example samples/python/stitching.py
A basic example on image stitching in Python.
*/
/** @example samples/cpp/stitching_detailed.cpp
A detailed example on image stitching
*/
/** @brief High level image stitcher.
It's possible to use this class without being aware of the entire stitching pipeline. However, to
be able to achieve higher stitching stability and quality of the final images at least being
familiar with the theory is recommended.
@note
- A basic example on image stitching can be found at
opencv_source_code/samples/cpp/stitching.cpp
- A basic example on image stitching in Python can be found at
opencv_source_code/samples/python/stitching.py
- A detailed example on image stitching can be found at
opencv_source_code/samples/cpp/stitching_detailed.cpp
*/
class CV_EXPORTS_W Stitcher
{
public:
/**
* When setting a resolution for stitching, this values is a placeholder
* for preserving the original resolution.
*/
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/)
static constexpr double ORIG_RESOL = -1.0;
#else
// support MSVS 2013
static const double ORIG_RESOL; // Initialized in stitcher.cpp
#endif
enum Status
{
OK = 0,
ERR_NEED_MORE_IMGS = 1,
ERR_HOMOGRAPHY_EST_FAIL = 2,
ERR_CAMERA_PARAMS_ADJUST_FAIL = 3
};
enum Mode
{
/** Mode for creating photo panoramas. Expects images under perspective
transformation and projects resulting pano to sphere.
@sa detail::BestOf2NearestMatcher SphericalWarper
*/
PANORAMA = 0,
/** Mode for composing scans. Expects images under affine transformation does
not compensate exposure by default.
@sa detail::AffineBestOf2NearestMatcher AffineWarper
*/
SCANS = 1,
};
/** @brief Creates a Stitcher configured in one of the stitching modes.
@param mode Scenario for stitcher operation. This is usually determined by source of images
to stitch and their transformation. Default parameters will be chosen for operation in given
scenario.
@return Stitcher class instance.
*/
CV_WRAP static Ptr<Stitcher> create(Mode mode = Stitcher::PANORAMA);
CV_WRAP double registrationResol() const { return registr_resol_; }
CV_WRAP void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
CV_WRAP double seamEstimationResol() const { return seam_est_resol_; }
CV_WRAP void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; }
CV_WRAP double compositingResol() const { return compose_resol_; }
CV_WRAP void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; }
CV_WRAP double panoConfidenceThresh() const { return conf_thresh_; }
CV_WRAP void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
CV_WRAP bool waveCorrection() const { return do_wave_correct_; }
CV_WRAP void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
CV_WRAP InterpolationFlags interpolationFlags() const { return interp_flags_; }
CV_WRAP void setInterpolationFlags(InterpolationFlags interp_flags) { interp_flags_ = interp_flags; }
detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
Ptr<Feature2D> featuresFinder() { return features_finder_; }
const Ptr<Feature2D> featuresFinder() const { return features_finder_; }
void setFeaturesFinder(Ptr<Feature2D> 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::UMat& matchingMask() const { return matching_mask_; }
void setMatchingMask(const cv::UMat &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<detail::Estimator> estimator() { return estimator_; }
const Ptr<detail::Estimator> estimator() const { return estimator_; }
void setEstimator(Ptr<detail::Estimator> estimator)
{ estimator_ = estimator; }
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; }
/** @brief These functions try to match the given images and to estimate rotations of each camera.
@note Use the functions only if you're aware of the stitching pipeline, otherwise use
Stitcher::stitch.
@param images Input images.
@param masks Masks for each input image specifying where to look for keypoints (optional).
@return Status code.
*/
CV_WRAP Status estimateTransform(InputArrayOfArrays images, InputArrayOfArrays masks = noArray());
/** @brief These function restors camera rotation and camera intrinsics of each camera
* that can be got with @ref Stitcher::cameras call
@param images Input images.
@param cameras Estimated rotation of cameras for each of the input images.
@param component Indices (0-based) of images constituting the final panorama (optional).
@return Status code.
*/
Status setTransform(InputArrayOfArrays images,
const std::vector<detail::CameraParams> &cameras,
const std::vector<int> &component);
/** @overload */
Status setTransform(InputArrayOfArrays images, const std::vector<detail::CameraParams> &cameras);
/** @overload */
CV_WRAP Status composePanorama(OutputArray pano);
/** @brief These functions try to compose the given images (or images stored internally from the other function
calls) into the final pano under the assumption that the image transformations were estimated
before.
@note Use the functions only if you're aware of the stitching pipeline, otherwise use
Stitcher::stitch.
@param images Input images.
@param pano Final pano.
@return Status code.
*/
CV_WRAP Status composePanorama(InputArrayOfArrays images, OutputArray pano);
/** @overload */
CV_WRAP Status stitch(InputArrayOfArrays images, OutputArray pano);
/** @brief These functions try to stitch the given images.
@param images Input images.
@param masks Masks for each input image specifying where to look for keypoints (optional).
@param pano Final pano.
@return Status code.
*/
CV_WRAP Status stitch(InputArrayOfArrays images, InputArrayOfArrays masks, OutputArray pano);
std::vector<int> component() const { return indices_; }
std::vector<detail::CameraParams> cameras() const { return cameras_; }
CV_WRAP double workScale() const { return work_scale_; }
UMat resultMask() const { return result_mask_; }
private:
Status matchImages();
Status estimateCameraParams();
double registr_resol_;
double seam_est_resol_;
double compose_resol_;
double conf_thresh_;
InterpolationFlags interp_flags_;
Ptr<Feature2D> features_finder_;
Ptr<detail::FeaturesMatcher> features_matcher_;
cv::UMat matching_mask_;
Ptr<detail::BundleAdjusterBase> bundle_adjuster_;
Ptr<detail::Estimator> estimator_;
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::UMat> imgs_;
std::vector<cv::UMat> masks_;
std::vector<cv::Size> full_img_sizes_;
std::vector<detail::ImageFeatures> features_;
std::vector<detail::MatchesInfo> pairwise_matches_;
std::vector<cv::UMat> seam_est_imgs_;
std::vector<int> indices_;
std::vector<detail::CameraParams> cameras_;
UMat result_mask_;
double work_scale_;
double seam_scale_;
double seam_work_aspect_;
double warped_image_scale_;
};
/**
* @deprecated use Stitcher::create
*/
CV_DEPRECATED Ptr<Stitcher> createStitcher(bool try_use_gpu = false);
/**
* @deprecated use Stitcher::create
*/
CV_DEPRECATED Ptr<Stitcher> createStitcherScans(bool try_use_gpu = false);
//! @} stitching
} // namespace cv
#endif // OPENCV_STITCHING_STITCHER_HPP

View File

@ -0,0 +1,86 @@
/*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_AUTOCALIB_HPP
#define OPENCV_STITCHING_AUTOCALIB_HPP
#include "opencv2/core.hpp"
#include "matchers.hpp"
namespace cv {
namespace detail {
//! @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_W 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_W calibrateRotatingCamera(const std::vector<Mat> &Hs,CV_OUT Mat &K);
//! @} stitching_autocalib
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_AUTOCALIB_HPP

View File

@ -0,0 +1,184 @@
/*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_BLENDERS_HPP
#define OPENCV_STITCHING_BLENDERS_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"
#include "opencv2/core/cuda.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching_blend
//! @{
/** @brief Base class for all blenders.
Simple blender which puts one image over another
*/
class CV_EXPORTS_W Blender
{
public:
virtual ~Blender() {}
enum { NO, FEATHER, MULTI_BAND };
CV_WRAP 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
*/
CV_WRAP virtual void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);
/** @overload */
CV_WRAP virtual void prepare(Rect dst_roi);
/** @brief Processes the image.
@param img Source image
@param mask Source image mask
@param tl Source image top-left corners
*/
CV_WRAP 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
*/
CV_WRAP virtual void blend(CV_IN_OUT InputOutputArray dst,CV_IN_OUT InputOutputArray dst_mask);
protected:
UMat dst_, dst_mask_;
Rect dst_roi_;
};
/** @brief Simple blender which mixes images at its borders.
*/
class CV_EXPORTS_W FeatherBlender : public Blender
{
public:
CV_WRAP FeatherBlender(float sharpness = 0.02f);
CV_WRAP float sharpness() const { return sharpness_; }
CV_WRAP void setSharpness(float val) { sharpness_ = val; }
CV_WRAP void prepare(Rect dst_roi) CV_OVERRIDE;
CV_WRAP void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE;
CV_WRAP void blend(InputOutputArray dst, InputOutputArray dst_mask) CV_OVERRIDE;
//! 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.
CV_WRAP Rect createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &weight_maps);
private:
float sharpness_;
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_W MultiBandBlender : public Blender
{
public:
CV_WRAP MultiBandBlender(int try_gpu = false, int num_bands = 5, int weight_type = CV_32F);
CV_WRAP int numBands() const { return actual_num_bands_; }
CV_WRAP void setNumBands(int val) { actual_num_bands_ = val; }
CV_WRAP void prepare(Rect dst_roi) CV_OVERRIDE;
CV_WRAP void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE;
CV_WRAP void blend(CV_IN_OUT InputOutputArray dst, CV_IN_OUT InputOutputArray dst_mask) CV_OVERRIDE;
private:
int actual_num_bands_, num_bands_;
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
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
std::vector<cuda::GpuMat> gpu_dst_pyr_laplace_;
std::vector<cuda::GpuMat> gpu_dst_band_weights_;
std::vector<Point> gpu_tl_points_;
std::vector<cuda::GpuMat> gpu_imgs_with_border_;
std::vector<std::vector<cuda::GpuMat> > gpu_weight_pyr_gauss_vec_;
std::vector<std::vector<cuda::GpuMat> > gpu_src_pyr_laplace_vec_;
std::vector<std::vector<cuda::GpuMat> > gpu_ups_;
cuda::GpuMat gpu_dst_mask_;
cuda::GpuMat gpu_mask_;
cuda::GpuMat gpu_img_;
cuda::GpuMat gpu_weight_map_;
cuda::GpuMat gpu_add_mask_;
int gpu_feed_idx_;
bool gpu_initialized_;
#endif
};
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
void CV_EXPORTS_W normalizeUsingWeightMap(InputArray weight, CV_IN_OUT InputOutputArray src);
void CV_EXPORTS_W createWeightMap(InputArray mask, float sharpness, CV_IN_OUT InputOutputArray weight);
void CV_EXPORTS_W createLaplacePyr(InputArray img, int num_levels, CV_IN_OUT std::vector<UMat>& pyr);
void CV_EXPORTS_W createLaplacePyrGpu(InputArray img, int num_levels, CV_IN_OUT std::vector<UMat>& pyr);
// Restores source image
void CV_EXPORTS_W restoreImageFromLaplacePyr(CV_IN_OUT std::vector<UMat>& pyr);
void CV_EXPORTS_W restoreImageFromLaplacePyrGpu(CV_IN_OUT std::vector<UMat>& pyr);
//! @}
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_BLENDERS_HPP

View File

@ -0,0 +1,78 @@
/*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_CAMERA_HPP
#define OPENCV_STITCHING_CAMERA_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_W_SIMPLE CameraParams
{
CameraParams();
CameraParams(const CameraParams& other);
CameraParams& operator =(const CameraParams& other);
CV_WRAP Mat K() const;
CV_PROP_RW double focal; // Focal length
CV_PROP_RW double aspect; // Aspect ratio
CV_PROP_RW double ppx; // Principal point X
CV_PROP_RW double ppy; // Principal point Y
CV_PROP_RW Mat R; // Rotation
CV_PROP_RW Mat t; // Translation
};
//! @}
} // namespace detail
} // namespace cv
#endif // #ifndef OPENCV_STITCHING_CAMERA_HPP

View File

@ -0,0 +1,245 @@
/*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_EXPOSURE_COMPENSATE_HPP
#define OPENCV_STITCHING_EXPOSURE_COMPENSATE_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_W ExposureCompensator
{
public:
ExposureCompensator(): updateGain(true) {}
virtual ~ExposureCompensator() {}
enum { NO, GAIN, GAIN_BLOCKS, CHANNELS, CHANNELS_BLOCKS };
CV_WRAP static Ptr<ExposureCompensator> createDefault(int type);
/**
@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)
*/
CV_WRAP 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
*/
CV_WRAP virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0;
CV_WRAP virtual void getMatGains(CV_OUT std::vector<Mat>& ) {CV_Error(Error::StsInternal, "");};
CV_WRAP virtual void setMatGains(std::vector<Mat>& ) { CV_Error(Error::StsInternal, ""); };
CV_WRAP void setUpdateGain(bool b) { updateGain = b; };
CV_WRAP bool getUpdateGain() { return updateGain; };
protected :
bool updateGain;
};
/** @brief Stub exposure compensator which does nothing.
*/
class CV_EXPORTS_W NoExposureCompensator : public ExposureCompensator
{
public:
void feed(const std::vector<Point> &/*corners*/, const std::vector<UMat> &/*images*/,
const std::vector<std::pair<UMat,uchar> > &/*masks*/) CV_OVERRIDE { }
CV_WRAP void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) CV_OVERRIDE { }
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE { umv.clear(); return; };
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE { umv.clear(); return; };
};
/** @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_W GainCompensator : public ExposureCompensator
{
public:
// This Constructor only exists to make source level compatibility detector happy
CV_WRAP GainCompensator()
: GainCompensator(1) {}
CV_WRAP GainCompensator(int nr_feeds)
: nr_feeds_(nr_feeds), similarity_threshold_(1) {}
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
void singleFeed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks);
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE ;
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE ;
CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; }
CV_WRAP int getNrFeeds() { return nr_feeds_; }
CV_WRAP void setSimilarityThreshold(double similarity_threshold) { similarity_threshold_ = similarity_threshold; }
CV_WRAP double getSimilarityThreshold() const { return similarity_threshold_; }
void prepareSimilarityMask(const std::vector<Point> &corners, const std::vector<UMat> &images);
std::vector<double> gains() const;
private:
UMat buildSimilarityMask(InputArray src_array1, InputArray src_array2);
Mat_<double> gains_;
int nr_feeds_;
double similarity_threshold_;
std::vector<UMat> similarities_;
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image
intensities on each channel independently.
*/
class CV_EXPORTS_W ChannelsCompensator : public ExposureCompensator
{
public:
CV_WRAP ChannelsCompensator(int nr_feeds=1)
: nr_feeds_(nr_feeds), similarity_threshold_(1) {}
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE;
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE;
CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; }
CV_WRAP int getNrFeeds() { return nr_feeds_; }
CV_WRAP void setSimilarityThreshold(double similarity_threshold) { similarity_threshold_ = similarity_threshold; }
CV_WRAP double getSimilarityThreshold() const { return similarity_threshold_; }
std::vector<Scalar> gains() const { return gains_; }
private:
std::vector<Scalar> gains_;
int nr_feeds_;
double similarity_threshold_;
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image blocks.
*/
class CV_EXPORTS_W BlocksCompensator : public ExposureCompensator
{
public:
BlocksCompensator(int bl_width=32, int bl_height=32, int nr_feeds=1)
: bl_width_(bl_width), bl_height_(bl_height), nr_feeds_(nr_feeds), nr_gain_filtering_iterations_(2),
similarity_threshold_(1) {}
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE;
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE;
CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; }
CV_WRAP int getNrFeeds() { return nr_feeds_; }
CV_WRAP void setSimilarityThreshold(double similarity_threshold) { similarity_threshold_ = similarity_threshold; }
CV_WRAP double getSimilarityThreshold() const { return similarity_threshold_; }
CV_WRAP void setBlockSize(int width, int height) { bl_width_ = width; bl_height_ = height; }
CV_WRAP void setBlockSize(Size size) { setBlockSize(size.width, size.height); }
CV_WRAP Size getBlockSize() const { return Size(bl_width_, bl_height_); }
CV_WRAP void setNrGainsFilteringIterations(int nr_iterations) { nr_gain_filtering_iterations_ = nr_iterations; }
CV_WRAP int getNrGainsFilteringIterations() const { return nr_gain_filtering_iterations_; }
protected:
template<class Compensator>
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks);
private:
UMat getGainMap(const GainCompensator& compensator, int bl_idx, Size bl_per_img);
UMat getGainMap(const ChannelsCompensator& compensator, int bl_idx, Size bl_per_img);
int bl_width_, bl_height_;
std::vector<UMat> gain_maps_;
int nr_feeds_;
int nr_gain_filtering_iterations_;
double similarity_threshold_;
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block
intensities, see @cite UES01 for details.
*/
class CV_EXPORTS_W BlocksGainCompensator : public BlocksCompensator
{
public:
// This Constructor only exists to make source level compatibility detector happy
CV_WRAP BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
: BlocksGainCompensator(bl_width, bl_height, 1) {}
CV_WRAP BlocksGainCompensator(int bl_width, int bl_height, int nr_feeds)
: BlocksCompensator(bl_width, bl_height, nr_feeds) {}
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
// This function only exists to make source level compatibility detector happy
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE {
BlocksCompensator::apply(index, corner, image, mask); }
// This function only exists to make source level compatibility detector happy
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE { BlocksCompensator::getMatGains(umv); }
// This function only exists to make source level compatibility detector happy
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE { BlocksCompensator::setMatGains(umv); }
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block
on each channel.
*/
class CV_EXPORTS_W BlocksChannelsCompensator : public BlocksCompensator
{
public:
CV_WRAP BlocksChannelsCompensator(int bl_width=32, int bl_height=32, int nr_feeds=1)
: BlocksCompensator(bl_width, bl_height, nr_feeds) {}
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
};
//! @}
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP

View File

@ -0,0 +1,253 @@
/*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_MATCHERS_HPP
#define OPENCV_STITCHING_MATCHERS_HPP
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/opencv_modules.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching_match
//! @{
/** @brief Structure containing image keypoints and descriptors. */
struct CV_EXPORTS_W_SIMPLE ImageFeatures
{
CV_PROP_RW int img_idx;
CV_PROP_RW Size img_size;
std::vector<KeyPoint> keypoints;
CV_PROP_RW UMat descriptors;
CV_WRAP std::vector<KeyPoint> getKeypoints() { return keypoints; };
};
/** @brief
@param featuresFinder
@param images
@param features
@param masks
*/
CV_EXPORTS_W void computeImageFeatures(
const Ptr<Feature2D> &featuresFinder,
InputArrayOfArrays images,
CV_OUT std::vector<ImageFeatures> &features,
InputArrayOfArrays masks = noArray());
/** @brief
@param featuresFinder
@param image
@param features
@param mask
*/
CV_EXPORTS_AS(computeImageFeatures2) void computeImageFeatures(
const Ptr<Feature2D> &featuresFinder,
InputArray image,
CV_OUT ImageFeatures &features,
InputArray mask = noArray());
/** @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_W_SIMPLE MatchesInfo
{
MatchesInfo();
MatchesInfo(const MatchesInfo &other);
MatchesInfo& operator =(const MatchesInfo &other);
CV_PROP_RW int src_img_idx;
CV_PROP_RW int dst_img_idx; //!< Images indices (optional)
std::vector<DMatch> matches;
std::vector<uchar> inliers_mask; //!< Geometrically consistent matches mask
CV_PROP_RW int num_inliers; //!< Number of geometrically consistent matches
CV_PROP_RW Mat H; //!< Estimated transformation
CV_PROP_RW double confidence; //!< Confidence two images are from the same panorama
CV_WRAP std::vector<DMatch> getMatches() { return matches; };
CV_WRAP std::vector<uchar> getInliers() { return inliers_mask; };
};
/** @brief Feature matchers base class. */
class CV_EXPORTS_W FeaturesMatcher
{
public:
CV_WRAP virtual ~FeaturesMatcher() {}
/** @overload
@param features1 First image features
@param features2 Second image features
@param matches_info Found matches
*/
CV_WRAP_AS(apply) void operator ()(const ImageFeatures &features1, const ImageFeatures &features2,
CV_OUT MatchesInfo& matches_info) { match(features1, features2, matches_info); }
/** @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
*/
CV_WRAP_AS(apply2) void operator ()(const std::vector<ImageFeatures> &features, CV_OUT 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
*/
CV_WRAP bool isThreadSafe() const { return is_thread_safe_; }
/** @brief Frees unused memory allocated before if there is any.
*/
CV_WRAP 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_W 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
*/
CV_WRAP BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
int num_matches_thresh2 = 6);
CV_WRAP void collectGarbage() CV_OVERRIDE;
CV_WRAP static Ptr<BestOf2NearestMatcher> create(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
int num_matches_thresh2 = 6);
protected:
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info) CV_OVERRIDE;
int num_matches_thresh1_;
int num_matches_thresh2_;
Ptr<FeaturesMatcher> impl_;
};
class CV_EXPORTS_W BestOf2NearestRangeMatcher : public BestOf2NearestMatcher
{
public:
CV_WRAP 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 transformation estimate will be placed in matches_info).
@sa cv::detail::FeaturesMatcher cv::detail::BestOf2NearestMatcher
*/
class CV_EXPORTS_W AffineBestOf2NearestMatcher : public BestOf2NearestMatcher
{
public:
/** @brief Constructs a "best of 2 nearest" matcher that expects affine transformation
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
*/
CV_WRAP 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) CV_OVERRIDE;
bool full_affine_;
};
//! @} stitching_match
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_MATCHERS_HPP

View File

@ -0,0 +1,373 @@
/*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_MOTION_ESTIMATORS_HPP
#define OPENCV_STITCHING_MOTION_ESTIMATORS_HPP
#include "opencv2/core.hpp"
#include "matchers.hpp"
#include "util.hpp"
#include "camera.hpp"
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_W Estimator
{
public:
virtual ~Estimator() {}
/** @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
*/
CV_WRAP_AS(apply) bool operator ()(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
CV_OUT CV_IN_OUT std::vector<CameraParams> &cameras)
{
return estimate(features, pairwise_matches, cameras);
}
protected:
/** @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,
CV_OUT std::vector<CameraParams> &cameras) = 0;
};
/** @brief Homography based rotation estimator.
*/
class CV_EXPORTS_W HomographyBasedEstimator : public Estimator
{
public:
CV_WRAP HomographyBasedEstimator(bool is_focals_estimated = false)
: is_focals_estimated_(is_focals_estimated) {}
private:
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) CV_OVERRIDE;
bool is_focals_estimated_;
};
/** @brief Affine transformation based estimator.
This estimator uses pairwise transformations estimated by matcher to estimate
final transformation for each camera.
@sa cv::detail::HomographyBasedEstimator
*/
class CV_EXPORTS_W AffineBasedEstimator : public Estimator
{
public:
CV_WRAP AffineBasedEstimator(){}
private:
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) CV_OVERRIDE;
};
/** @brief Base class for all camera parameters refinement methods.
*/
class CV_EXPORTS_W BundleAdjusterBase : public Estimator
{
public:
CV_WRAP const Mat refinementMask() const { return refinement_mask_.clone(); }
CV_WRAP void setRefinementMask(const Mat &mask)
{
CV_Assert(mask.type() == CV_8U && mask.size() == Size(3, 3));
refinement_mask_ = mask.clone();
}
CV_WRAP double confThresh() const { return conf_thresh_; }
CV_WRAP void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
CV_WRAP TermCriteria termCriteria() { return term_criteria_; }
CV_WRAP 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_images_(0), total_num_matches_(0),
num_params_per_cam_(num_params_per_cam),
num_errs_per_measurement_(num_errs_per_measurement),
features_(0), pairwise_matches_(0), conf_thresh_(0)
{
setRefinementMask(Mat::ones(3, 3, CV_8U));
setConfThresh(1.);
setTermCriteria(TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 1000, DBL_EPSILON));
}
// Runs bundle adjustment
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) CV_OVERRIDE;
/** @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
Mat refinement_mask_;
int num_images_;
int total_num_matches_;
int num_params_per_cam_;
int num_errs_per_measurement_;
const ImageFeatures *features_;
const MatchesInfo *pairwise_matches_;
// Threshold to filter out poorly matched image pairs
double conf_thresh_;
//Levenberg-Marquardt algorithm termination criteria
TermCriteria term_criteria_;
// Camera parameters matrix (CV_64F)
Mat cam_params_;
// Connected images pairs
std::vector<std::pair<int,int> > edges_;
};
/** @brief Stub bundle adjuster that does nothing.
*/
class CV_EXPORTS_W NoBundleAdjuster : public BundleAdjusterBase
{
public:
CV_WRAP NoBundleAdjuster() : BundleAdjusterBase(0, 0) {}
private:
bool estimate(const std::vector<ImageFeatures> &, const std::vector<MatchesInfo> &,
std::vector<CameraParams> &) CV_OVERRIDE
{
return true;
}
void setUpInitialCameraParams(const std::vector<CameraParams> &) CV_OVERRIDE {}
void obtainRefinedCameraParams(std::vector<CameraParams> &) const CV_OVERRIDE {}
void calcError(Mat &) CV_OVERRIDE {}
void calcJacobian(Mat &) CV_OVERRIDE {}
};
/** @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_W BundleAdjusterReproj : public BundleAdjusterBase
{
public:
CV_WRAP BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const CV_OVERRIDE;
void calcError(Mat &err) CV_OVERRIDE;
void calcJacobian(Mat &jac) CV_OVERRIDE;
Mat err1_, err2_;
};
/** @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_W BundleAdjusterRay : public BundleAdjusterBase
{
public:
CV_WRAP BundleAdjusterRay() : BundleAdjusterBase(4, 3) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const CV_OVERRIDE;
void calcError(Mat &err) CV_OVERRIDE;
void calcJacobian(Mat &jac) CV_OVERRIDE;
Mat err1_, err2_;
};
/** @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_W BundleAdjusterAffine : public BundleAdjusterBase
{
public:
CV_WRAP BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const CV_OVERRIDE;
void calcError(Mat &err) CV_OVERRIDE;
void calcJacobian(Mat &jac) CV_OVERRIDE;
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_W BundleAdjusterAffinePartial : public BundleAdjusterBase
{
public:
CV_WRAP BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
void obtainRefinedCameraParams(std::vector<CameraParams> &cameras) const CV_OVERRIDE;
void calcError(Mat &err) CV_OVERRIDE;
void calcJacobian(Mat &jac) CV_OVERRIDE;
Mat err1_, err2_;
};
enum WaveCorrectKind
{
WAVE_CORRECT_HORIZ,
WAVE_CORRECT_VERT,
WAVE_CORRECT_AUTO
};
/** @brief Tries to detect the wave correction kind depending
on whether a panorama spans horizontally or vertically
@param rmats Camera rotation matrices.
@return The correction kind to use for this panorama
*/
CV_EXPORTS
WaveCorrectKind autoDetectWaveCorrectKind(const std::vector<Mat> &rmats);
/** @brief Tries to make panorama more horizontal (or vertical).
@param rmats Camera rotation matrices.
@param kind Correction kind, see detail::WaveCorrectKind.
*/
void CV_EXPORTS_W waveCorrect(CV_IN_OUT std::vector<Mat> &rmats, WaveCorrectKind kind);
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
// Returns matches graph representation in DOT language
String CV_EXPORTS_W matchesGraphAsString(std::vector<String> &pathes, std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
CV_EXPORTS_W std::vector<int> 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);
//! @} stitching_rotation
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_MOTION_ESTIMATORS_HPP

View File

@ -0,0 +1,291 @@
/*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_SEAM_FINDERS_HPP
#define OPENCV_STITCHING_SEAM_FINDERS_HPP
#include <set>
#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_W SeamFinder
{
public:
CV_WRAP virtual ~SeamFinder() {}
enum { NO, VORONOI_SEAM, DP_SEAM };
/** @brief Estimates seams.
@param src Source images
@param corners Source image top-left corners
@param masks Source image masks to update
*/
CV_WRAP virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &masks) = 0;
CV_WRAP static Ptr<SeamFinder> createDefault(int type);
};
/** @brief Stub seam estimator which does nothing.
*/
class CV_EXPORTS_W NoSeamFinder : public SeamFinder
{
public:
CV_WRAP void find(const std::vector<UMat>&, const std::vector<Point>&, CV_IN_OUT std::vector<UMat>&) CV_OVERRIDE {}
};
/** @brief Base class for all pairwise seam estimators.
*/
class CV_EXPORTS_W PairwiseSeamFinder : public SeamFinder
{
public:
CV_WRAP virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &masks) CV_OVERRIDE;
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<UMat> images_;
std::vector<Size> sizes_;
std::vector<Point> corners_;
std::vector<UMat> masks_;
};
/** @brief Voronoi diagram-based seam estimator.
*/
class CV_EXPORTS_W VoronoiSeamFinder : public PairwiseSeamFinder
{
public:
CV_WRAP virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &masks) CV_OVERRIDE;
virtual void find(const std::vector<Size> &size, const std::vector<Point> &corners,
std::vector<UMat> &masks);
private:
void findInPair(size_t first, size_t second, Rect roi) CV_OVERRIDE;
};
class CV_EXPORTS_W DpSeamFinder : public SeamFinder
{
public:
enum CostFunction { COLOR, COLOR_GRAD };
DpSeamFinder(CostFunction costFunc = COLOR);
CV_WRAP DpSeamFinder(String costFunc );
CostFunction costFunction() const { return costFunc_; }
void setCostFunction(CostFunction val) { costFunc_ = val; }
CV_WRAP void setCostFunction(String val);
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) CV_OVERRIDE;
private:
enum ComponentState
{
FIRST = 1, SECOND = 2, INTERS = 4,
INTERS_FIRST = INTERS | FIRST,
INTERS_SECOND = INTERS | SECOND
};
class ImagePairLess
{
public:
ImagePairLess(const std::vector<Mat> &images, const std::vector<Point> &corners)
: src_(&images[0]), corners_(&corners[0]) {}
bool operator() (const std::pair<size_t, size_t> &l, const std::pair<size_t, size_t> &r) const
{
Point c1 = corners_[l.first] + Point(src_[l.first].cols / 2, src_[l.first].rows / 2);
Point c2 = corners_[l.second] + Point(src_[l.second].cols / 2, src_[l.second].rows / 2);
int d1 = (c1 - c2).dot(c1 - c2);
c1 = corners_[r.first] + Point(src_[r.first].cols / 2, src_[r.first].rows / 2);
c2 = corners_[r.second] + Point(src_[r.second].cols / 2, src_[r.second].rows / 2);
int d2 = (c1 - c2).dot(c1 - c2);
return d1 < d2;
}
private:
const Mat *src_;
const Point *corners_;
};
class ClosePoints
{
public:
ClosePoints(int minDist) : minDist_(minDist) {}
bool operator() (const Point &p1, const Point &p2) const
{
int dist2 = (p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y);
return dist2 < minDist_ * minDist_;
}
private:
int minDist_;
};
void process(
const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
void findComponents();
void findEdges();
void resolveConflicts(
const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2);
void computeGradients(const Mat &image1, const Mat &image2);
bool hasOnlyOneNeighbor(int comp);
bool closeToContour(int y, int x, const Mat_<uchar> &contourMask);
bool getSeamTips(int comp1, int comp2, Point &p1, Point &p2);
void computeCosts(
const Mat &image1, const Mat &image2, Point tl1, Point tl2,
int comp, Mat_<float> &costV, Mat_<float> &costH);
bool estimateSeam(
const Mat &image1, const Mat &image2, Point tl1, Point tl2, int comp,
Point p1, Point p2, std::vector<Point> &seam, bool &isHorizontal);
void updateLabelsUsingSeam(
int comp1, int comp2, const std::vector<Point> &seam, bool isHorizontalSeam);
CostFunction costFunc_;
// processing images pair data
Point unionTl_, unionBr_;
Size unionSize_;
Mat_<uchar> mask1_, mask2_;
Mat_<uchar> contour1mask_, contour2mask_;
Mat_<float> gradx1_, grady1_;
Mat_<float> gradx2_, grady2_;
// components data
int ncomps_;
Mat_<int> labels_;
std::vector<ComponentState> states_;
std::vector<Point> tls_, brs_;
std::vector<std::vector<Point> > contours_;
std::set<std::pair<int, int> > edges_;
};
/** @brief Base class for all minimum graph-cut-based seam estimators.
*/
class CV_EXPORTS GraphCutSeamFinderBase
{
public:
enum CostType { COST_COLOR, COST_COLOR_GRAD };
};
/** @brief Minimum graph cut-based seam estimator. See details in @cite V03 .
*/
class CV_EXPORTS_W GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
{
public:
GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f);
CV_WRAP GraphCutSeamFinder(String cost_type,float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f);
~GraphCutSeamFinder();
CV_WRAP void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) CV_OVERRIDE;
private:
// To avoid GCGraph dependency
class Impl;
Ptr<PairwiseSeamFinder> impl_;
};
#ifdef HAVE_OPENCV_CUDALEGACY
class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
{
public:
GraphCutSeamFinderGpu(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f)
: cost_type_(cost_type), terminal_cost_(terminal_cost),
bad_region_penalty_(bad_region_penalty) {}
void find(const std::vector<cv::UMat> &src, const std::vector<cv::Point> &corners,
std::vector<cv::UMat> &masks) CV_OVERRIDE;
void findInPair(size_t first, size_t second, Rect roi) CV_OVERRIDE;
private:
void setGraphWeightsColor(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &mask1, const cv::Mat &mask2,
cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
void setGraphWeightsColorGrad(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &dx1, const cv::Mat &dx2,
const cv::Mat &dy1, const cv::Mat &dy2, const cv::Mat &mask1, const cv::Mat &mask2,
cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom);
std::vector<Mat> dx_, dy_;
int cost_type_;
float terminal_cost_;
float bad_region_penalty_;
};
#endif
//! @}
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_SEAM_FINDERS_HPP

View File

@ -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_W Timelapser
{
public:
enum {AS_IS, CROP};
virtual ~Timelapser() {}
CV_WRAP static Ptr<Timelapser> createDefault(int type);
CV_WRAP virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_WRAP virtual void process(InputArray img, InputArray mask, Point tl);
CV_WRAP virtual const UMat& getDst() {return dst_;}
protected:
virtual bool test_point(Point pt);
UMat dst_;
Rect dst_roi_;
};
class CV_EXPORTS_W TimelapserCrop : public Timelapser
{
public:
virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes) CV_OVERRIDE;
};
//! @}
} // namespace detail
} // namespace cv
#endif // OPENCV_STITCHING_TIMELAPSERS_HPP

View File

@ -0,0 +1,121 @@
/*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_UTIL_HPP
#define OPENCV_STITCHING_UTIL_HPP
#include <list>
#include "opencv2/core.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching
//! @{
class CV_EXPORTS DisjointSets
{
public:
DisjointSets(int elem_count = 0) { createOneElemSets(elem_count); }
void createOneElemSets(int elem_count);
int findSetByElem(int elem);
int mergeSets(int set1, int set2);
std::vector<int> parent;
std::vector<int> size;
private:
std::vector<int> rank_;
};
struct CV_EXPORTS GraphEdge
{
GraphEdge(int from, int to, float weight);
bool operator <(const GraphEdge& other) const { return weight < other.weight; }
bool operator >(const GraphEdge& other) const { return weight > other.weight; }
int from, to;
float weight;
};
inline GraphEdge::GraphEdge(int _from, int _to, float _weight) : from(_from), to(_to), weight(_weight) {}
class CV_EXPORTS Graph
{
public:
Graph(int num_vertices = 0) { create(num_vertices); }
void create(int num_vertices) { edges_.assign(num_vertices, std::list<GraphEdge>()); }
int numVertices() const { return static_cast<int>(edges_.size()); }
void addEdge(int from, int to, float weight);
template <typename B> B forEach(B body) const;
template <typename B> B walkBreadthFirst(int from, B body) const;
private:
std::vector< std::list<GraphEdge> > edges_;
};
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
CV_EXPORTS_W bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi);
CV_EXPORTS_W Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images);
CV_EXPORTS_W Rect resultRoi(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS_W Rect resultRoiIntersection(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS_W Point resultTl(const std::vector<Point> &corners);
// Returns random 'count' element subset of the {0,1,...,size-1} set
CV_EXPORTS_W void selectRandomSubset(int count, int size, std::vector<int> &subset);
CV_EXPORTS_W int& stitchingLogLevel();
//! @}
} // namespace detail
} // namespace cv
#include "util_inl.hpp"
#endif // OPENCV_STITCHING_UTIL_HPP

View File

@ -0,0 +1,131 @@
/*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_UTIL_INL_HPP
#define OPENCV_STITCHING_UTIL_INL_HPP
#include <queue>
#include "opencv2/core.hpp"
#include "util.hpp" // Make your IDE see declarations
//! @cond IGNORED
namespace cv {
namespace detail {
template <typename B>
B Graph::forEach(B body) const
{
for (int i = 0; i < numVertices(); ++i)
{
std::list<GraphEdge>::const_iterator edge = edges_[i].begin();
for (; edge != edges_[i].end(); ++edge)
body(*edge);
}
return body;
}
template <typename B>
B Graph::walkBreadthFirst(int from, B body) const
{
std::vector<bool> was(numVertices(), false);
std::queue<int> vertices;
was[from] = true;
vertices.push(from);
while (!vertices.empty())
{
int vertex = vertices.front();
vertices.pop();
std::list<GraphEdge>::const_iterator edge = edges_[vertex].begin();
for (; edge != edges_[vertex].end(); ++edge)
{
if (!was[edge->to])
{
body(*edge);
was[edge->to] = true;
vertices.push(edge->to);
}
}
}
return body;
}
//////////////////////////////////////////////////////////////////////////////
// Some auxiliary math functions
static inline
float normL2(const Point3f& a)
{
return a.x * a.x + a.y * a.y + a.z * a.z;
}
static inline
float normL2(const Point3f& a, const Point3f& b)
{
return normL2(a - b);
}
static inline
double normL2sq(const Mat &r)
{
return r.dot(r);
}
static inline int sqr(int x) { return x * x; }
static inline float sqr(float x) { return x * x; }
static inline double sqr(double x) { return x * x; }
} // namespace detail
} // namespace cv
//! @endcond
#endif // OPENCV_STITCHING_UTIL_INL_HPP

View File

@ -0,0 +1,682 @@
/*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_WARPERS_HPP
#define OPENCV_STITCHING_WARPERS_HPP
#include "opencv2/core.hpp"
#include "opencv2/core/cuda.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/opencv_modules.hpp"
namespace cv {
namespace detail {
//! @addtogroup stitching_warp
//! @{
/** @brief Rotation-only model image warper interface.
*/
class CV_EXPORTS RotationWarper
{
public:
virtual ~RotationWarper() {}
/** @brief Projects the image point.
@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;
/** @brief Projects the image point backward.
@param pt Projected point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Backward-projected point
*/
#if CV_VERSION_MAJOR == 4
virtual Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
CV_UNUSED(pt); CV_UNUSED(K); CV_UNUSED(R);
CV_Error(Error::StsNotImplemented, "");
}
#else
virtual Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R) = 0;
#endif
/** @brief Builds the projection maps according to the given camera data.
@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;
/** @brief Projects the image.
@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,
CV_OUT 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, CV_OUT 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_W_SIMPLE ProjectorBase
{
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];
float rinv[9];
float r_kinv[9];
float k_rinv[9];
float t[3];
};
/** @brief Base class for rotation-based warper using a detail::ProjectorBase_ derived class.
*/
template <class P>
class CV_EXPORTS_TEMPLATE RotationWarperBase : public RotationWarper
{
public:
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPointBackward(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst) CV_OVERRIDE;
void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, OutputArray dst) CV_OVERRIDE;
Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE;
float getScale() const CV_OVERRIDE{ return projector_.scale; }
void setScale(float val) CV_OVERRIDE { projector_.scale = val; }
protected:
// Detects ROI of the destination image. It's correct for any projection.
virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
// Detects ROI of the destination image by walking over image border.
// Correctness for any projection isn't guaranteed.
void detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br);
P projector_;
};
struct CV_EXPORTS PlaneProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
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; }
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T);
Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R, InputArray T);
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R,
int interp_mode, int border_mode, CV_OUT OutputArray dst) CV_OVERRIDE;
virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
CV_OUT OutputArray dst);
Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE;
Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T);
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE;
};
/** @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) {}
/** @brief Projects the image point.
@param pt Source point
@param K Camera intrinsic parameters
@param H Camera extrinsic parameters
@return Projected point
*/
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray H) CV_OVERRIDE;
/** @brief Projects the image point backward.
@param pt Projected point
@param K Camera intrinsic parameters
@param H Camera extrinsic parameters
@return Backward-projected point
*/
Point2f warpPointBackward(const Point2f &pt, InputArray K, InputArray H) CV_OVERRIDE;
/** @brief Builds the projection maps according to the given camera data.
@param src_size Source image size
@param K Camera intrinsic parameters
@param H Camera extrinsic parameters
@param xmap Projection map for the x axis
@param ymap Projection map for the y axis
@return Projected image minimum bounding box
*/
Rect buildMaps(Size src_size, InputArray K, InputArray H, OutputArray xmap, OutputArray ymap) CV_OVERRIDE;
/** @brief Projects the image.
@param src Source image
@param K Camera intrinsic parameters
@param H Camera extrinsic parameters
@param interp_mode Interpolation mode
@param border_mode Border extrapolation mode
@param dst Projected image
@return Project image top-left corner
*/
Point warp(InputArray src, InputArray K, InputArray H,
int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE;
/**
@param src_size Source image bounding box
@param K Camera intrinsic parameters
@param H Camera extrinsic parameters
@return Projected image minimum bounding box
*/
Rect warpRoi(Size src_size, InputArray K, InputArray H) CV_OVERRIDE;
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_W_SIMPLE SphericalProjector : ProjectorBase
{
CV_WRAP void mapForward(float x, float y, float &u, float &v);
CV_WRAP void mapBackward(float u, float v, float &x, float &y);
};
/** @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) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE;
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE;
};
struct CV_EXPORTS CylindricalProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
/** @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) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE;
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE
{
RotationWarperBase<CylindricalProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
}
};
struct CV_EXPORTS FisheyeProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS FisheyeWarper : public RotationWarperBase<FisheyeProjector>
{
public:
FisheyeWarper(float scale) { projector_.scale = scale; }
};
struct CV_EXPORTS StereographicProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS StereographicWarper : public RotationWarperBase<StereographicProjector>
{
public:
StereographicWarper(float scale) { projector_.scale = scale; }
};
struct CV_EXPORTS CompressedRectilinearProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS CompressedRectilinearWarper : public RotationWarperBase<CompressedRectilinearProjector>
{
public:
CompressedRectilinearWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS CompressedRectilinearPortraitProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS CompressedRectilinearPortraitWarper : public RotationWarperBase<CompressedRectilinearPortraitProjector>
{
public:
CompressedRectilinearPortraitWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS PaniniProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS PaniniWarper : public RotationWarperBase<PaniniProjector>
{
public:
PaniniWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS PaniniPortraitProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS PaniniPortraitWarper : public RotationWarperBase<PaniniPortraitProjector>
{
public:
PaniniPortraitWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS MercatorProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS MercatorWarper : public RotationWarperBase<MercatorProjector>
{
public:
MercatorWarper(float scale) { projector_.scale = scale; }
};
struct CV_EXPORTS TransverseMercatorProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS TransverseMercatorWarper : public RotationWarperBase<TransverseMercatorProjector>
{
public:
TransverseMercatorWarper(float scale) { projector_.scale = scale; }
};
class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
{
public:
PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {}
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE
{
Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
d_ymap_.download(ymap);
return result;
}
Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap) CV_OVERRIDE
{
Rect result = buildMaps(src_size, K, R, T, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
d_ymap_.download(ymap);
return result;
}
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst) CV_OVERRIDE
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
d_dst_.download(dst);
return result;
}
Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
OutputArray dst) CV_OVERRIDE
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, T, interp_mode, border_mode, d_dst_);
d_dst_.download(dst);
return result;
}
Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
cuda::GpuMat & dst);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
cuda::GpuMat & dst);
private:
cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
};
class CV_EXPORTS SphericalWarperGpu : public SphericalWarper
{
public:
SphericalWarperGpu(float scale) : SphericalWarper(scale) {}
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE
{
Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
d_ymap_.download(ymap);
return result;
}
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst) CV_OVERRIDE
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
d_dst_.download(dst);
return result;
}
Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
cuda::GpuMat & dst);
private:
cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
};
class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper
{
public:
CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {}
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE
{
Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_);
d_xmap_.download(xmap);
d_ymap_.download(ymap);
return result;
}
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst) CV_OVERRIDE
{
d_src_.upload(src);
Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_);
d_dst_.download(dst);
return result;
}
Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap);
Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode,
cuda::GpuMat & dst);
private:
cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_;
};
struct CV_EXPORTS SphericalPortraitProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
// Projects image onto unit sphere with origin at (0, 0, 0).
// Poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points.
class CV_EXPORTS SphericalPortraitWarper : public RotationWarperBase<SphericalPortraitProjector>
{
public:
SphericalPortraitWarper(float scale) { projector_.scale = scale; }
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE;
};
struct CV_EXPORTS CylindricalPortraitProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS CylindricalPortraitWarper : public RotationWarperBase<CylindricalPortraitProjector>
{
public:
CylindricalPortraitWarper(float scale) { projector_.scale = scale; }
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE
{
RotationWarperBase<CylindricalPortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
}
};
struct CV_EXPORTS PlanePortraitProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS PlanePortraitWarper : public RotationWarperBase<PlanePortraitProjector>
{
public:
PlanePortraitWarper(float scale) { projector_.scale = scale; }
protected:
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE
{
RotationWarperBase<PlanePortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
}
};
//! @} stitching_warp
} // namespace detail
} // namespace cv
#include "warpers_inl.hpp"
#endif // OPENCV_STITCHING_WARPERS_HPP

View File

@ -0,0 +1,782 @@
/*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_WARPERS_INL_HPP
#define OPENCV_STITCHING_WARPERS_INL_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, InputArray K, InputArray R)
{
projector_.setCameraParams(K, R);
Point2f uv;
projector_.mapForward(pt.x, pt.y, uv.x, uv.y);
return uv;
}
template <class P>
Point2f RotationWarperBase<P>::warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
projector_.setCameraParams(K, R);
Point2f xy;
projector_.mapBackward(pt.x, pt.y, xy.x, xy.y);
return xy;
}
template <class P>
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);
Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
float x, y;
for (int v = dst_tl.y; v <= dst_br.y; ++v)
{
for (int u = dst_tl.x; u <= dst_br.x; ++u)
{
projector_.mapBackward(static_cast<float>(u), static_cast<float>(v), x, y);
xmap.at<float>(v - dst_tl.y, u - dst_tl.x) = x;
ymap.at<float>(v - dst_tl.y, u - dst_tl.x) = y;
}
}
return Rect(dst_tl, dst_br);
}
template <class P>
Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst)
{
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());
remap(src, dst, xmap, ymap, interp_mode, border_mode);
return dst_roi.tl();
}
template <class P>
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);
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);
float u, v;
for (int y = 0; y < dst_size.height; ++y)
{
for (int x = 0; x < dst_size.width; ++x)
{
projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
xmap.at<float>(y, x) = u - src_tl.x;
ymap.at<float>(y, x) = v - src_tl.y;
}
}
dst.create(dst_size, src.type());
remap(src, dst, xmap, ymap, interp_mode, border_mode);
}
template <class P>
Rect RotationWarperBase<P>::warpRoi(Size src_size, InputArray K, InputArray R)
{
projector_.setCameraParams(K, R);
Point dst_tl, dst_br;
detectResultRoi(src_size, dst_tl, dst_br);
return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
}
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 u, v;
for (int y = 0; y < src_size.height; ++y)
{
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);
}
}
dst_tl.x = static_cast<int>(tl_uf);
dst_tl.y = static_cast<int>(tl_vf);
dst_br.x = static_cast<int>(br_uf);
dst_br.y = static_cast<int>(br_vf);
}
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 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);
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);
}
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);
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);
}
dst_tl.x = static_cast<int>(tl_uf);
dst_tl.y = static_cast<int>(tl_vf);
dst_br.x = static_cast<int>(br_uf);
dst_br.y = static_cast<int>(br_vf);
}
inline
void PlaneProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
x_ = t[0] + x_ / z_ * (1 - t[2]);
y_ = t[1] + y_ / z_ * (1 - t[2]);
u = scale * x_;
v = scale * y_;
}
inline
void PlaneProjector::mapBackward(float u, float v, float &x, float &y)
{
u = u / scale - t[0];
v = v / scale - t[1];
float z;
x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]);
y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]);
z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]);
x /= z;
y /= z;
}
inline
void SphericalProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
u = scale * atan2f(x_, z_);
float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_);
v = scale * (static_cast<float>(CV_PI) - acosf(w == w ? w : 0));
}
inline
void SphericalProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float sinv = sinf(static_cast<float>(CV_PI) - v);
float x_ = sinv * sinf(u);
float y_ = cosf(static_cast<float>(CV_PI) - v);
float z_ = sinv * cosf(u);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void CylindricalProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
u = scale * atan2f(x_, z_);
v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
}
inline
void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float x_ = sinf(u);
float y_ = v;
float z_ = cosf(u);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = scale * v_ * cosf(u_);
v = scale * v_ * sinf(u_);
}
inline
void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float u_ = atan2f(v, u);
float v_ = sqrtf(u*u + v*v);
float sinv = sinf((float)CV_PI - v_);
float x_ = sinv * sinf(u_);
float y_ = cosf((float)CV_PI - v_);
float z_ = sinv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void StereographicProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float r = sinf(v_) / (1 - cosf(v_));
u = scale * r * std::cos(u_);
v = scale * r * std::sin(u_);
}
inline
void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float u_ = atan2f(v, u);
float r = sqrtf(u*u + v*v);
float v_ = 2 * atanf(1.f / r);
float sinv = sinf((float)CV_PI - v_);
float x_ = sinv * sinf(u_);
float y_ = cosf((float)CV_PI - v_);
float z_ = sinv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = scale * a * tanf(u_ / a);
v = scale * b * tanf(v_) / cosf(u_);
}
inline
void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float aatg = a * atanf(u / a);
float u_ = aatg;
float v_ = atanf(v * cosf(aatg) / b);
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
{
float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = - scale * a * tanf(u_ / a);
v = scale * b * tanf(v_) / cosf(u_);
}
inline
void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= - scale;
v /= scale;
float aatg = a * atanf(u / a);
float u_ = aatg;
float v_ = atanf(v * cosf( aatg ) / b);
float cosv = cosf(v_);
float y_ = cosv * sinf(u_);
float x_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void PaniniProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float tg = a * tanf(u_ / a);
u = scale * tg;
float sinu = sinf(u_);
if ( fabs(sinu) < 1E-7 )
v = scale * b * tanf(v_);
else
v = scale * b * tg * tanf(v_) / sinu;
}
inline
void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float lamda = a * atanf(u / a);
float u_ = lamda;
float v_;
if ( fabs(lamda) > 1E-7)
v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
else
v_ = atanf(v / b);
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
{
float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float tg = a * tanf(u_ / a);
u = - scale * tg;
float sinu = sinf( u_ );
if ( fabs(sinu) < 1E-7 )
v = scale * b * tanf(v_);
else
v = scale * b * tg * tanf(v_) / sinu;
}
inline
void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= - scale;
v /= scale;
float lamda = a * atanf(u / a);
float u_ = lamda;
float v_;
if ( fabs(lamda) > 1E-7)
v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
else
v_ = atanf(v / b);
float cosv = cosf(v_);
float y_ = cosv * sinf(u_);
float x_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void MercatorProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = scale * u_;
v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) );
}
inline
void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float v_ = atanf( sinhf(v) );
float u_ = u;
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float B = cosf(v_) * sinf(u_);
u = scale / 2 * logf( (1+B) / (1-B) );
v = scale * atan2f(tanf(v_), cosf(u_));
}
inline
void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float v_ = asinf( sinf(v) / coshf(u) );
float u_ = atan2f( sinhf(u), std::cos(v) );
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
{
float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float x_ = y0_;
float y_ = x0_;
float u, v;
u = scale * atan2f(x_, z_);
v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
u0 = -u;//v;
v0 = v;//u;
}
inline
void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
{
float u, v;
u = -u0;//v0;
v = v0;//u0;
u /= scale;
v /= scale;
float sinv = sinf(static_cast<float>(CV_PI) - v);
float x0_ = sinv * sinf(u);
float y0_ = cosf(static_cast<float>(CV_PI) - v);
float z_ = sinv * cosf(u);
float x_ = y0_;
float y_ = x0_;
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
{
float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float x_ = y0_;
float y_ = x0_;
float u, v;
u = scale * atan2f(x_, z_);
v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
u0 = -u;//v;
v0 = v;//u;
}
inline
void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
{
float u, v;
u = -u0;//v0;
v = v0;//u0;
u /= scale;
v /= scale;
float x0_ = sinf(u);
float y0_ = v;
float z_ = cosf(u);
float x_ = y0_;
float y_ = x0_;
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0)
{
float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float x_ = y0_;
float y_ = x0_;
x_ = t[0] + x_ / z_ * (1 - t[2]);
y_ = t[1] + y_ / z_ * (1 - t[2]);
float u,v;
u = scale * x_;
v = scale * y_;
u0 = -u;
v0 = v;
}
inline
void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
{
float u, v;
u = -u0;
v = v0;
u = u / scale - t[0];
v = v / scale - t[1];
float z;
x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]);
y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]);
z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]);
x /= z;
y /= z;
}
} // namespace detail
} // namespace cv
//! @endcond
#endif // OPENCV_STITCHING_WARPERS_INL_HPP

View File

@ -0,0 +1,277 @@
/*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_WARPER_CREATORS_HPP
#define OPENCV_STITCHING_WARPER_CREATORS_HPP
#include "opencv2/stitching/detail/warpers.hpp"
#include <string>
namespace cv {
class CV_EXPORTS_W PyRotationWarper
{
Ptr<detail::RotationWarper> rw;
public:
CV_WRAP PyRotationWarper(String type, float scale);
CV_WRAP PyRotationWarper() {};
~PyRotationWarper() {}
/** @brief Projects the image point.
@param pt Source point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Projected point
*/
CV_WRAP Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
/** @brief Projects the image point backward.
@param pt Projected point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Backward-projected point
*/
#if CV_VERSION_MAJOR == 4
CV_WRAP Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
CV_UNUSED(pt); CV_UNUSED(K); CV_UNUSED(R);
CV_Error(Error::StsNotImplemented, "");
}
#else
CV_WRAP Point2f warpPointBackward(const Point2f &pt, InputArray K, InputArray R);
#endif
/** @brief Builds the projection maps according to the given camera data.
@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
*/
CV_WRAP Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
/** @brief Projects the image.
@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
*/
CV_WRAP Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
CV_OUT OutputArray dst);
/** @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
*/
CV_WRAP void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, CV_OUT OutputArray dst);
/**
@param src_size Source image bounding box
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Projected image minimum bounding box
*/
CV_WRAP Rect warpRoi(Size src_size, InputArray K, InputArray R);
CV_WRAP float getScale() const { return 1.f; }
CV_WRAP void setScale(float) {}
};
//! @addtogroup stitching_warp
//! @{
/** @brief Image warper factories base class.
*/
class CV_EXPORTS_W WarperCreator
{
public:
CV_WRAP virtual ~WarperCreator() {}
virtual Ptr<detail::RotationWarper> create(float scale) const = 0;
};
/** @brief Plane warper factory class.
@sa detail::PlaneWarper
*/
class CV_EXPORTS PlaneWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PlaneWarper>(scale); }
};
/** @brief Affine warper factory class.
@sa detail::AffineWarper
*/
class CV_EXPORTS AffineWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::AffineWarper>(scale); }
};
/** @brief Cylindrical warper factory class.
@sa detail::CylindricalWarper
*/
class CV_EXPORTS CylindricalWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CylindricalWarper>(scale); }
};
/** @brief Spherical warper factory class */
class CV_EXPORTS SphericalWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::SphericalWarper>(scale); }
};
class CV_EXPORTS FisheyeWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::FisheyeWarper>(scale); }
};
class CV_EXPORTS StereographicWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::StereographicWarper>(scale); }
};
class CV_EXPORTS CompressedRectilinearWarper: public WarperCreator
{
float a, b;
public:
CompressedRectilinearWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CompressedRectilinearWarper>(scale, a, b); }
};
class CV_EXPORTS CompressedRectilinearPortraitWarper: public WarperCreator
{
float a, b;
public:
CompressedRectilinearPortraitWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CompressedRectilinearPortraitWarper>(scale, a, b); }
};
class CV_EXPORTS PaniniWarper: public WarperCreator
{
float a, b;
public:
PaniniWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PaniniWarper>(scale, a, b); }
};
class CV_EXPORTS PaniniPortraitWarper: public WarperCreator
{
float a, b;
public:
PaniniPortraitWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PaniniPortraitWarper>(scale, a, b); }
};
class CV_EXPORTS MercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::MercatorWarper>(scale); }
};
class CV_EXPORTS TransverseMercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::TransverseMercatorWarper>(scale); }
};
#ifdef HAVE_OPENCV_CUDAWARPING
class PlaneWarperGpu: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PlaneWarperGpu>(scale); }
};
class CylindricalWarperGpu: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CylindricalWarperGpu>(scale); }
};
class SphericalWarperGpu: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::SphericalWarperGpu>(scale); }
};
#endif
//! @} stitching_warp
} // namespace cv
#endif // OPENCV_STITCHING_WARPER_CREATORS_HPP