diff --git a/modules/reg/include/opencv2/reg/map.hpp b/modules/reg/include/opencv2/reg/map.hpp index 26b29e38e..a885a2844 100644 --- a/modules/reg/include/opencv2/reg/map.hpp +++ b/modules/reg/include/opencv2/reg/map.hpp @@ -121,13 +121,13 @@ namespace reg { The class is only used to define the common interface for any possible map. */ -class CV_EXPORTS Map +class CV_EXPORTS_W Map { public: /*! * Virtual destructor */ - virtual ~Map(void); + virtual ~Map(); /*! * Warps image to a new coordinate frame. The calculation is img2(x)=img1(T^{-1}(x)), as we @@ -136,7 +136,7 @@ public: * \param[in] img1 Original image * \param[out] img2 Warped image */ - virtual void warp(const cv::Mat& img1, cv::Mat& img2) const; + CV_WRAP virtual void warp(InputArray img1, OutputArray img2) const; /*! * Warps image to a new coordinate frame. The calculation is img2(x)=img1(T(x)), so in fact @@ -145,27 +145,27 @@ public: * \param[in] img1 Original image * \param[out] img2 Warped image */ - virtual void inverseWarp(const cv::Mat& img1, cv::Mat& img2) const = 0; + CV_WRAP virtual void inverseWarp(InputArray img1, OutputArray img2) const = 0; /*! * Calculates the inverse map * \return Inverse map */ - virtual cv::Ptr inverseMap(void) const = 0; + CV_WRAP virtual cv::Ptr inverseMap() const = 0; /*! * Changes the map composing the current transformation with the one provided in the call. * The order is first the current transformation, then the input argument. * \param[in] map Transformation to compose with. */ - virtual void compose(const Map& map) = 0; + CV_WRAP virtual void compose(cv::Ptr map) = 0; /*! * Scales the map by a given factor as if the coordinates system is expanded/compressed * by that factor. * \param[in] factor Expansion if bigger than one, compression if smaller than one */ - virtual void scale(double factor) = 0; + CV_WRAP virtual void scale(double factor) = 0; }; //! @} diff --git a/modules/reg/include/opencv2/reg/mapaffine.hpp b/modules/reg/include/opencv2/reg/mapaffine.hpp index 1c9132633..1843d8431 100644 --- a/modules/reg/include/opencv2/reg/mapaffine.hpp +++ b/modules/reg/include/opencv2/reg/mapaffine.hpp @@ -49,13 +49,13 @@ namespace reg { /*! * Defines an affine transformation */ -class CV_EXPORTS MapAffine : public Map +class CV_EXPORTS_W MapAffine : public Map { public: /*! * Default constructor builds an identity map */ - MapAffine(void); + CV_WRAP MapAffine(); /*! * Constructor providing explicit values @@ -67,15 +67,15 @@ public: /*! * Destructor */ - ~MapAffine(void); + ~MapAffine(); - void inverseWarp(const cv::Mat& img1, cv::Mat& img2) const; + CV_WRAP void inverseWarp(InputArray img1, OutputArray img2) const; - cv::Ptr inverseMap(void) const; + CV_WRAP cv::Ptr inverseMap() const; - void compose(const Map& map); + CV_WRAP void compose(cv::Ptr map); - void scale(double factor); + CV_WRAP void scale(double factor); /*! * Return linear part of the affine transformation @@ -85,6 +85,10 @@ public: return linTr_; } + CV_WRAP void getLinTr(OutputArray linTr) const { + Mat(linTr_).copyTo(linTr); + } + /*! * Return displacement part of the affine transformation * \return Displacement part of the affine transformation @@ -93,6 +97,10 @@ public: return shift_; } + CV_WRAP void getShift(OutputArray shift) const { + Mat(shift_).copyTo(shift); + } + private: cv::Matx linTr_; cv::Vec shift_; diff --git a/modules/reg/include/opencv2/reg/mapper.hpp b/modules/reg/include/opencv2/reg/mapper.hpp index 8abadd14e..2c2862d49 100644 --- a/modules/reg/include/opencv2/reg/mapper.hpp +++ b/modules/reg/include/opencv2/reg/mapper.hpp @@ -47,11 +47,11 @@ namespace reg { //! @addtogroup reg //! @{ -/** @brief Base class for modelling an algorithm for calculating a +/** @brief Base class for modelling an algorithm for calculating a map The class is only used to define the common interface for any possible mapping algorithm. */ -class CV_EXPORTS Mapper +class CV_EXPORTS_W Mapper { public: virtual ~Mapper(void) {} @@ -60,16 +60,16 @@ public: * Calculate mapping between two images * \param[in] img1 Reference image * \param[in] img2 Warped image - * \param[in,out] res Map from img1 to img2, stored in a smart pointer. If present as input, - * it is an initial rough estimation that the mapper will try to refine. + * \param[in] If present, it is an initial rough estimation that the mapper will try to refine. + * \return Map from img1 to img2, stored in a smart pointer. */ - virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const = 0; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const = 0; /* * Returns a map compatible with the Mapper class * \return Pointer to identity Map */ - virtual cv::Ptr getMap(void) const = 0; + CV_WRAP virtual cv::Ptr getMap() const = 0; protected: /* diff --git a/modules/reg/include/opencv2/reg/mappergradaffine.hpp b/modules/reg/include/opencv2/reg/mappergradaffine.hpp index 08d539711..8b0d7b41f 100644 --- a/modules/reg/include/opencv2/reg/mappergradaffine.hpp +++ b/modules/reg/include/opencv2/reg/mappergradaffine.hpp @@ -49,15 +49,15 @@ namespace reg { /*! * Mapper for affine motion */ -class CV_EXPORTS MapperGradAffine: public Mapper +class CV_EXPORTS_W MapperGradAffine: public Mapper { public: - MapperGradAffine(void); + CV_WRAP MapperGradAffine(); ~MapperGradAffine(void); - virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const; - cv::Ptr getMap(void) const; + CV_WRAP cv::Ptr getMap() const; }; //! @} diff --git a/modules/reg/include/opencv2/reg/mappergradeuclid.hpp b/modules/reg/include/opencv2/reg/mappergradeuclid.hpp index 29c49cb65..c41a5f7f0 100644 --- a/modules/reg/include/opencv2/reg/mappergradeuclid.hpp +++ b/modules/reg/include/opencv2/reg/mappergradeuclid.hpp @@ -49,15 +49,15 @@ namespace reg { /*! * Mapper for euclidean motion: rotation plus shift */ -class CV_EXPORTS MapperGradEuclid: public Mapper +class CV_EXPORTS_W MapperGradEuclid: public Mapper { public: - MapperGradEuclid(void); - ~MapperGradEuclid(void); + CV_WRAP MapperGradEuclid(); + ~MapperGradEuclid(); - virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const; - cv::Ptr getMap(void) const; + CV_WRAP cv::Ptr getMap() const; }; //! @} diff --git a/modules/reg/include/opencv2/reg/mappergradproj.hpp b/modules/reg/include/opencv2/reg/mappergradproj.hpp index f1721e820..5d83fc4f0 100644 --- a/modules/reg/include/opencv2/reg/mappergradproj.hpp +++ b/modules/reg/include/opencv2/reg/mappergradproj.hpp @@ -49,15 +49,15 @@ namespace reg { /*! * Gradient mapper for a projective transformation */ -class CV_EXPORTS MapperGradProj: public Mapper +class CV_EXPORTS_W MapperGradProj: public Mapper { public: - MapperGradProj(void); - ~MapperGradProj(void); + CV_WRAP MapperGradProj(); + ~MapperGradProj(); - virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const; - cv::Ptr getMap(void) const; + CV_WRAP cv::Ptr getMap() const; }; //! @} diff --git a/modules/reg/include/opencv2/reg/mappergradshift.hpp b/modules/reg/include/opencv2/reg/mappergradshift.hpp index a9f75b3a6..3a3642758 100644 --- a/modules/reg/include/opencv2/reg/mappergradshift.hpp +++ b/modules/reg/include/opencv2/reg/mappergradshift.hpp @@ -49,15 +49,15 @@ namespace reg { /*! * Gradient mapper for a translation */ -class CV_EXPORTS MapperGradShift: public Mapper +class CV_EXPORTS_W MapperGradShift: public Mapper { public: - MapperGradShift(void); - virtual ~MapperGradShift(void); + CV_WRAP MapperGradShift(); + virtual ~MapperGradShift(); - virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const; - cv::Ptr getMap(void) const; + CV_WRAP cv::Ptr getMap() const; }; //! @} diff --git a/modules/reg/include/opencv2/reg/mappergradsimilar.hpp b/modules/reg/include/opencv2/reg/mappergradsimilar.hpp index ea45ab912..6382180cc 100644 --- a/modules/reg/include/opencv2/reg/mappergradsimilar.hpp +++ b/modules/reg/include/opencv2/reg/mappergradsimilar.hpp @@ -49,15 +49,15 @@ namespace reg { /*! * Calculates a similarity transformation between to images (scale, rotation, and shift) */ -class CV_EXPORTS MapperGradSimilar: public Mapper +class CV_EXPORTS_W MapperGradSimilar: public Mapper { public: - MapperGradSimilar(void); - ~MapperGradSimilar(void); + CV_WRAP MapperGradSimilar(); + ~MapperGradSimilar(); - virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const; - cv::Ptr getMap(void) const; + CV_WRAP cv::Ptr getMap() const; }; //! @} diff --git a/modules/reg/include/opencv2/reg/mapperpyramid.hpp b/modules/reg/include/opencv2/reg/mapperpyramid.hpp index 33440bdae..f9fbd0181 100644 --- a/modules/reg/include/opencv2/reg/mapperpyramid.hpp +++ b/modules/reg/include/opencv2/reg/mapperpyramid.hpp @@ -39,7 +39,9 @@ #define MAPPERPYRAMID_H_ #include "mapper.hpp" - +#include "mapaffine.hpp" +#include "mapprojec.hpp" +#include "mapshift.hpp" namespace cv { namespace reg { @@ -50,27 +52,52 @@ namespace reg { /*! * Calculates a map using a gaussian pyramid */ -class CV_EXPORTS MapperPyramid: public Mapper +class CV_EXPORTS_W MapperPyramid: public Mapper { public: /* * Constructor * \param[in] baseMapper Base mapper used for the refinements */ - MapperPyramid(const Mapper& baseMapper); + CV_WRAP MapperPyramid(Ptr baseMapper); - void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr& res) const; + CV_WRAP virtual cv::Ptr calculate(InputArray img1, InputArray img2, cv::Ptr init = cv::Ptr()) const; - cv::Ptr getMap(void) const; + CV_WRAP cv::Ptr getMap() const; - unsigned numLev_; /*!< Number of levels of the pyramid */ - unsigned numIterPerScale_; /*!< Number of iterations at a given scale of the pyramid */ + CV_PROP_RW int numLev_; /*!< Number of levels of the pyramid */ + CV_PROP_RW int numIterPerScale_; /*!< Number of iterations at a given scale of the pyramid */ private: MapperPyramid& operator=(const MapperPyramid&); const Mapper& baseMapper_; /*!< Mapper used in inner level */ }; +/*! + * Converts a pointer to a Map returned by MapperPyramid::calculate into the specified Map pointer type + */ +class CV_EXPORTS_W MapTypeCaster +{ +public: + CV_WRAP static Ptr toAffine(Ptr sourceMap) + { + MapAffine& affineMap = dynamic_cast(*sourceMap); + return Ptr(new MapAffine(affineMap)); + } + + CV_WRAP static Ptr toShift(Ptr sourceMap) + { + MapShift& shiftMap = dynamic_cast(*sourceMap); + return Ptr(new MapShift(shiftMap)); + } + + CV_WRAP static Ptr toProjec(Ptr sourceMap) + { + MapProjec& projecMap = dynamic_cast(*sourceMap); + return Ptr(new MapProjec(projecMap)); + } +}; + //! @} }} // namespace cv::reg diff --git a/modules/reg/include/opencv2/reg/mapprojec.hpp b/modules/reg/include/opencv2/reg/mapprojec.hpp index 57ef14600..356b18552 100644 --- a/modules/reg/include/opencv2/reg/mapprojec.hpp +++ b/modules/reg/include/opencv2/reg/mapprojec.hpp @@ -50,13 +50,13 @@ namespace reg { /*! * Defines an transformation that consists on a projective transformation */ -class CV_EXPORTS MapProjec : public Map +class CV_EXPORTS_W MapProjec : public Map { public: /*! * Default constructor builds an identity map */ - MapProjec(void); + CV_WRAP MapProjec(); /*! * Constructor providing explicit values @@ -67,15 +67,15 @@ public: /*! * Destructor */ - ~MapProjec(void); + ~MapProjec(); - void inverseWarp(const cv::Mat& img1, cv::Mat& img2) const; + CV_WRAP void inverseWarp(InputArray img1, OutputArray img2) const; - cv::Ptr inverseMap(void) const; + CV_WRAP cv::Ptr inverseMap() const; - void compose(const Map& map); + CV_WRAP void compose(cv::Ptr map); - void scale(double factor); + CV_WRAP void scale(double factor); /*! * Returns projection matrix @@ -85,10 +85,14 @@ public: return projTr_; } + CV_WRAP void getProjTr(OutputArray projTr) const { + Mat(projTr_).copyTo(projTr); + } + /*! * Normalizes object's homography */ - void normalize(void) { + CV_WRAP void normalize() { double z = 1./projTr_(2, 2); for(size_t v_i = 0; v_i < sizeof(projTr_.val)/sizeof(projTr_.val[0]); ++v_i) projTr_.val[v_i] *= z; diff --git a/modules/reg/include/opencv2/reg/mapshift.hpp b/modules/reg/include/opencv2/reg/mapshift.hpp index e5f54a4ce..c7119440a 100644 --- a/modules/reg/include/opencv2/reg/mapshift.hpp +++ b/modules/reg/include/opencv2/reg/mapshift.hpp @@ -50,32 +50,33 @@ namespace reg { /*! * Defines an transformation that consists on a simple displacement */ -class CV_EXPORTS MapShift : public Map +class CV_EXPORTS_W MapShift : public Map { public: /*! * Default constructor builds an identity map */ - MapShift(void); + CV_WRAP MapShift(); /*! * Constructor providing explicit values * \param[in] shift Displacement */ - MapShift(const cv::Vec& shift); + + CV_WRAP MapShift(InputArray shift); /*! * Destructor */ - ~MapShift(void); + ~MapShift(); - void inverseWarp(const cv::Mat& img1, cv::Mat& img2) const; + CV_WRAP void inverseWarp(InputArray img1, OutputArray img2) const; - cv::Ptr inverseMap(void) const; + CV_WRAP cv::Ptr inverseMap() const; - void compose(const Map& map); + CV_WRAP void compose(cv::Ptr map); - void scale(double factor); + CV_WRAP void scale(double factor); /*! * Return displacement @@ -85,6 +86,10 @@ public: return shift_; } + CV_WRAP void getShift(OutputArray shift) const { + Mat(shift_).copyTo(shift); + } + private: cv::Vec shift_; /*< Displacement */ }; diff --git a/modules/reg/perf/perf_reg.cpp b/modules/reg/perf/perf_reg.cpp index 3622f4bed..c0e2ce934 100644 --- a/modules/reg/perf/perf_reg.cpp +++ b/modules/reg/perf/perf_reg.cpp @@ -72,10 +72,9 @@ Vec perfShift(const Mat& img1) mapTest.warp(img1, img2); // Register - MapperGradShift mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); MapShift* mapShift = dynamic_cast(mapPtr.get()); return mapShift->getShift(); @@ -96,10 +95,9 @@ Matx perfEuclidean(const Mat& img1) mapTest.warp(img1, img2); // Register - MapperGradEuclid mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); MapAffine* mapAff = dynamic_cast(mapPtr.get()); Matx resLinTr = mapAff->getLinTr(); @@ -127,10 +125,9 @@ Matx perfSimilarity(const Mat& img1) mapTest.warp(img1, img2); // Register - MapperGradSimilar mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); MapAffine* mapAff = dynamic_cast(mapPtr.get()); Matx resLinTr = mapAff->getLinTr(); @@ -154,10 +151,9 @@ Matx perfAffine(const Mat& img1) mapTest.warp(img1, img2); // Register - MapperGradAffine mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); MapAffine* mapAff = dynamic_cast(mapPtr.get()); Matx resLinTr = mapAff->getLinTr(); @@ -179,10 +175,9 @@ Matx perfProjective(const Mat& img1) mapTest.warp(img1, img2); // Register - MapperGradProj mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); MapProjec* mapProj = dynamic_cast(mapPtr.get()); mapProj->normalize(); diff --git a/modules/reg/samples/map_test.cpp b/modules/reg/samples/map_test.cpp index 607b3f289..c59ce96ed 100644 --- a/modules/reg/samples/map_test.cpp +++ b/modules/reg/samples/map_test.cpp @@ -99,10 +99,9 @@ static void testShift(const Mat& img1) showDifference(img1, img2, DIFF_IM); // Register - MapperGradShift mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result MapShift* mapShift = dynamic_cast(mapPtr.get()); @@ -135,10 +134,9 @@ static void testEuclidean(const Mat& img1) showDifference(img1, img2, DIFF_IM); // Register - MapperGradEuclid mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result MapAffine* mapAff = dynamic_cast(mapPtr.get()); @@ -174,10 +172,9 @@ static void testSimilarity(const Mat& img1) showDifference(img1, img2, DIFF_IM); // Register - MapperGradSimilar mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result MapAffine* mapAff = dynamic_cast(mapPtr.get()); @@ -209,10 +206,9 @@ static void testAffine(const Mat& img1) showDifference(img1, img2, DIFF_IM); // Register - MapperGradAffine mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result MapAffine* mapAff = dynamic_cast(mapPtr.get()); @@ -243,10 +239,9 @@ static void testProjective(const Mat& img1) showDifference(img1, img2, DIFF_IM); // Register - MapperGradProj mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result MapProjec* mapProj = dynamic_cast(mapPtr.get()); @@ -347,7 +342,7 @@ static void calcHomographyFeature(const Mat& image1, const Mat& image2) warpPerspective(image2, result, Hinv, image1.size()); cout << "--- Feature method\n" << H << endl; - + Mat imf1, resf; image1.convertTo(imf1, CV_64FC3); result.convertTo(resf, CV_64FC3); @@ -359,10 +354,9 @@ static void calcHomographyPixel(const Mat& img1, const Mat& img2) static const char* diffpixel = "Difference pixel registered"; // Register using pixel differences - MapperGradProj mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result MapProjec* mapProj = dynamic_cast(mapPtr.get()); @@ -398,7 +392,7 @@ static void comparePixelVsFeature(const Mat& img1_8b, const Mat& img2_8b) int main(void) { - Mat img1; + Mat img1; img1 = imread("home.png", CV_LOAD_IMAGE_UNCHANGED); if(!img1.data) { cout << "Could not open or find file" << endl; diff --git a/modules/reg/samples/reg_shift.py b/modules/reg/samples/reg_shift.py new file mode 100755 index 000000000..8ee415471 --- /dev/null +++ b/modules/reg/samples/reg_shift.py @@ -0,0 +1,20 @@ +#!/usr/bin/python + +import cv2 +import numpy as np +import sys + +img1 = cv2.imread(sys.argv[1]) +img1 = img1.astype(np.float32) +shift = np.array([5., 5.]) +mapTest = cv2.reg.MapShift(shift) + +img2 = mapTest.warp(img1) + +mapper = cv2.reg.MapperGradShift() +mappPyr = cv2.reg.MapperPyramid(mapper) + +resMap = mappPyr.calculate(img1, img2) +mapShift = cv2.reg.MapTypeCaster_toShift(resMap) + +print(mapShift.getShift()) diff --git a/modules/reg/src/map.cpp b/modules/reg/src/map.cpp index aff9700d6..58f872751 100644 --- a/modules/reg/src/map.cpp +++ b/modules/reg/src/map.cpp @@ -44,12 +44,12 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -Map::~Map(void) +Map::~Map() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Map::warp(const Mat& img1, Mat& img2) const +void Map::warp(InputArray img1, OutputArray img2) const { Ptr invMap(inverseMap()); invMap->inverseWarp(img1, img2); diff --git a/modules/reg/src/mapaffine.cpp b/modules/reg/src/mapaffine.cpp index 781ec24ad..b9d38d7b6 100644 --- a/modules/reg/src/mapaffine.cpp +++ b/modules/reg/src/mapaffine.cpp @@ -45,7 +45,7 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapAffine::MapAffine(void) +MapAffine::MapAffine() : linTr_(Matx::eye()), shift_() { } @@ -57,13 +57,14 @@ MapAffine::MapAffine(const Matx& linTr, const Vec& shif } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapAffine::~MapAffine(void) +MapAffine::~MapAffine() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapAffine::inverseWarp(const Mat& img1, Mat& img2) const +void MapAffine::inverseWarp(InputArray _img1, OutputArray img2) const { + Mat img1 = _img1.getMat(); // Rows and columns in destination Mat dest_r, dest_c; dest_r.create(img1.size(), CV_32FC1); @@ -93,10 +94,10 @@ Ptr MapAffine::inverseMap(void) const } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapAffine::compose(const Map& map) +void MapAffine::compose(cv::Ptr map) { // Composition of affine transformations T and T' is (T o T') = A'Ax + A'b + b' - const MapAffine& mapAff = static_cast(map); + const MapAffine& mapAff = static_cast(*map); Matx compMat = mapAff.getLinTr()*linTr_; Vec compShift = mapAff.getLinTr()*shift_ + mapAff.getShift(); linTr_ = compMat; diff --git a/modules/reg/src/mapper.cpp b/modules/reg/src/mapper.cpp index e338c6c51..a2eb4f2a4 100644 --- a/modules/reg/src/mapper.cpp +++ b/modules/reg/src/mapper.cpp @@ -59,28 +59,45 @@ void Mapper::gradient(const Mat& img1, const Mat& img2, Mat& Ix, Mat& Iy, Mat& I } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Mapper::grid(const Mat& img, Mat& grid_r, Mat& grid_c) const + +template +void fillGridMatrices(const Mat img, Mat grid_r, Mat grid_c) { - // Matrices with reference frame coordinates - grid_r.create(img.size(), img.type()); - grid_c.create(img.size(), img.type()); if(img.channels() == 1) { for(int r_i = 0; r_i < img.rows; ++r_i) { for(int c_i = 0; c_i < img.cols; ++c_i) { - grid_r.at(r_i, c_i) = r_i; - grid_c.at(r_i, c_i) = c_i; + grid_r.at<_Tp>(r_i, c_i) = (_Tp)r_i; + grid_c.at<_Tp>(r_i, c_i) = (_Tp)c_i; } } } else { - Vec3d ones(1., 1., 1.); + Vec<_Tp, 3> ones((_Tp)1, (_Tp)1, (_Tp)1); for(int r_i = 0; r_i < img.rows; ++r_i) { for(int c_i = 0; c_i < img.cols; ++c_i) { - grid_r.at(r_i, c_i) = r_i*ones; - grid_c.at(r_i, c_i) = c_i*ones; + grid_r.at< Vec<_Tp, 3> >(r_i, c_i) = (_Tp)r_i*ones; + grid_c.at< Vec<_Tp, 3> >(r_i, c_i) = (_Tp)c_i*ones; } } } } +void Mapper::grid(const Mat& img, Mat& grid_r, Mat& grid_c) const +{ + CV_DbgAssert(img.channels() == 1 || img.channels() == 3); + + // Matrices with reference frame coordinates + grid_r.create(img.size(), img.type()); + grid_c.create(img.size(), img.type()); + + if(img.depth() == CV_8U) + fillGridMatrices(img, grid_r, grid_c); + if(img.depth() == CV_16U) + fillGridMatrices(img, grid_r, grid_c); + else if(img.depth() == CV_32F) + fillGridMatrices(img, grid_r, grid_c); + else if(img.depth() == CV_64F) + fillGridMatrices(img, grid_r, grid_c); +} + }} // namespace cv::reg diff --git a/modules/reg/src/mappergradaffine.cpp b/modules/reg/src/mappergradaffine.cpp index fd698c452..77b537770 100644 --- a/modules/reg/src/mappergradaffine.cpp +++ b/modules/reg/src/mappergradaffine.cpp @@ -44,21 +44,21 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradAffine::MapperGradAffine(void) +MapperGradAffine::MapperGradAffine() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradAffine::~MapperGradAffine(void) +MapperGradAffine::~MapperGradAffine() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapperGradAffine::calculate( - const cv::Mat& img1, const cv::Mat& image2, cv::Ptr& res) const +cv::Ptr MapperGradAffine::calculate(InputArray _img1, InputArray image2, cv::Ptr init) const { + Mat img1 = _img1.getMat(); Mat gradx, grady, imgDiff; Mat img2; @@ -66,11 +66,11 @@ void MapperGradAffine::calculate( CV_DbgAssert(img1.channels() == image2.channels()); CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3); - if(!res.empty()) { + if(!init.empty()) { // We have initial values for the registration: we move img2 to that initial reference - res->inverseWarp(image2, img2); + init->inverseWarp(image2, img2); } else { - img2 = image2; + img2 = image2.getMat(); } // Get gradient in all channels @@ -145,16 +145,19 @@ void MapperGradAffine::calculate( Matx linTr(k(0) + 1., k(1), k(3), k(4) + 1.); Vec shift(k(2), k(5)); - if(res.empty()) { - res = Ptr(new MapAffine(linTr, shift)); + if(init.empty()) { + return Ptr(new MapAffine(linTr, shift)); } else { - MapAffine newTr(linTr, shift); - res->compose(newTr); + Ptr newTr(new MapAffine(linTr, shift)); + MapAffine* initPtr = dynamic_cast(init.get()); + Ptr oldTr(new MapAffine(initPtr->getLinTr(), initPtr->getShift())); + oldTr->compose(newTr); + return oldTr; } } //////////////////////////////////////////////////////////////////////////////////////////////////// -cv::Ptr MapperGradAffine::getMap(void) const +cv::Ptr MapperGradAffine::getMap() const { return cv::Ptr(new MapAffine()); } diff --git a/modules/reg/src/mappergradeuclid.cpp b/modules/reg/src/mappergradeuclid.cpp index 26557cbc4..2f126afb6 100644 --- a/modules/reg/src/mappergradeuclid.cpp +++ b/modules/reg/src/mappergradeuclid.cpp @@ -44,21 +44,22 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradEuclid::MapperGradEuclid(void) +MapperGradEuclid::MapperGradEuclid() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradEuclid::~MapperGradEuclid(void) +MapperGradEuclid::~MapperGradEuclid() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapperGradEuclid::calculate( - const cv::Mat& img1, const cv::Mat& image2, cv::Ptr& res) const +cv::Ptr MapperGradEuclid::calculate( + InputArray _img1, InputArray image2, cv::Ptr init) const { + Mat img1 = _img1.getMat(); Mat gradx, grady, imgDiff; Mat img2; @@ -66,11 +67,11 @@ void MapperGradEuclid::calculate( CV_DbgAssert(img1.channels() == image2.channels()); CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3); - if(!res.empty()) { + if(!init.empty()) { // We have initial values for the registration: we move img2 to that initial reference - res->inverseWarp(image2, img2); + init->inverseWarp(image2, img2); } else { - img2 = image2; + img2 = image2.getMat(); } // Matrices with reference frame coordinates @@ -111,16 +112,19 @@ void MapperGradEuclid::calculate( Matx linTr(cosT, -sinT, sinT, cosT); Vec shift(k(0), k(1)); - if(res.empty()) { - res = Ptr(new MapAffine(linTr, shift)); + if(init.empty()) { + return Ptr(new MapAffine(linTr, shift)); } else { - MapAffine newTr(linTr, shift); - res->compose(newTr); + Ptr newTr(new MapAffine(linTr, shift)); + MapAffine* initPtr = dynamic_cast(init.get()); + Ptr oldTr(new MapAffine(initPtr->getLinTr(), initPtr->getShift())); + oldTr->compose(newTr); + return oldTr; } } //////////////////////////////////////////////////////////////////////////////////////////////////// -cv::Ptr MapperGradEuclid::getMap(void) const +cv::Ptr MapperGradEuclid::getMap() const { return cv::Ptr(new MapAffine()); } diff --git a/modules/reg/src/mappergradproj.cpp b/modules/reg/src/mappergradproj.cpp index f0c9b5e57..f1a0f4b14 100644 --- a/modules/reg/src/mappergradproj.cpp +++ b/modules/reg/src/mappergradproj.cpp @@ -44,21 +44,22 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradProj::MapperGradProj(void) +MapperGradProj::MapperGradProj() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradProj::~MapperGradProj(void) +MapperGradProj::~MapperGradProj() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapperGradProj::calculate( - const cv::Mat& img1, const cv::Mat& image2, cv::Ptr& res) const +cv::Ptr MapperGradProj::calculate( + InputArray _img1, InputArray image2, cv::Ptr init) const { + Mat img1 = _img1.getMat(); Mat gradx, grady, imgDiff; Mat img2; @@ -66,11 +67,11 @@ void MapperGradProj::calculate( CV_DbgAssert(img1.channels() == image2.channels()); CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3); - if(!res.empty()) { + if(!init.empty()) { // We have initial values for the registration: we move img2 to that initial reference - res->inverseWarp(image2, img2); + init->inverseWarp(image2, img2); } else { - img2 = image2; + img2 = image2.getMat(); } // Get gradient in all channels @@ -195,16 +196,19 @@ void MapperGradProj::calculate( Vec k = A.inv(DECOMP_CHOLESKY)*b; Matx H(k(0) + 1., k(1), k(2), k(3), k(4) + 1., k(5), k(6), k(7), 1.); - if(res.empty()) { - res = Ptr(new MapProjec(H)); + if(init.empty()) { + return Ptr(new MapProjec(H)); } else { - MapProjec newTr(H); - res->compose(newTr); + Ptr newTr(new MapProjec(H)); + MapProjec* initPtr = dynamic_cast(init.get()); + Ptr oldTr(new MapProjec(initPtr->getProjTr())); + oldTr->compose(newTr); + return oldTr; } } //////////////////////////////////////////////////////////////////////////////////////////////////// -cv::Ptr MapperGradProj::getMap(void) const +cv::Ptr MapperGradProj::getMap() const { return cv::Ptr(new MapProjec()); } diff --git a/modules/reg/src/mappergradshift.cpp b/modules/reg/src/mappergradshift.cpp index 517a373cf..d77fb3c9d 100644 --- a/modules/reg/src/mappergradshift.cpp +++ b/modules/reg/src/mappergradshift.cpp @@ -44,31 +44,32 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradShift::MapperGradShift(void) +MapperGradShift::MapperGradShift() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradShift::~MapperGradShift(void) +MapperGradShift::~MapperGradShift() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapperGradShift::calculate( - const cv::Mat& img1, const cv::Mat& image2, cv::Ptr& res) const +cv::Ptr MapperGradShift::calculate( + InputArray _img1, InputArray image2, cv::Ptr init) const { + Mat img1 = _img1.getMat(); Mat gradx, grady, imgDiff; Mat img2; CV_DbgAssert(img1.size() == image2.size()); - if(!res.empty()) { + if(!init.empty()) { // We have initial values for the registration: we move img2 to that initial reference - res->inverseWarp(image2, img2); + init->inverseWarp(image2, img2); } else { - img2 = image2; + img2 = image2.getMat(); } // Get gradient in all channels @@ -92,16 +93,19 @@ void MapperGradShift::calculate( // Calculate shift. We use Cholesky decomposition, as A is symmetric. Vec shift = A.inv(DECOMP_CHOLESKY)*b; - if(res.empty()) { - res = Ptr(new MapShift(shift)); + if(init.empty()) { + return Ptr(new MapShift(shift)); } else { - MapShift newTr(shift); - res->compose(newTr); + Ptr newTr(new MapShift(shift)); + MapShift* initPtr = dynamic_cast(init.get()); + Ptr oldTr(new MapShift(initPtr->getShift())); + oldTr->compose(newTr); + return oldTr; } } //////////////////////////////////////////////////////////////////////////////////////////////////// -cv::Ptr MapperGradShift::getMap(void) const +cv::Ptr MapperGradShift::getMap() const { return cv::Ptr(new MapShift()); } diff --git a/modules/reg/src/mappergradsimilar.cpp b/modules/reg/src/mappergradsimilar.cpp index 0b7a615a3..1a401908c 100644 --- a/modules/reg/src/mappergradsimilar.cpp +++ b/modules/reg/src/mappergradsimilar.cpp @@ -44,21 +44,22 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradSimilar::MapperGradSimilar(void) +MapperGradSimilar::MapperGradSimilar() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperGradSimilar::~MapperGradSimilar(void) +MapperGradSimilar::~MapperGradSimilar() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapperGradSimilar::calculate( - const cv::Mat& img1, const cv::Mat& image2, cv::Ptr& res) const +cv::Ptr MapperGradSimilar::calculate( + InputArray _img1, InputArray image2, cv::Ptr init) const { + Mat img1 = _img1.getMat(); Mat gradx, grady, imgDiff; Mat img2; @@ -66,11 +67,11 @@ void MapperGradSimilar::calculate( CV_DbgAssert(img1.channels() == image2.channels()); CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3); - if(!res.empty()) { + if(!init.empty()) { // We have initial values for the registration: we move img2 to that initial reference - res->inverseWarp(image2, img2); + init->inverseWarp(image2, img2); } else { - img2 = image2; + img2 = image2.getMat(); } // Get gradient in all channels @@ -126,16 +127,19 @@ void MapperGradSimilar::calculate( Matx linTr(k(0) + 1., k(1), -k(1), k(0) + 1.); Vec shift(k(2), k(3)); - if(res.empty()) { - res = Ptr(new MapAffine(linTr, shift)); + if(init.empty()) { + return Ptr(new MapAffine(linTr, shift)); } else { - MapAffine newTr(linTr, shift); - res->compose(newTr); + Ptr newTr(new MapAffine(linTr, shift)); + MapAffine* initPtr = dynamic_cast(init.get()); + Ptr oldTr(new MapAffine(initPtr->getLinTr(), initPtr->getShift())); + oldTr->compose(newTr); + return oldTr; } } //////////////////////////////////////////////////////////////////////////////////////////////////// -cv::Ptr MapperGradSimilar::getMap(void) const +cv::Ptr MapperGradSimilar::getMap() const { return cv::Ptr(new MapAffine()); } diff --git a/modules/reg/src/mapperpyramid.cpp b/modules/reg/src/mapperpyramid.cpp index 88c401880..4ec40be5d 100644 --- a/modules/reg/src/mapperpyramid.cpp +++ b/modules/reg/src/mapperpyramid.cpp @@ -48,22 +48,23 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapperPyramid::MapperPyramid(const Mapper& baseMapper) - : numLev_(3), numIterPerScale_(3), baseMapper_(baseMapper) +MapperPyramid::MapperPyramid(Ptr baseMapper) + : numLev_(3), numIterPerScale_(3), baseMapper_(*baseMapper) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapperPyramid::calculate(const Mat& img1, const Mat& image2, Ptr& res) const +Ptr MapperPyramid::calculate(InputArray _img1, InputArray image2, Ptr init) const { + Mat img1 = _img1.getMat(); Mat img2; - if(!res.empty()) { + if(!init.empty()) { // We have initial values for the registration: we move img2 to that initial reference - res->inverseWarp(image2, img2); + init->inverseWarp(image2, img2); } else { - res = baseMapper_.getMap(); - img2 = image2; + init = baseMapper_.getMap(); + img2 = image2.getMat(); } cv::Ptr ident = baseMapper_.getMap(); @@ -72,29 +73,30 @@ void MapperPyramid::calculate(const Mat& img1, const Mat& image2, Ptr& res) vector pyrIm1(numLev_), pyrIm2(numLev_); pyrIm1[0] = img1; pyrIm2[0] = img2; - for(size_t im_i = 1; im_i < numLev_; ++im_i) { + for(int im_i = 1; im_i < numLev_; ++im_i) { pyrDown(pyrIm1[im_i - 1], pyrIm1[im_i]); pyrDown(pyrIm2[im_i - 1], pyrIm2[im_i]); } Mat currRef, currImg; - for(size_t lv_i = 0; lv_i < numLev_; ++lv_i) { + for(int lv_i = 0; lv_i < numLev_; ++lv_i) { currRef = pyrIm1[numLev_ - 1 - lv_i]; currImg = pyrIm2[numLev_ - 1 - lv_i]; // Scale the transformation as we are incresing the resolution in each iteration if(lv_i != 0) { ident->scale(2.); } - for(size_t it_i = 0; it_i < numIterPerScale_; ++it_i) { - baseMapper_.calculate(currRef, currImg, ident); + for(int it_i = 0; it_i < numIterPerScale_; ++it_i) { + ident = baseMapper_.calculate(currRef, currImg, ident); } } - res->compose(*ident.get()); + init->compose(ident); + return init; } //////////////////////////////////////////////////////////////////////////////////////////////////// -cv::Ptr MapperPyramid::getMap(void) const +cv::Ptr MapperPyramid::getMap() const { return cv::Ptr(); } diff --git a/modules/reg/src/mapprojec.cpp b/modules/reg/src/mapprojec.cpp index 7d5becfe6..9b653b443 100644 --- a/modules/reg/src/mapprojec.cpp +++ b/modules/reg/src/mapprojec.cpp @@ -45,7 +45,7 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapProjec::MapProjec(void) +MapProjec::MapProjec() : projTr_(Matx::eye()) { } @@ -57,13 +57,14 @@ MapProjec::MapProjec(const Matx& projTr) } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapProjec::~MapProjec(void) +MapProjec::~MapProjec() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapProjec::inverseWarp(const Mat& img1, Mat& img2) const +void MapProjec::inverseWarp(InputArray _img1, OutputArray img2) const { + Mat img1 = _img1.getMat(); // Rows and columns in destination Mat dest_r, dest_c; dest_r.create(img1.size(), CV_32FC1); @@ -95,10 +96,10 @@ Ptr MapProjec::inverseMap(void) const } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapProjec::compose(const Map& map) +void MapProjec::compose(Ptr map) { // Composition of homographies H and H' is (H o H') = H'*H - const MapProjec& mapProj = static_cast(map); + const MapProjec& mapProj = static_cast(*map); Matx compProjTr = mapProj.getProjTr()*projTr_; projTr_ = compProjTr; } diff --git a/modules/reg/src/mapshift.cpp b/modules/reg/src/mapshift.cpp index 81262e881..9952eb97f 100644 --- a/modules/reg/src/mapshift.cpp +++ b/modules/reg/src/mapshift.cpp @@ -46,23 +46,26 @@ namespace reg { //////////////////////////////////////////////////////////////////////////////////////////////////// -MapShift::MapShift(void) : shift_() +MapShift::MapShift() : shift_() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapShift::MapShift(const Vec& shift) : shift_(shift) +MapShift::MapShift(InputArray shift) { + Mat shiftMat = shift.getMat(); + shiftMat.copyTo(shift_); } //////////////////////////////////////////////////////////////////////////////////////////////////// -MapShift::~MapShift(void) +MapShift::~MapShift() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapShift::inverseWarp(const Mat& img1, Mat& img2) const +void MapShift::inverseWarp(InputArray _img1, OutputArray img2) const { + Mat img1 = _img1.getMat(); // Rows and columns in destination Mat dest_r, dest_c; dest_r.create(img1.size(), CV_32FC1); @@ -91,10 +94,10 @@ Ptr MapShift::inverseMap(void) const } //////////////////////////////////////////////////////////////////////////////////////////////////// -void MapShift::compose(const Map& map) +void MapShift::compose(cv::Ptr map) { // Composition of transformations T and T' is (T o T') = b + b' - const MapShift& mapShift = static_cast(map); + const MapShift& mapShift = static_cast(*map); shift_ += mapShift.getShift(); } diff --git a/modules/reg/test/test_reg.cpp b/modules/reg/test/test_reg.cpp index 44b19d8ca..cae7e7f23 100644 --- a/modules/reg/test/test_reg.cpp +++ b/modules/reg/test/test_reg.cpp @@ -59,11 +59,13 @@ using namespace std; using namespace cv; using namespace cv::reg; +#define REG_DEBUG_OUTPUT 0 + class RegTest : public testing::Test { public: - void loadImage(); + void loadImage(int dstDataType = CV_32FC3); void testShift(); void testEuclidean(); @@ -84,20 +86,20 @@ void RegTest::testShift() mapTest.warp(img1, img2); // Register - MapperGradShift mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result - MapShift* mapShift = dynamic_cast(mapPtr.get()); + Ptr mapShift = MapTypeCaster::toShift(mapPtr); +#if REG_DEBUG_OUTPUT cout << endl << "--- Testing shift mapper ---" << endl; cout << Mat(shift) << endl; cout << Mat(mapShift->getShift()) << endl; - +#endif // Check accuracy Ptr mapInv(mapShift->inverseMap()); - mapTest.compose(*mapInv.get()); + mapTest.compose(mapInv); double shNorm = norm(mapTest.getShift()); EXPECT_LE(shNorm, 0.1); } @@ -116,22 +118,22 @@ void RegTest::testEuclidean() mapTest.warp(img1, img2); // Register - MapperGradEuclid mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result - MapAffine* mapAff = dynamic_cast(mapPtr.get()); + Ptr mapAff = MapTypeCaster::toAffine(mapPtr); +#if REG_DEBUG_OUTPUT cout << endl << "--- Testing Euclidean mapper ---" << endl; cout << Mat(linTr) << endl; cout << Mat(shift) << endl; cout << Mat(mapAff->getLinTr()) << endl; cout << Mat(mapAff->getShift()) << endl; - +#endif // Check accuracy Ptr mapInv(mapAff->inverseMap()); - mapTest.compose(*mapInv.get()); + mapTest.compose(mapInv); double shNorm = norm(mapTest.getShift()); EXPECT_LE(shNorm, 0.1); double linTrNorm = norm(mapTest.getLinTr()); @@ -154,22 +156,23 @@ void RegTest::testSimilarity() mapTest.warp(img1, img2); // Register - MapperGradSimilar mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result - MapAffine* mapAff = dynamic_cast(mapPtr.get()); + Ptr mapAff = MapTypeCaster::toAffine(mapPtr); +#if REG_DEBUG_OUTPUT cout << endl << "--- Testing similarity mapper ---" << endl; cout << Mat(linTr) << endl; cout << Mat(shift) << endl; cout << Mat(mapAff->getLinTr()) << endl; cout << Mat(mapAff->getShift()) << endl; +#endif // Check accuracy Ptr mapInv(mapAff->inverseMap()); - mapTest.compose(*mapInv.get()); + mapTest.compose(mapInv); double shNorm = norm(mapTest.getShift()); EXPECT_LE(shNorm, 0.1); double linTrNorm = norm(mapTest.getLinTr()); @@ -188,22 +191,23 @@ void RegTest::testAffine() mapTest.warp(img1, img2); // Register - MapperGradAffine mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result - MapAffine* mapAff = dynamic_cast(mapPtr.get()); + Ptr mapAff = MapTypeCaster::toAffine(mapPtr); +#if REG_DEBUG_OUTPUT cout << endl << "--- Testing affine mapper ---" << endl; cout << Mat(linTr) << endl; cout << Mat(shift) << endl; cout << Mat(mapAff->getLinTr()) << endl; cout << Mat(mapAff->getShift()) << endl; +#endif // Check accuracy Ptr mapInv(mapAff->inverseMap()); - mapTest.compose(*mapInv.get()); + mapTest.compose(mapInv); double shNorm = norm(mapTest.getShift()); EXPECT_LE(shNorm, 0.1); double linTrNorm = norm(mapTest.getLinTr()); @@ -222,34 +226,34 @@ void RegTest::testProjective() mapTest.warp(img1, img2); // Register - MapperGradProj mapper; + Ptr mapper = makePtr(); MapperPyramid mappPyr(mapper); - Ptr mapPtr; - mappPyr.calculate(img1, img2, mapPtr); + Ptr mapPtr = mappPyr.calculate(img1, img2); // Print result - MapProjec* mapProj = dynamic_cast(mapPtr.get()); + Ptr mapProj = MapTypeCaster::toProjec(mapPtr); mapProj->normalize(); +#if REG_DEBUG_OUTPUT cout << endl << "--- Testing projective transformation mapper ---" << endl; cout << Mat(projTr) << endl; cout << Mat(mapProj->getProjTr()) << endl; +#endif // Check accuracy Ptr mapInv(mapProj->inverseMap()); - mapTest.compose(*mapInv.get()); + mapTest.compose(mapInv); double projNorm = norm(mapTest.getProjTr()); EXPECT_LE(projNorm, sqrt(3.) + 0.01); EXPECT_GE(projNorm, sqrt(3.) - 0.01); } -void RegTest::loadImage() +void RegTest::loadImage(int dstDataType) { const string imageName = cvtest::TS::ptr()->get_data_path() + "reg/home.png"; img1 = imread(imageName, -1); - ASSERT_TRUE(img1.data != 0); - // Convert to double, 3 channels - img1.convertTo(img1, CV_64FC3); + ASSERT_TRUE(!img1.empty()); + img1.convertTo(img1, dstDataType); } @@ -282,3 +286,15 @@ TEST_F(RegTest, projective) loadImage(); testProjective(); } + +TEST_F(RegTest, projective_dt64fc3) +{ + loadImage(CV_64FC3); + testProjective(); +} + +TEST_F(RegTest, projective_dt64fc1) +{ + loadImage(CV_64FC1); + testProjective(); +}