vendor: OpenCV 5.0.0 snapshot at 755e50675d97db9b7d449d8bd6b09888646f6c6e

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:11:13 +08:00
commit 12022378a3
3872 changed files with 2513409 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
set(the_description "Image Registration")
ocv_define_module(reg opencv_imgproc opencv_core WRAP python)
+100
View File
@@ -0,0 +1,100 @@
OpenCV pixel-intensity based registration module
================================================
Author and maintainer: Alfonso Sanchez-Beato
alfonsosanchezbeato\_\_\_\_gmail.com
These classes implement a module for OpenCV for parametric image registration.
The implemented method is direct alignment, that is, it uses directly the pixel
values for calculating the registration between a pair of images, as opposed to
feature-based registration. The implementation follows essentially the
corresponding part of the paper "Image Alignment and Stitching: A Tutorial",
from Richard Szeliski.
Feature based methods have some advantages over pixel based methods when we are
trying to register pictures that have been shoot under different lighting
conditions or exposition times, or when the images overlap only partially. On
the other hand, the main advantage of pixel-based methods when compared to
feature based methods is their better precision for some pictures (those shoot
under similar lighting conditions and that have a significative overlap), due to
the fact that we are using all the information available in the image, which
allows us to achieve subpixel accuracy. This is particularly important for
certain applications like multi-frame denoising or super-resolution.
In fact, pixel and feature registration methods can complement each other: an
application could first obtain a coarse registration using features and then
refine the registration using a pixel based method on the overlapping area of
the images. The code developed allows this use case.
The module implements classes derived from the abstract classes cv::reg::Map or
cv::reg::Mapper. The former models a coordinate transformation between two
reference frames, while the later encapsulates a way of invoking a method that
calculates a Map between two images. Although the objective has been to
implement pixel based methods, the module could be extended to support other
methods that can calculate transformations between images (feature methods,
optical flow, etc.).
Each class derived from Map implements a motion model, as follows:
* MapShift: Models a simple translation
* MapAffine: Models an affine transformation
* MapProject: Models a projective transformation
MapProject can also be used to model affine motion or translations, but some
operations on it are more costly, and that is the reason for defining the other
two classes.
The classes derived from Mapper are
* MapperGradShift: Gradient based alignment for calculating translations. It
produces a MapShift (two parameters that correspond to the shift vector).
* MapperGradEuclid: Gradient based alignment for euclidean motions, that is,
rotations and translations. It calculates three parameters (angle and shift
vector), although the result is stored in a MapAffine object for convenience.
* MapperGradSimilar: Gradient based alignment for calculating similarities,
which adds scaling to the euclidean motion. It calculates four parameters (two
for the anti-symmetric matrix and two for the shift vector), although the result
is stored in a MapAffine object for convenience.
* MapperGradAffine: Gradient based alignment for an affine motion model. The
number of parameters is six and the result is stored in a MapAffine object.
* MapperGradProj: Gradient based alignment for calculating projective
transformations. The number of parameters is eight and the result is stored in a
MapProject object.
* MapperPyramid: It implements hyerarchical motion estimation using a Gaussian
pyramid. Its constructor accepts as argument any other object that implements
the Mapper interface, and it is that mapper the one called by MapperPyramid for
each scale of the pyramid.
If the motion between the images is not very small, the normal way of using
these classes is to create a MapperGrad\* object and use it as input to create a
MapperPyramid, which in turn is called to perform the calculation. However, if
the motion between the images is small enough, we can use directly the
MapperGrad\* classes. Another possibility is to use first a feature based method
to perform a coarse registration and then do a refinement through MapperPyramid
or directly a MapperGrad\* object. The "calculate" method of the mappers accepts
an initial estimation of the motion as input.
When deciding which MapperGrad to use we must take into account that mappers
with more parameters can handle more complex motions, but involve more
calculations and are therefore slower. Also, if we are confident on the motion
model that is followed by the sequence, increasing the number of parameters
beyond what we need will decrease the accuracy: it is better to use the least
number of degrees of freedom that we can.
In the file map_test.cpp some examples on how to use this module can be seen.
There is a test function for each MapperGrad\*. A motion is simulated on an input
image and then we register the moved image using a MapperPyramid created with
the right MapperGrad\*. The difference images of the pictures before and after
registering are displayed, and the ground truth parameters and the calculated
ones are printed. Additionally, two images from a real video are registered
using first SURF features and then MapperGradProj+MapperPyramid. The difference
between the images and the difference of the registered images using the two
methods are displayed. It can be seen in the differences shown that using a
pixel based difference we can achieve more accuracy.
+10
View File
@@ -0,0 +1,10 @@
@article{Szeliski06,
title={Image alignment and stitching: A tutorial},
author={Szeliski, Richard},
journal={Foundations and Trends{\textregistered} in Computer Graphics and Vision},
volume={2},
number={1},
pages={1--104},
year={2006},
publisher={Now Publishers Inc.}
}
+175
View File
@@ -0,0 +1,175 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAP_H_
#define MAP_H_
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
/** @defgroup reg Image Registration
The Registration module implements parametric image registration. The implemented method is direct
alignment, that is, it uses directly the pixel values for calculating the registration between a
pair of images, as opposed to feature-based registration. The implementation follows essentially the
corresponding part of @cite Szeliski06 .
Feature based methods have some advantages over pixel based methods when we are trying to register
pictures that have been shoot under different lighting conditions or exposition times, or when the
images overlap only partially. On the other hand, the main advantage of pixel-based methods when
compared to feature based methods is their better precision for some pictures (those shoot under
similar lighting conditions and that have a significative overlap), due to the fact that we are
using all the information available in the image, which allows us to achieve subpixel accuracy. This
is particularly important for certain applications like multi-frame denoising or super-resolution.
In fact, pixel and feature registration methods can complement each other: an application could
first obtain a coarse registration using features and then refine the registration using a pixel
based method on the overlapping area of the images. The code developed allows this use case.
The module implements classes derived from the abstract classes cv::reg::Map or cv::reg::Mapper. The
former models a coordinate transformation between two reference frames, while the later encapsulates
a way of invoking a method that calculates a Map between two images. Although the objective has been
to implement pixel based methods, the module can be extended to support other methods that can
calculate transformations between images (feature methods, optical flow, etc.).
Each class derived from Map implements a motion model, as follows:
- MapShift: Models a simple translation
- MapAffine: Models an affine transformation
- MapProjec: Models a projective transformation
MapProject can also be used to model affine motion or translations, but some operations on it are
more costly, and that is the reason for defining the other two classes.
The classes derived from Mapper are
- MapperGradShift: Gradient based alignment for calculating translations. It produces a MapShift
(two parameters that correspond to the shift vector).
- MapperGradEuclid: Gradient based alignment for euclidean motions, that is, rotations and
translations. It calculates three parameters (angle and shift vector), although the result is
stored in a MapAffine object for convenience.
- MapperGradSimilar: Gradient based alignment for calculating similarities, which adds scaling to
the euclidean motion. It calculates four parameters (two for the anti-symmetric matrix and two
for the shift vector), although the result is stored in a MapAffine object for better
convenience.
- MapperGradAffine: Gradient based alignment for an affine motion model. The number of parameters
is six and the result is stored in a MapAffine object.
- MapperGradProj: Gradient based alignment for calculating projective transformations. The number
of parameters is eight and the result is stored in a MapProject object.
- MapperPyramid: It implements hyerarchical motion estimation using a Gaussian pyramid. Its
constructor accepts as argument any other object that implements the Mapper interface, and it is
that mapper the one called by MapperPyramid for each scale of the pyramid.
If the motion between the images is not very small, the normal way of using these classes is to
create a MapperGrad\* object and use it as input to create a MapperPyramid, which in turn is called
to perform the calculation. However, if the motion between the images is small enough, we can use
directly the MapperGrad\* classes. Another possibility is to use first a feature based method to
perform a coarse registration and then do a refinement through MapperPyramid or directly a
MapperGrad\* object. The "calculate" method of the mappers accepts an initial estimation of the
motion as input.
When deciding which MapperGrad to use we must take into account that mappers with more parameters
can handle more complex motions, but involve more calculations and are therefore slower. Also, if we
are confident on the motion model that is followed by the sequence, increasing the number of
parameters beyond what we need will decrease the accuracy: it is better to use the least number of
degrees of freedom that we can.
In the module tests there are examples that show how to register a pair of images using any of the
implemented mappers.
*/
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/** @brief Base class for modelling a Map between two images.
The class is only used to define the common interface for any possible map.
*/
class CV_EXPORTS_W Map
{
public:
/*!
* Virtual destructor
*/
virtual ~Map();
/*!
* Warps image to a new coordinate frame. The calculation is img2(x)=img1(T^{-1}(x)), as we
* have to apply the inverse transformation to the points to move them to were the values
* of img2 are.
* \param[in] img1 Original image
* \param[out] img2 Warped image
*/
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
* this is the inverse warping as we are taking the value of img1 with the forward
* transformation of the points.
* \param[in] img1 Original image
* \param[out] img2 Warped image
*/
CV_WRAP virtual void inverseWarp(InputArray img1, OutputArray img2) const = 0;
/*!
* Calculates the inverse map
* \return Inverse map
*/
CV_WRAP virtual cv::Ptr<Map> 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.
*/
CV_WRAP virtual void compose(cv::Ptr<Map> 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
*/
CV_WRAP virtual void scale(double factor) = 0;
};
//! @}
}} // namespace cv::reg
#endif // MAP_H_
@@ -0,0 +1,113 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPAFFINE_H_
#define MAPAFFINE_H_
#include "map.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Defines an affine transformation
*/
class CV_EXPORTS_W MapAffine : public Map
{
public:
/*!
* Default constructor builds an identity map
*/
CV_WRAP MapAffine();
/*!
* Constructor providing explicit values
* \param[in] linTr Linear part of the affine transformation
* \param[in] shift Displacement part of the affine transformation
*/
CV_WRAP MapAffine(InputArray linTr, InputArray shift);
/*!
* Destructor
*/
~MapAffine();
CV_WRAP void inverseWarp(InputArray img1, OutputArray img2) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> inverseMap() const CV_OVERRIDE;
CV_WRAP void compose(cv::Ptr<Map> map) CV_OVERRIDE;
CV_WRAP void scale(double factor) CV_OVERRIDE;
/*!
* Return linear part of the affine transformation
* \return Linear part of the affine transformation
*/
const cv::Matx<double, 2, 2>& getLinTr() const {
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
*/
const cv::Vec<double, 2>& getShift() const {
return shift_;
}
CV_WRAP void getShift(OutputArray shift) const {
Mat(shift_).copyTo(shift);
}
private:
cv::Matx<double, 2, 2> linTr_;
cv::Vec<double, 2> shift_;
};
//! @}
}} // namespace cv::reg
#endif // MAPAFFINE_H_
+113
View File
@@ -0,0 +1,113 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPER_H_
#define MAPPER_H_
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
#include "map.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/** @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_W Mapper
{
public:
virtual ~Mapper(void) {}
/*
* Calculate mapping between two images
* \param[in] img1 Reference image
* \param[in] img2 Warped image
* \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.
*/
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const = 0;
/*
* Returns a map compatible with the Mapper class
* \return Pointer to identity Map
*/
CV_WRAP virtual cv::Ptr<Map> getMap() const = 0;
protected:
/*
* Calculates gradient and difference between images
* \param[in] img1 Image one
* \param[in] img2 Image two
* \param[out] Ix Gradient x-coordinate
* \param[out] Iy Gradient y-coordinate
* \param[out] It Difference of images
*/
void gradient(const cv::Mat& img1, const cv::Mat& img2,
cv::Mat& Ix, cv::Mat& Iy, cv::Mat& It) const;
/*
* Fills matrices with pixel coordinates of an image
* \param[in] img Image
* \param[out] grid_r Row (y-coordinate)
* \param[out] grid_c Column (x-coordinate)
*/
void grid(const Mat& img, Mat& grid_r, Mat& grid_c) const;
/*
* Per-element square of a matrix
* \param[in] mat1 Input matrix
* \return mat1[i,j]^2
*/
cv::Mat sqr(const cv::Mat& mat1) const
{
cv::Mat res;
res.create(mat1.size(), mat1.type());
res = mat1.mul(mat1);
return res;
}
};
//! @}
}} // namespace cv::reg
#endif // MAPPER_H_
@@ -0,0 +1,67 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPERGRADAFFINE_H_
#define MAPPERGRADAFFINE_H_
#include "mapper.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Mapper for affine motion
*/
class CV_EXPORTS_W MapperGradAffine: public Mapper
{
public:
CV_WRAP MapperGradAffine();
~MapperGradAffine(void);
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> getMap() const CV_OVERRIDE;
};
//! @}
}} // namespace cv::reg
#endif // MAPPERGRADAFFINE_H_
@@ -0,0 +1,67 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPERGRADEUCLID_H_
#define MAPPERGRADEUCLID_H_
#include "mapper.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Mapper for euclidean motion: rotation plus shift
*/
class CV_EXPORTS_W MapperGradEuclid: public Mapper
{
public:
CV_WRAP MapperGradEuclid();
~MapperGradEuclid();
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> getMap() const CV_OVERRIDE;
};
//! @}
}} // namespace cv::reg
#endif // MAPPERGRADEUCLID_H_
@@ -0,0 +1,67 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPERGRADPROJ_H_
#define MAPPERGRADPROJ_H_
#include "mapper.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Gradient mapper for a projective transformation
*/
class CV_EXPORTS_W MapperGradProj: public Mapper
{
public:
CV_WRAP MapperGradProj();
~MapperGradProj();
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> getMap() const CV_OVERRIDE;
};
//! @}
}} // namespace cv::reg
#endif // MAPPERGRADPROJ_H_
@@ -0,0 +1,67 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPERGRADSHIFT_H_
#define MAPPERGRADSHIFT_H_
#include "mapper.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Gradient mapper for a translation
*/
class CV_EXPORTS_W MapperGradShift: public Mapper
{
public:
CV_WRAP MapperGradShift();
virtual ~MapperGradShift();
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> getMap() const CV_OVERRIDE;
};
//! @}
}} // namespace cv::reg
#endif // MAPPERGRADSHIFT_H_
@@ -0,0 +1,67 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPERGRADSIMILAR_H_
#define MAPPERGRADSIMILAR_H_
#include "mapper.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Calculates a similarity transformation between to images (scale, rotation, and shift)
*/
class CV_EXPORTS_W MapperGradSimilar: public Mapper
{
public:
CV_WRAP MapperGradSimilar();
~MapperGradSimilar();
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> getMap() const CV_OVERRIDE;
};
//! @}
}} // namespace cv::reg
#endif // MAPPERGRADSIMILAR_H_
@@ -0,0 +1,105 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPERPYRAMID_H_
#define MAPPERPYRAMID_H_
#include "mapper.hpp"
#include "mapaffine.hpp"
#include "mapprojec.hpp"
#include "mapshift.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Calculates a map using a gaussian pyramid
*/
class CV_EXPORTS_W MapperPyramid: public Mapper
{
public:
/*
* Constructor
* \param[in] baseMapper Base mapper used for the refinements
*/
CV_WRAP MapperPyramid(Ptr<Mapper> baseMapper);
CV_WRAP virtual cv::Ptr<Map> calculate(InputArray img1, InputArray img2, cv::Ptr<Map> init = cv::Ptr<Map>()) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> getMap() const CV_OVERRIDE;
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<MapAffine> toAffine(Ptr<Map> sourceMap)
{
MapAffine& affineMap = dynamic_cast<MapAffine&>(*sourceMap);
return Ptr<MapAffine>(new MapAffine(affineMap));
}
CV_WRAP static Ptr<MapShift> toShift(Ptr<Map> sourceMap)
{
MapShift& shiftMap = dynamic_cast<MapShift&>(*sourceMap);
return Ptr<MapShift>(new MapShift(shiftMap));
}
CV_WRAP static Ptr<MapProjec> toProjec(Ptr<Map> sourceMap)
{
MapProjec& projecMap = dynamic_cast<MapProjec&>(*sourceMap);
return Ptr<MapProjec>(new MapProjec(projecMap));
}
};
//! @}
}} // namespace cv::reg
#endif // MAPPERPYRAMID_H_
@@ -0,0 +1,109 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPPROJEC_H_
#define MAPPROJEC_H_
#include "map.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Defines an transformation that consists on a projective transformation
*/
class CV_EXPORTS_W MapProjec : public Map
{
public:
/*!
* Default constructor builds an identity map
*/
CV_WRAP MapProjec();
/*!
* Constructor providing explicit values
* \param[in] projTr Projective transformation
*/
CV_WRAP MapProjec(InputArray projTr);
/*!
* Destructor
*/
~MapProjec();
CV_WRAP void inverseWarp(InputArray img1, OutputArray img2) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> inverseMap() const CV_OVERRIDE;
CV_WRAP void compose(cv::Ptr<Map> map) CV_OVERRIDE;
CV_WRAP void scale(double factor) CV_OVERRIDE;
/*!
* Returns projection matrix
* \return Projection matrix
*/
const cv::Matx<double, 3, 3>& getProjTr() const {
return projTr_;
}
CV_WRAP void getProjTr(OutputArray projTr) const {
Mat(projTr_).copyTo(projTr);
}
/*!
* Normalizes object's homography
*/
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;
}
private:
cv::Matx<double, 3, 3> projTr_; /*< Projection matrix */
};
//! @}
}} // namespace cv::reg
#endif // MAPPROJEC_H_
@@ -0,0 +1,101 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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 MAPSHIFT_H_
#define MAPSHIFT_H_
#include "map.hpp"
namespace cv {
namespace reg {
//! @addtogroup reg
//! @{
/*!
* Defines an transformation that consists on a simple displacement
*/
class CV_EXPORTS_W MapShift : public Map
{
public:
/*!
* Default constructor builds an identity map
*/
CV_WRAP MapShift();
/*!
* Constructor providing explicit values
* \param[in] shift Displacement
*/
CV_WRAP MapShift(InputArray shift);
/*!
* Destructor
*/
~MapShift();
CV_WRAP void inverseWarp(InputArray img1, OutputArray img2) const CV_OVERRIDE;
CV_WRAP cv::Ptr<Map> inverseMap() const CV_OVERRIDE;
CV_WRAP void compose(cv::Ptr<Map> map) CV_OVERRIDE;
CV_WRAP void scale(double factor) CV_OVERRIDE;
/*!
* Return displacement
* \return Displacement
*/
const cv::Vec<double, 2>& getShift() const {
return shift_;
}
CV_WRAP void getShift(OutputArray shift) const {
Mat(shift_).copyTo(shift);
}
private:
cv::Vec<double, 2> shift_; /*< Displacement */
};
//! @}
}} // namespace cv::reg
#endif // MAPSHIFT_H_
+48
View File
@@ -0,0 +1,48 @@
/*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.
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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*/
#include "perf_precomp.hpp"
using namespace perf;
CV_PERF_TEST_MAIN(reg)
+62
View File
@@ -0,0 +1,62 @@
/*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.
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/reg/mapaffine.hpp"
#include "opencv2/reg/mapshift.hpp"
#include "opencv2/reg/mapprojec.hpp"
#include "opencv2/reg/mappergradshift.hpp"
#include "opencv2/reg/mappergradeuclid.hpp"
#include "opencv2/reg/mappergradsimilar.hpp"
#include "opencv2/reg/mappergradaffine.hpp"
#include "opencv2/reg/mappergradproj.hpp"
#include "opencv2/reg/mapperpyramid.hpp"
namespace opencv_test {
using namespace cv::reg;
}
#endif
+263
View File
@@ -0,0 +1,263 @@
/*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.
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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*/
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
using namespace perf;
Vec<double, 2> perfShift(const Mat& img1)
{
Mat img2;
// Warp original image
Vec<double, 2> shift(5., 5.);
MapShift mapTest(shift);
mapTest.warp(img1, img2);
// Register
Ptr<MapperGradShift> mapper = makePtr<MapperGradShift>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
MapShift* mapShift = dynamic_cast<MapShift*>(mapPtr.get());
return mapShift->getShift();
}
Matx<double, 2, 6> perfEuclidean(const Mat& img1)
{
Mat img2;
Matx<double, 2, 6> transf;
// Warp original image
double theta = 3*CV_PI/180;
double cosT = cos(theta);
double sinT = sin(theta);
Matx<double, 2, 2> linTr(cosT, -sinT, sinT, cosT);
Vec<double, 2> shift(5., 5.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
// Register
Ptr<MapperGradEuclid> mapper = makePtr<MapperGradEuclid>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
MapAffine* mapAff = dynamic_cast<MapAffine*>(mapPtr.get());
Matx<double, 2, 2> resLinTr = mapAff->getLinTr();
transf(0, 0) = resLinTr(0, 0), transf(0, 1) = resLinTr(0, 1);
transf(1, 0) = resLinTr(1, 0), transf(1, 1) = resLinTr(1, 1);
Vec<double, 2> resShift = mapAff->getShift();
transf(0, 2) = resShift(0);
transf(1, 2) = resShift(1);
return transf;
}
Matx<double, 2, 6> perfSimilarity(const Mat& img1)
{
Mat img2;
Matx<double, 2, 6> transf;
// Warp original image
double theta = 3*CV_PI/180;
double scale = 0.95;
double a = scale*cos(theta);
double b = scale*sin(theta);
Matx<double, 2, 2> linTr(a, -b, b, a);
Vec<double, 2> shift(5., 5.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
// Register
Ptr<MapperGradSimilar> mapper = makePtr<MapperGradSimilar>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
MapAffine* mapAff = dynamic_cast<MapAffine*>(mapPtr.get());
Matx<double, 2, 2> resLinTr = mapAff->getLinTr();
transf(0, 0) = resLinTr(0, 0), transf(0, 1) = resLinTr(0, 1);
transf(1, 0) = resLinTr(1, 0), transf(1, 1) = resLinTr(1, 1);
Vec<double, 2> resShift = mapAff->getShift();
transf(0, 2) = resShift(0);
transf(1, 2) = resShift(1);
return transf;
}
Matx<double, 2, 6> perfAffine(const Mat& img1)
{
Mat img2;
Matx<double, 2, 6> transf;
// Warp original image
Matx<double, 2, 2> linTr(1., 0.1, -0.01, 1.);
Vec<double, 2> shift(1., 1.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
// Register
Ptr<MapperGradAffine> mapper = makePtr<MapperGradAffine>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
MapAffine* mapAff = dynamic_cast<MapAffine*>(mapPtr.get());
Matx<double, 2, 2> resLinTr = mapAff->getLinTr();
transf(0, 0) = resLinTr(0, 0), transf(0, 1) = resLinTr(0, 1);
transf(1, 0) = resLinTr(1, 0), transf(1, 1) = resLinTr(1, 1);
Vec<double, 2> resShift = mapAff->getShift();
transf(0, 2) = resShift(0);
transf(1, 2) = resShift(1);
return transf;
}
Matx<double, 3, 3> perfProjective(const Mat& img1)
{
Mat img2;
// Warp original image
Matx<double, 3, 3> projTr(1., 0., 0., 0., 1., 0., 0.0001, 0.0001, 1);
MapProjec mapTest(projTr);
mapTest.warp(img1, img2);
// Register
Ptr<MapperGradProj> mapper = makePtr<MapperGradProj>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
MapProjec* mapProj = dynamic_cast<MapProjec*>(mapPtr.get());
mapProj->normalize();
return mapProj->getProjTr();
}
PERF_TEST_P(Size_MatType, Registration_Shift,
Combine(Values(szSmall64, szSmall128),
Values(MatType(CV_64FC1), MatType(CV_64FC3))))
{
declare.time(60);
const Size size = get<0>(GetParam());
const int type = get<1>(GetParam());
Mat frame(size, type);
Vec<double, 2> shift;
declare.in(frame, WARMUP_RNG).out(shift);
TEST_CYCLE() shift = perfShift(frame);
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(Size_MatType, Registration_Euclidean,
Combine(Values(szSmall64, szSmall128),
Values(MatType(CV_64FC1), MatType(CV_64FC3))))
{
declare.time(60);
const Size size = get<0>(GetParam());
const int type = get<1>(GetParam());
Mat frame(size, type);
Matx<double, 2, 6> result;
declare.in(frame, WARMUP_RNG).out(result);
TEST_CYCLE() result = perfEuclidean(frame);
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(Size_MatType, Registration_Similarity,
Combine(Values(szSmall64, szSmall128),
Values(MatType(CV_64FC1), MatType(CV_64FC3))))
{
declare.time(60);
const Size size = get<0>(GetParam());
const int type = get<1>(GetParam());
Mat frame(size, type);
Matx<double, 2, 6> result;
declare.in(frame, WARMUP_RNG).out(result);
TEST_CYCLE() result = perfSimilarity(frame);
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(Size_MatType, Registration_Affine,
Combine(Values(szSmall64, szSmall128),
Values(MatType(CV_64FC1), MatType(CV_64FC3))))
{
declare.time(60);
const Size size = get<0>(GetParam());
const int type = get<1>(GetParam());
Mat frame(size, type);
Matx<double, 2, 6> result;
declare.in(frame, WARMUP_RNG).out(result);
TEST_CYCLE() result = perfAffine(frame);
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(Size_MatType, Registration_Projective,
Combine(Values(szSmall64, szSmall128),
Values(MatType(CV_64FC1), MatType(CV_64FC3))))
{
declare.time(60);
const Size size = get<0>(GetParam());
const int type = get<1>(GetParam());
Mat frame(size, type);
Matx<double, 3, 3> result;
declare.in(frame, WARMUP_RNG).out(result);
TEST_CYCLE() result = perfProjective(frame);
SANITY_CHECK_NOTHING();
}
}} // namespace
+10
View File
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 2.8)
project(map_test)
find_package(OpenCV REQUIRED)
set(SOURCES map_test.cpp)
add_definitions(-DCOMPARE_FEATURES)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(map_test ${SOURCES} ${HEADERS})
target_link_libraries(map_test ${OpenCV_LIBS})
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

+422
View File
@@ -0,0 +1,422 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp> // OpenCV window I/O
#include <opencv2/imgproc.hpp> // OpenCV image transformations
#ifdef COMPARE_FEATURES
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/geometry.hpp>
using namespace cv::xfeatures2d;
#endif
#include "opencv2/reg/mapaffine.hpp"
#include "opencv2/reg/mapshift.hpp"
#include "opencv2/reg/mapprojec.hpp"
#include "opencv2/reg/mappergradshift.hpp"
#include "opencv2/reg/mappergradeuclid.hpp"
#include "opencv2/reg/mappergradsimilar.hpp"
#include "opencv2/reg/mappergradaffine.hpp"
#include "opencv2/reg/mappergradproj.hpp"
#include "opencv2/reg/mapperpyramid.hpp"
static const char* DIFF_IM = "Image difference";
static const char* DIFF_REGPIX_IM = "Image difference: pixel registered";
using namespace cv;
using namespace cv::reg;
using namespace std;
static void showDifference(const Mat& image1, const Mat& image2, const char* title)
{
Mat img1, img2;
image1.convertTo(img1, CV_32FC3);
image2.convertTo(img2, CV_32FC3);
if(img1.channels() != 1)
cvtColor(img1, img1, COLOR_BGR2GRAY);
if(img2.channels() != 1)
cvtColor(img2, img2, COLOR_BGR2GRAY);
Mat imgDiff;
img1.copyTo(imgDiff);
imgDiff -= img2;
imgDiff /= 2.f;
imgDiff += 128.f;
Mat imgSh;
imgDiff.convertTo(imgSh, CV_8UC3);
imshow(title, imgSh);
}
static void testShift(const Mat& img1)
{
Mat img2;
// Warp original image
Vec<double, 2> shift(5., 5.);
MapShift mapTest(shift);
mapTest.warp(img1, img2);
showDifference(img1, img2, DIFF_IM);
// Register
Ptr<MapperGradShift> mapper = makePtr<MapperGradShift>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
MapShift* mapShift = dynamic_cast<MapShift*>(mapPtr.get());
cout << endl << "--- Testing shift mapper ---" << endl;
cout << Mat(shift) << endl;
cout << Mat(mapShift->getShift()) << endl;
// Display registration accuracy
Mat dest;
mapShift->inverseWarp(img2, dest);
showDifference(img1, dest, DIFF_REGPIX_IM);
waitKey(0);
destroyWindow(DIFF_IM);
destroyWindow(DIFF_REGPIX_IM);
}
static void testEuclidean(const Mat& img1)
{
Mat img2;
// Warp original image
double theta = 3*CV_PI/180;
double cosT = cos(theta);
double sinT = sin(theta);
Matx<double, 2, 2> linTr(cosT, -sinT, sinT, cosT);
Vec<double, 2> shift(5., 5.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
showDifference(img1, img2, DIFF_IM);
// Register
Ptr<MapperGradEuclid> mapper = makePtr<MapperGradEuclid>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
MapAffine* mapAff = dynamic_cast<MapAffine*>(mapPtr.get());
cout << endl << "--- Testing Euclidean mapper ---" << endl;
cout << Mat(linTr) << endl;
cout << Mat(shift) << endl;
cout << Mat(mapAff->getLinTr()) << endl;
cout << Mat(mapAff->getShift()) << endl;
// Display registration accuracy
Mat dest;
mapAff->inverseWarp(img2, dest);
showDifference(img1, dest, DIFF_REGPIX_IM);
waitKey(0);
destroyWindow(DIFF_IM);
destroyWindow(DIFF_REGPIX_IM);
}
static void testSimilarity(const Mat& img1)
{
Mat img2;
// Warp original image
double theta = 3*CV_PI/180;
double scale = 0.95;
double a = scale*cos(theta);
double b = scale*sin(theta);
Matx<double, 2, 2> linTr(a, -b, b, a);
Vec<double, 2> shift(5., 5.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
showDifference(img1, img2, DIFF_IM);
// Register
Ptr<MapperGradSimilar> mapper = makePtr<MapperGradSimilar>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
MapAffine* mapAff = dynamic_cast<MapAffine*>(mapPtr.get());
cout << endl << "--- Testing similarity mapper ---" << endl;
cout << Mat(linTr) << endl;
cout << Mat(shift) << endl;
cout << Mat(mapAff->getLinTr()) << endl;
cout << Mat(mapAff->getShift()) << endl;
// Display registration accuracy
Mat dest;
mapAff->inverseWarp(img2, dest);
showDifference(img1, dest, DIFF_REGPIX_IM);
waitKey(0);
destroyWindow(DIFF_IM);
destroyWindow(DIFF_REGPIX_IM);
}
static void testAffine(const Mat& img1)
{
Mat img2;
// Warp original image
Matx<double, 2, 2> linTr(1., 0.1, -0.01, 1.);
Vec<double, 2> shift(1., 1.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
showDifference(img1, img2, DIFF_IM);
// Register
Ptr<MapperGradAffine> mapper = makePtr<MapperGradAffine>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
MapAffine* mapAff = dynamic_cast<MapAffine*>(mapPtr.get());
cout << endl << "--- Testing affine mapper ---" << endl;
cout << Mat(linTr) << endl;
cout << Mat(shift) << endl;
cout << Mat(mapAff->getLinTr()) << endl;
cout << Mat(mapAff->getShift()) << endl;
// Display registration accuracy
Mat dest;
mapAff->inverseWarp(img2, dest);
showDifference(img1, dest, DIFF_REGPIX_IM);
waitKey(0);
destroyWindow(DIFF_IM);
destroyWindow(DIFF_REGPIX_IM);
}
static void testProjective(const Mat& img1)
{
Mat img2;
// Warp original image
Matx<double, 3, 3> projTr(1., 0., 0., 0., 1., 0., 0.0001, 0.0001, 1);
MapProjec mapTest(projTr);
mapTest.warp(img1, img2);
showDifference(img1, img2, DIFF_IM);
// Register
Ptr<MapperGradProj> mapper = makePtr<MapperGradProj>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
MapProjec* mapProj = dynamic_cast<MapProjec*>(mapPtr.get());
mapProj->normalize();
cout << endl << "--- Testing projective transformation mapper ---" << endl;
cout << Mat(projTr) << endl;
cout << Mat(mapProj->getProjTr()) << endl;
// Display registration accuracy
Mat dest;
mapProj->inverseWarp(img2, dest);
showDifference(img1, dest, DIFF_REGPIX_IM);
waitKey(0);
destroyWindow(DIFF_IM);
destroyWindow(DIFF_REGPIX_IM);
}
#ifdef COMPARE_FEATURES
//
// Following an example from
// http:// ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/
//
static void calcHomographyFeature(const Mat& image1, const Mat& image2)
{
static const char* difffeat = "Difference feature registered";
Mat gray_image1;
Mat gray_image2;
// Convert to Grayscale
if(image1.channels() != 1)
cvtColor(image1, gray_image1, COLOR_BGR2GRAY);
else
image1.copyTo(gray_image1);
if(image2.channels() != 1)
cvtColor(image2, gray_image2, COLOR_BGR2GRAY);
else
image2.copyTo(gray_image2);
//-- Step 1: Detect the keypoints using SIFT or SURF Detector
#ifdef USE_SIFT
Ptr<Feature2D> features = SIFT::create();
#else
int minHessian = 400;
Ptr<Feature2D> features = SURF::create(minHessian);
#endif
std::vector<KeyPoint> keypoints_object, keypoints_scene;
features->detect(gray_image1, keypoints_object);
features->detect(gray_image2, keypoints_scene);
//-- Step 2: Calculate descriptors (feature vectors)
Mat descriptors_object, descriptors_scene;
features->compute(gray_image1, keypoints_object, descriptors_object);
features->compute(gray_image2, keypoints_scene, descriptors_scene);
//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector<DMatch> matches;
matcher.match(descriptors_object, descriptors_scene, matches);
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for(int i = 0; i < descriptors_object.rows; i++)
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
//-- Use only "good" matches (i.e. whose distance is less than 3*min_dist)
std::vector<DMatch> good_matches;
for(int i = 0; i < descriptors_object.rows; i++) {
if(matches[i].distance < 3*min_dist) {
good_matches.push_back( matches[i]);
}
}
std::vector< Point2f > obj;
std::vector< Point2f > scene;
for(size_t i = 0; i < good_matches.size(); i++)
{
//-- Get the keypoints from the good matches
obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
}
// Find the Homography Matrix
Mat H = findHomography( obj, scene, RANSAC );
// Use the Homography Matrix to warp the images
Mat result;
Mat Hinv = H.inv();
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);
showDifference(imf1, resf, difffeat);
}
static void calcHomographyPixel(const Mat& img1, const Mat& img2)
{
static const char* diffpixel = "Difference pixel registered";
// Register using pixel differences
Ptr<MapperGradProj> mapper = makePtr<MapperGradProj>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
MapProjec* mapProj = dynamic_cast<MapProjec*>(mapPtr.get());
mapProj->normalize();
cout << "--- Pixel-based method\n" << Mat(mapProj->getProjTr()) << endl;
// Display registration accuracy
Mat dest;
mapProj->inverseWarp(img2, dest);
showDifference(img1, dest, diffpixel);
}
static void comparePixelVsFeature(const Mat& img1_8b, const Mat& img2_8b)
{
static const char* difforig = "Difference non-registered";
// Show difference of images
Mat img1, img2;
img1_8b.convertTo(img1, CV_64FC3);
img2_8b.convertTo(img2, CV_64FC3);
showDifference(img1, img2, difforig);
cout << endl << "--- Comparing feature-based with pixel difference based ---" << endl;
// Register using SURF keypoints
calcHomographyFeature(img1_8b, img2_8b);
// Register using pixel differences
calcHomographyPixel(img1, img2);
waitKey(0);
}
#endif
int main(void)
{
Mat img1;
img1 = imread("home.png", IMREAD_UNCHANGED);
if(!img1.data) {
cout << "Could not open or find file" << endl;
return -1;
}
// Convert to double, 3 channels
img1.convertTo(img1, CV_64FC3);
testShift(img1);
testEuclidean(img1);
testSimilarity(img1);
testAffine(img1);
testProjective(img1);
#ifdef COMPARE_FEATURES
Mat imgcmp1 = imread("LR_05.png", IMREAD_UNCHANGED);
if(!imgcmp1.data) {
cout << "Could not open or find file" << endl;
return -1;
}
Mat imgcmp2 = imread("LR_06.png", IMREAD_UNCHANGED);
if(!imgcmp2.data) {
cout << "Could not open or find file" << endl;
return -1;
}
comparePixelVsFeature(imgcmp1, imgcmp2);
#endif
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/python
import cv2 as cv
import numpy as np
import sys
img1 = cv.imread(sys.argv[1])
img1 = img1.astype(np.float32)
shift = np.array([5., 5.])
mapTest = cv.reg.MapShift(shift)
img2 = mapTest.warp(img1)
mapper = cv.reg.MapperGradShift()
mappPyr = cv.reg.MapperPyramid(mapper)
resMap = mappPyr.calculate(img1, img2)
mapShift = cv.reg.MapTypeCaster_toShift(resMap)
print(mapShift.getShift())
+59
View File
@@ -0,0 +1,59 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include "opencv2/reg/map.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
Map::~Map()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Map::warp(InputArray img1, OutputArray img2) const
{
Ptr<Map> invMap(inverseMap());
invMap->inverseWarp(img1, img2);
}
}} // namespace cv::reg
+115
View File
@@ -0,0 +1,115 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include <opencv2/imgproc.hpp>
#include "opencv2/reg/mapaffine.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapAffine::MapAffine()
: linTr_(Matx<double, 2, 2>::eye()), shift_()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapAffine::MapAffine(InputArray linTr, InputArray shift)
: linTr_(linTr.getMat()), shift_(shift.getMat())
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapAffine::~MapAffine()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
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);
dest_c.create(img1.size(), CV_32FC1);
for(int r_i = 0; r_i < img1.rows; ++r_i)
{
for(int c_i = 0; c_i < img1.cols; ++c_i)
{
dest_c.at<float>(r_i, c_i) = float(c_i*linTr_(0, 0) + r_i*linTr_(0, 1) + shift_(0));
dest_r.at<float>(r_i, c_i) = float(c_i*linTr_(1, 0) + r_i*linTr_(1, 1) + shift_(1));
}
}
//remap(img1, img2, dest_c, dest_r, INTER_CUBIC, BORDER_REPLICATE);
// Parts that cannot be interpolated will be as in img1 (BORDER_TRANSPARENT means that
// remap will not touch them).
img1.copyTo(img2);
remap(img1, img2, dest_c, dest_r, INTER_CUBIC, BORDER_TRANSPARENT);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Ptr<Map> MapAffine::inverseMap(void) const
{
Matx<double, 2, 2> invLinTr = linTr_.inv(DECOMP_LU);
Vec<double, 2> invShift = -invLinTr*shift_;
return Ptr<Map>(new MapAffine(invLinTr, invShift));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void MapAffine::compose(cv::Ptr<Map> map)
{
// Composition of affine transformations T and T' is (T o T') = A'Ax + A'b + b'
const MapAffine& mapAff = static_cast<const MapAffine&>(*map);
Matx<double, 2, 2> compMat = mapAff.getLinTr()*linTr_;
Vec<double, 2> compShift = mapAff.getLinTr()*shift_ + mapAff.getShift();
linTr_ = compMat;
shift_ = compShift;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void MapAffine::scale(double factor)
{
// Only the shift is affected in this transformation
shift_ *= factor;
}
}} // namespace cv::reg
+103
View File
@@ -0,0 +1,103 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include <opencv2/imgproc.hpp>
#include "opencv2/reg/mapper.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
void Mapper::gradient(const Mat& img1, const Mat& img2, Mat& Ix, Mat& Iy, Mat& It) const
{
Size sz1 = img2.size();
Mat xkern = (Mat_<double>(1, 3) << -1., 0., 1.)/2.;
filter2D(img2, Ix, -1, xkern, Point(-1,-1), 0., BORDER_REPLICATE);
Mat ykern = (Mat_<double>(3, 1) << -1., 0., 1.)/2.;
filter2D(img2, Iy, -1, ykern, Point(-1,-1), 0., BORDER_REPLICATE);
It = Mat::zeros(sz1, img1.type());
It = img2 - img1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename _Tp>
void fillGridMatrices(const Mat img, Mat grid_r, Mat grid_c)
{
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<_Tp>(r_i, c_i) = (_Tp)r_i;
grid_c.at<_Tp>(r_i, c_i) = (_Tp)c_i;
}
}
} else {
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< 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<uchar>(img, grid_r, grid_c);
if(img.depth() == CV_16U)
fillGridMatrices<ushort>(img, grid_r, grid_c);
else if(img.depth() == CV_32F)
fillGridMatrices<float>(img, grid_r, grid_c);
else if(img.depth() == CV_64F)
fillGridMatrices<double>(img, grid_r, grid_c);
}
}} // namespace cv::reg
+166
View File
@@ -0,0 +1,166 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include "opencv2/reg/mappergradaffine.hpp"
#include "opencv2/reg/mapaffine.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradAffine::MapperGradAffine()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradAffine::~MapperGradAffine()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradAffine::calculate(InputArray _img1, InputArray image2, cv::Ptr<Map> init) const
{
Mat img1 = _img1.getMat();
Mat gradx, grady, imgDiff;
Mat img2;
CV_DbgAssert(img1.size() == image2.size());
CV_DbgAssert(img1.channels() == image2.channels());
CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3);
if(!init.empty()) {
// We have initial values for the registration: we move img2 to that initial reference
init->inverseWarp(image2, img2);
} else {
img2 = image2.getMat();
}
// Get gradient in all channels
gradient(img1, img2, gradx, grady, imgDiff);
// Matrices with reference frame coordinates
Mat grid_r, grid_c;
grid(img1, grid_r, grid_c);
// Calculate parameters using least squares
Matx<double, 6, 6> A;
Vec<double, 6> b;
// For each value in A, all the matrix elements are added and then the channels are also added,
// so we have two calls to "sum". The result can be found in the first element of the final
// Scalar object.
Mat xIx = grid_c.mul(gradx);
Mat xIy = grid_c.mul(grady);
Mat yIx = grid_r.mul(gradx);
Mat yIy = grid_r.mul(grady);
Mat Ix2 = gradx.mul(gradx);
Mat Iy2 = grady.mul(grady);
Mat xy = grid_c.mul(grid_r);
Mat IxIy = gradx.mul(grady);
A(0, 0) = sum(sum(sqr(xIx)))[0];
A(0, 1) = sum(sum(xy.mul(Ix2)))[0];
A(0, 2) = sum(sum(grid_c.mul(Ix2)))[0];
A(0, 3) = sum(sum(sqr(grid_c).mul(IxIy)))[0];
A(0, 4) = sum(sum(xy.mul(IxIy)))[0];
A(0, 5) = sum(sum(grid_c.mul(IxIy)))[0];
A(1, 1) = sum(sum(sqr(yIx)))[0];
A(1, 2) = sum(sum(grid_r.mul(Ix2)))[0];
A(1, 3) = A(0, 4);
A(1, 4) = sum(sum(sqr(grid_r).mul(IxIy)))[0];
A(1, 5) = sum(sum(grid_r.mul(IxIy)))[0];
A(2, 2) = sum(sum(Ix2))[0];
A(2, 3) = A(0, 5);
A(2, 4) = A(1, 5);
A(2, 5) = sum(sum(IxIy))[0];
A(3, 3) = sum(sum(sqr(xIy)))[0];
A(3, 4) = sum(sum(xy.mul(Iy2)))[0];
A(3, 5) = sum(sum(grid_c.mul(Iy2)))[0];
A(4, 4) = sum(sum(sqr(yIy)))[0];
A(4, 5) = sum(sum(grid_r.mul(Iy2)))[0];
A(5, 5) = sum(sum(Iy2))[0];
// Lower half values (A is symmetric)
A(1, 0) = A(0, 1);
A(2, 0) = A(0, 2);
A(2, 1) = A(1, 2);
A(3, 0) = A(0, 3);
A(3, 1) = A(1, 3);
A(3, 2) = A(2, 3);
A(4, 0) = A(0, 4);
A(4, 1) = A(1, 4);
A(4, 2) = A(2, 4);
A(4, 3) = A(3, 4);
A(5, 0) = A(0, 5);
A(5, 1) = A(1, 5);
A(5, 2) = A(2, 5);
A(5, 3) = A(3, 5);
A(5, 4) = A(4, 5);
// Calculation of b
b(0) = -sum(sum(imgDiff.mul(xIx)))[0];
b(1) = -sum(sum(imgDiff.mul(yIx)))[0];
b(2) = -sum(sum(imgDiff.mul(gradx)))[0];
b(3) = -sum(sum(imgDiff.mul(xIy)))[0];
b(4) = -sum(sum(imgDiff.mul(yIy)))[0];
b(5) = -sum(sum(imgDiff.mul(grady)))[0];
// Calculate affine transformation. We use Cholesky decomposition, as A is symmetric.
Vec<double, 6> k = A.inv(DECOMP_CHOLESKY)*b;
Matx<double, 2, 2> linTr(k(0) + 1., k(1), k(3), k(4) + 1.);
Vec<double, 2> shift(k(2), k(5));
if(init.empty()) {
return Ptr<Map>(new MapAffine(linTr, shift));
} else {
Ptr<MapAffine> newTr(new MapAffine(linTr, shift));
MapAffine* initPtr = dynamic_cast<MapAffine*>(init.get());
Ptr<MapAffine> oldTr(new MapAffine(initPtr->getLinTr(), initPtr->getShift()));
oldTr->compose(newTr);
return oldTr;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradAffine::getMap() const
{
return cv::Ptr<Map>(new MapAffine());
}
}} // namespace cv::reg
+133
View File
@@ -0,0 +1,133 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include "opencv2/reg/mappergradeuclid.hpp"
#include "opencv2/reg/mapaffine.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradEuclid::MapperGradEuclid()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradEuclid::~MapperGradEuclid()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradEuclid::calculate(
InputArray _img1, InputArray image2, cv::Ptr<Map> init) const
{
Mat img1 = _img1.getMat();
Mat gradx, grady, imgDiff;
Mat img2;
CV_DbgAssert(img1.size() == image2.size());
CV_DbgAssert(img1.channels() == image2.channels());
CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3);
if(!init.empty()) {
// We have initial values for the registration: we move img2 to that initial reference
init->inverseWarp(image2, img2);
} else {
img2 = image2.getMat();
}
// Matrices with reference frame coordinates
Mat grid_r, grid_c;
grid(img1, grid_r, grid_c);
// Get gradient in all channels
gradient(img1, img2, gradx, grady, imgDiff);
// Calculate parameters using least squares
Matx<double, 3, 3> A;
Vec<double, 3> b;
// For each value in A, all the matrix elements are added and then the channels are also added,
// so we have two calls to "sum". The result can be found in the first element of the final
// Scalar object.
Mat xIy_yIx = grid_c.mul(grady);
xIy_yIx -= grid_r.mul(gradx);
A(0, 0) = sum(sum(gradx.mul(gradx)))[0];
A(0, 1) = sum(sum(gradx.mul(grady)))[0];
A(0, 2) = sum(sum(gradx.mul(xIy_yIx)))[0];
A(1, 1) = sum(sum(grady.mul(grady)))[0];
A(1, 2) = sum(sum(grady.mul(xIy_yIx)))[0];
A(2, 2) = sum(sum(xIy_yIx.mul(xIy_yIx)))[0];
A(1, 0) = A(0, 1);
A(2, 0) = A(0, 2);
A(2, 1) = A(1, 2);
b(0) = -sum(sum(imgDiff.mul(gradx)))[0];
b(1) = -sum(sum(imgDiff.mul(grady)))[0];
b(2) = -sum(sum(imgDiff.mul(xIy_yIx)))[0];
// Calculate parameters. We use Cholesky decomposition, as A is symmetric.
Vec<double, 3> k = A.inv(DECOMP_CHOLESKY)*b;
double cosT = cos(k(2));
double sinT = sin(k(2));
Matx<double, 2, 2> linTr(cosT, -sinT, sinT, cosT);
Vec<double, 2> shift(k(0), k(1));
if(init.empty()) {
return Ptr<Map>(new MapAffine(linTr, shift));
} else {
Ptr<MapAffine> newTr(new MapAffine(linTr, shift));
MapAffine* initPtr = dynamic_cast<MapAffine*>(init.get());
Ptr<MapAffine> oldTr(new MapAffine(initPtr->getLinTr(), initPtr->getShift()));
oldTr->compose(newTr);
return oldTr;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradEuclid::getMap() const
{
return cv::Ptr<Map>(new MapAffine());
}
}} // namespace cv::reg
+217
View File
@@ -0,0 +1,217 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include "opencv2/reg/mappergradproj.hpp"
#include "opencv2/reg/mapprojec.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradProj::MapperGradProj()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradProj::~MapperGradProj()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradProj::calculate(
InputArray _img1, InputArray image2, cv::Ptr<Map> init) const
{
Mat img1 = _img1.getMat();
Mat gradx, grady, imgDiff;
Mat img2;
CV_DbgAssert(img1.size() == image2.size());
CV_DbgAssert(img1.channels() == image2.channels());
CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3);
if(!init.empty()) {
// We have initial values for the registration: we move img2 to that initial reference
init->inverseWarp(image2, img2);
} else {
img2 = image2.getMat();
}
// Get gradient in all channels
gradient(img1, img2, gradx, grady, imgDiff);
// Matrices with reference frame coordinates
Mat grid_r, grid_c;
grid(img1, grid_r, grid_c);
// Calculate parameters using least squares
Matx<double, 8, 8> A;
Vec<double, 8> b;
// For each value in A, all the matrix elements are added and then the channels are also added,
// so we have two calls to "sum". The result can be found in the first element of the final
// Scalar object.
Mat xIx = grid_c.mul(gradx);
Mat xIy = grid_c.mul(grady);
Mat yIx = grid_r.mul(gradx);
Mat yIy = grid_r.mul(grady);
Mat Ix2 = gradx.mul(gradx);
Mat Iy2 = grady.mul(grady);
Mat xy = grid_c.mul(grid_r);
Mat IxIy = gradx.mul(grady);
Mat x2 = grid_c.mul(grid_c);
Mat y2 = grid_r.mul(grid_r);
Mat G = xIx + yIy;
Mat G2 = sqr(G);
Mat IxG = gradx.mul(G);
Mat IyG = grady.mul(G);
A(0, 0) = sum(sum(x2.mul(Ix2)))[0];
A(1, 0) = sum(sum(xy.mul(Ix2)))[0];
A(2, 0) = sum(sum(grid_c.mul(Ix2)))[0];
A(3, 0) = sum(sum(x2.mul(IxIy)))[0];
A(4, 0) = sum(sum(xy.mul(IxIy)))[0];
A(5, 0) = sum(sum(grid_c.mul(IxIy)))[0];
A(6, 0) = -sum(sum(x2.mul(IxG)))[0];
A(7, 0) = -sum(sum(xy.mul(IxG)))[0];
A(1, 1) = sum(sum(y2.mul(Ix2)))[0];
A(2, 1) = sum(sum(grid_r.mul(Ix2)))[0];
A(3, 1) = A(4, 0);
A(4, 1) = sum(sum(y2.mul(IxIy)))[0];
A(5, 1) = sum(sum(grid_r.mul(IxIy)))[0];
A(6, 1) = A(7, 0);
A(7, 1) = -sum(sum(y2.mul(IxG)))[0];
A(2, 2) = sum(sum(Ix2))[0];
A(3, 2) = A(5, 0);
A(4, 2) = A(5, 1);
A(5, 2) = sum(sum(IxIy))[0];
A(6, 2) = -sum(sum(grid_c.mul(IxG)))[0];
A(7, 2) = -sum(sum(grid_r.mul(IxG)))[0];
A(3, 3) = sum(sum(x2.mul(Iy2)))[0];
A(4, 3) = sum(sum(xy.mul(Iy2)))[0];
A(5, 3) = sum(sum(grid_c.mul(Iy2)))[0];
A(6, 3) = -sum(sum(x2.mul(IyG)))[0];
A(7, 3) = -sum(sum(xy.mul(IyG)))[0];
A(4, 4) = sum(sum(y2.mul(Iy2)))[0];
A(5, 4) = sum(sum(grid_r.mul(Iy2)))[0];
A(6, 4) = A(7, 3);
A(7, 4) = -sum(sum(y2.mul(IyG)))[0];
A(5, 5) = sum(sum(Iy2))[0];
A(6, 5) = -sum(sum(grid_c.mul(IyG)))[0];
A(7, 5) = -sum(sum(grid_r.mul(IyG)))[0];
A(6, 6) = sum(sum(x2.mul(G2)))[0];
A(7, 6) = sum(sum(xy.mul(G2)))[0];
A(7, 7) = sum(sum(y2.mul(G2)))[0];
// Upper half values (A is symmetric)
A(0, 1) = A(1, 0);
A(0, 2) = A(2, 0);
A(0, 3) = A(3, 0);
A(0, 4) = A(4, 0);
A(0, 5) = A(5, 0);
A(0, 6) = A(6, 0);
A(0, 7) = A(7, 0);
A(1, 2) = A(2, 1);
A(1, 3) = A(3, 1);
A(1, 4) = A(4, 1);
A(1, 5) = A(5, 1);
A(1, 6) = A(6, 1);
A(1, 7) = A(7, 1);
A(2, 3) = A(3, 2);
A(2, 4) = A(4, 2);
A(2, 5) = A(5, 2);
A(2, 6) = A(6, 2);
A(2, 7) = A(7, 2);
A(3, 4) = A(4, 3);
A(3, 5) = A(5, 3);
A(3, 6) = A(6, 3);
A(3, 7) = A(7, 3);
A(4, 5) = A(5, 4);
A(4, 6) = A(6, 4);
A(4, 7) = A(7, 4);
A(5, 6) = A(6, 5);
A(5, 7) = A(7, 5);
A(6, 7) = A(7, 6);
// Calculation of b
b(0) = -sum(sum(imgDiff.mul(xIx)))[0];
b(1) = -sum(sum(imgDiff.mul(yIx)))[0];
b(2) = -sum(sum(imgDiff.mul(gradx)))[0];
b(3) = -sum(sum(imgDiff.mul(xIy)))[0];
b(4) = -sum(sum(imgDiff.mul(yIy)))[0];
b(5) = -sum(sum(imgDiff.mul(grady)))[0];
b(6) = sum(sum(imgDiff.mul(grid_c.mul(G))))[0];
b(7) = sum(sum(imgDiff.mul(grid_r.mul(G))))[0];
// Calculate affine transformation. We use Cholesky decomposition, as A is symmetric.
Vec<double, 8> k = A.inv(DECOMP_CHOLESKY)*b;
Matx<double, 3, 3> H(k(0) + 1., k(1), k(2), k(3), k(4) + 1., k(5), k(6), k(7), 1.);
if(init.empty()) {
return Ptr<Map>(new MapProjec(H));
} else {
Ptr<MapProjec> newTr(new MapProjec(H));
MapProjec* initPtr = dynamic_cast<MapProjec*>(init.get());
Ptr<MapProjec> oldTr(new MapProjec(initPtr->getProjTr()));
oldTr->compose(newTr);
return oldTr;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradProj::getMap() const
{
return cv::Ptr<Map>(new MapProjec());
}
}} // namespace cv::reg
+114
View File
@@ -0,0 +1,114 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include "opencv2/reg/mappergradshift.hpp"
#include "opencv2/reg/mapshift.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradShift::MapperGradShift()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradShift::~MapperGradShift()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradShift::calculate(
InputArray _img1, InputArray image2, cv::Ptr<Map> init) const
{
Mat img1 = _img1.getMat();
Mat gradx, grady, imgDiff;
Mat img2;
CV_DbgAssert(img1.size() == image2.size());
if(!init.empty()) {
// We have initial values for the registration: we move img2 to that initial reference
init->inverseWarp(image2, img2);
} else {
img2 = image2.getMat();
}
// Get gradient in all channels
gradient(img1, img2, gradx, grady, imgDiff);
// Calculate parameters using least squares
Matx<double, 2, 2> A;
Vec<double, 2> b;
// For each value in A, all the matrix elements are added and then the channels are also added,
// so we have two calls to "sum". The result can be found in the first element of the final
// Scalar object.
A(0, 0) = sum(sum(gradx.mul(gradx)))[0];
A(0, 1) = sum(sum(gradx.mul(grady)))[0];
A(1, 1) = sum(sum(grady.mul(grady)))[0];
A(1, 0) = A(0, 1);
b(0) = -sum(sum(imgDiff.mul(gradx)))[0];
b(1) = -sum(sum(imgDiff.mul(grady)))[0];
// Calculate shift. We use Cholesky decomposition, as A is symmetric.
Vec<double, 2> shift = A.inv(DECOMP_CHOLESKY)*b;
if(init.empty()) {
return Ptr<Map>(new MapShift(shift));
} else {
Ptr<MapShift> newTr(new MapShift(shift));
MapShift* initPtr = dynamic_cast<MapShift*>(init.get());
Ptr<MapShift> oldTr(new MapShift(initPtr->getShift()));
oldTr->compose(newTr);
return oldTr;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradShift::getMap() const
{
return cv::Ptr<Map>(new MapShift());
}
}} // namespace cv::reg
+148
View File
@@ -0,0 +1,148 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include "opencv2/reg/mappergradsimilar.hpp"
#include "opencv2/reg/mapaffine.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradSimilar::MapperGradSimilar()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperGradSimilar::~MapperGradSimilar()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradSimilar::calculate(
InputArray _img1, InputArray image2, cv::Ptr<Map> init) const
{
Mat img1 = _img1.getMat();
Mat gradx, grady, imgDiff;
Mat img2;
CV_DbgAssert(img1.size() == image2.size());
CV_DbgAssert(img1.channels() == image2.channels());
CV_DbgAssert(img1.channels() == 1 || img1.channels() == 3);
if(!init.empty()) {
// We have initial values for the registration: we move img2 to that initial reference
init->inverseWarp(image2, img2);
} else {
img2 = image2.getMat();
}
// Get gradient in all channels
gradient(img1, img2, gradx, grady, imgDiff);
// Matrices with reference frame coordinates
Mat grid_r, grid_c;
grid(img1, grid_r, grid_c);
// Calculate parameters using least squares
Matx<double, 4, 4> A;
Vec<double, 4> b;
// For each value in A, all the matrix elements are added and then the channels are also added,
// so we have two calls to "sum". The result can be found in the first element of the final
// Scalar object.
Mat xIx_p_yIy = grid_c.mul(gradx);
xIx_p_yIy += grid_r.mul(grady);
Mat yIx_m_xIy = grid_r.mul(gradx);
yIx_m_xIy -= grid_c.mul(grady);
A(0, 0) = sum(sum(sqr(xIx_p_yIy)))[0];
A(0, 1) = sum(sum(xIx_p_yIy.mul(yIx_m_xIy)))[0];
A(0, 2) = sum(sum(gradx.mul(xIx_p_yIy)))[0];
A(0, 3) = sum(sum(grady.mul(xIx_p_yIy)))[0];
A(1, 1) = sum(sum(sqr(yIx_m_xIy)))[0];
A(1, 2) = sum(sum(gradx.mul(yIx_m_xIy)))[0];
A(1, 3) = sum(sum(grady.mul(yIx_m_xIy)))[0];
A(2, 2) = sum(sum(sqr(gradx)))[0];
A(2, 3) = sum(sum(gradx.mul(grady)))[0];
A(3, 3) = sum(sum(sqr(grady)))[0];
// Lower half values (A is symmetric)
A(1, 0) = A(0, 1);
A(2, 0) = A(0, 2);
A(3, 0) = A(0, 3);
A(2, 1) = A(1, 2);
A(3, 1) = A(1, 3);
A(3, 2) = A(2, 3);
// Calculation of b
b(0) = -sum(sum(imgDiff.mul(xIx_p_yIy)))[0];
b(1) = -sum(sum(imgDiff.mul(yIx_m_xIy)))[0];
b(2) = -sum(sum(imgDiff.mul(gradx)))[0];
b(3) = -sum(sum(imgDiff.mul(grady)))[0];
// Calculate affine transformation. We use Cholesky decomposition, as A is symmetric.
Vec<double, 4> k = A.inv(DECOMP_CHOLESKY)*b;
Matx<double, 2, 2> linTr(k(0) + 1., k(1), -k(1), k(0) + 1.);
Vec<double, 2> shift(k(2), k(3));
if(init.empty()) {
return Ptr<Map>(new MapAffine(linTr, shift));
} else {
Ptr<MapAffine> newTr(new MapAffine(linTr, shift));
MapAffine* initPtr = dynamic_cast<MapAffine*>(init.get());
Ptr<MapAffine> oldTr(new MapAffine(initPtr->getLinTr(), initPtr->getShift()));
oldTr->compose(newTr);
return oldTr;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperGradSimilar::getMap() const
{
return cv::Ptr<Map>(new MapAffine());
}
}} // namespace cv::reg
+105
View File
@@ -0,0 +1,105 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include <vector>
#include "opencv2/imgproc.hpp"
#include "opencv2/reg/mapperpyramid.hpp"
using namespace std;
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapperPyramid::MapperPyramid(Ptr<Mapper> baseMapper)
: numLev_(3), numIterPerScale_(3), baseMapper_(*baseMapper)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Ptr<Map> MapperPyramid::calculate(InputArray _img1, InputArray image2, Ptr<Map> init) const
{
Mat img1 = _img1.getMat();
Mat img2;
if(!init.empty()) {
// We have initial values for the registration: we move img2 to that initial reference
init->inverseWarp(image2, img2);
} else {
init = baseMapper_.getMap();
img2 = image2.getMat();
}
cv::Ptr<Map> ident = baseMapper_.getMap();
// Precalculate pyramid images
vector<Mat> pyrIm1(numLev_), pyrIm2(numLev_);
pyrIm1[0] = img1;
pyrIm2[0] = img2;
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(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(int it_i = 0; it_i < numIterPerScale_; ++it_i) {
ident = baseMapper_.calculate(currRef, currImg, ident);
}
}
init->compose(ident);
return init;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
cv::Ptr<Map> MapperPyramid::getMap() const
{
return cv::Ptr<Map>();
}
}} // namespace cv::reg
+118
View File
@@ -0,0 +1,118 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include <opencv2/imgproc.hpp>
#include "opencv2/reg/mapprojec.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapProjec::MapProjec()
: projTr_(Matx<double, 3, 3>::eye())
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapProjec::MapProjec(InputArray projTr)
: projTr_(projTr.getMat())
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapProjec::~MapProjec()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
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);
dest_c.create(img1.size(), CV_32FC1);
for(int r_i = 0; r_i < img1.rows; ++r_i)
{
for(int c_i = 0; c_i < img1.cols; ++c_i)
{
double z = c_i*projTr_(2, 0) + r_i*projTr_(2, 1) + projTr_(2, 2);
dest_c.at<float>(r_i, c_i) =
float((c_i*projTr_(0, 0) + r_i*projTr_(0, 1) + projTr_(0, 2))/z);
dest_r.at<float>(r_i, c_i) =
float((c_i*projTr_(1, 0) + r_i*projTr_(1, 1) + projTr_(1, 2))/z);
}
}
//remap(img1, img2, dest_c, dest_r, INTER_CUBIC, BORDER_REPLICATE);
// Parts that cannot be interpolated will be as in img1 (BORDER_TRANSPARENT means that
// remap will not touch them).
img1.copyTo(img2);
remap(img1, img2, dest_c, dest_r, INTER_CUBIC, BORDER_TRANSPARENT);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Ptr<Map> MapProjec::inverseMap(void) const
{
Matx<double, 3, 3> invProjTr = projTr_.inv(DECOMP_LU);
return Ptr<Map>(new MapProjec(invProjTr));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void MapProjec::compose(Ptr<Map> map)
{
// Composition of homographies H and H' is (H o H') = H'*H
const MapProjec& mapProj = static_cast<const MapProjec&>(*map);
Matx<double, 3, 3> compProjTr = mapProj.getProjTr()*projTr_;
projTr_ = compProjTr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void MapProjec::scale(double factor)
{
// Shift is multiplied, projective factors are divided
projTr_(0, 2) *= factor;
projTr_(1, 2) *= factor;
projTr_(2, 0) /= factor;
projTr_(2, 1) /= factor;
}
}} // namespace cv::reg
+111
View File
@@ -0,0 +1,111 @@
/*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.
//
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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 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*/
#include "precomp.hpp"
#include <opencv2/imgproc.hpp>
#include "opencv2/reg/mapshift.hpp"
namespace cv {
namespace reg {
////////////////////////////////////////////////////////////////////////////////////////////////////
MapShift::MapShift() : shift_()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapShift::MapShift(InputArray shift)
{
Mat shiftMat = shift.getMat();
shiftMat.copyTo(shift_);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
MapShift::~MapShift()
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
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);
dest_c.create(img1.size(), CV_32FC1);
for(int r_i = 0; r_i < img1.rows; ++r_i)
{
for(int c_i = 0; c_i < img1.cols; ++c_i)
{
dest_c.at<float>(r_i, c_i) = float(c_i + shift_(0));
dest_r.at<float>(r_i, c_i) = float(r_i + shift_(1));
}
}
//remap(img1, img2, dest_c, dest_r, INTER_CUBIC, BORDER_REPLICATE);
// Parts that cannot be interpolated will be as in img1 (BORDER_TRANSPARENT means that
// remap will not touch them).
img1.copyTo(img2);
remap(img1, img2, dest_c, dest_r, INTER_CUBIC, BORDER_TRANSPARENT);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Ptr<Map> MapShift::inverseMap(void) const
{
Vec<double, 2> invShift = -shift_;
return Ptr<Map>(new MapShift(invShift));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void MapShift::compose(cv::Ptr<Map> map)
{
// Composition of transformations T and T' is (T o T') = b + b'
const MapShift& mapShift = static_cast<const MapShift&>(*map);
shift_ += mapShift.getShift();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void MapShift::scale(double factor)
{
shift_ *= factor;
}
}} // namespace cv::reg
+5
View File
@@ -0,0 +1,5 @@
#ifndef OPENCV_REG_PRECOMP_H__
#define OPENCV_REG_PRECOMP_H__
#endif
+46
View File
@@ -0,0 +1,46 @@
/*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.
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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*/
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")
+62
View File
@@ -0,0 +1,62 @@
/*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.
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/reg/mapaffine.hpp"
#include "opencv2/reg/mapshift.hpp"
#include "opencv2/reg/mapprojec.hpp"
#include "opencv2/reg/mappergradshift.hpp"
#include "opencv2/reg/mappergradeuclid.hpp"
#include "opencv2/reg/mappergradsimilar.hpp"
#include "opencv2/reg/mappergradaffine.hpp"
#include "opencv2/reg/mappergradproj.hpp"
#include "opencv2/reg/mapperpyramid.hpp"
namespace opencv_test {
using namespace cv::reg;
}
#endif
+288
View File
@@ -0,0 +1,288 @@
/*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.
// Copyright (C) 2013, Alfonso Sanchez-Beato, 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*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
#define REG_DEBUG_OUTPUT 0
class RegTest : public testing::Test
{
public:
void loadImage(int dstDataType = CV_32FC3);
void testShift();
void testEuclidean();
void testSimilarity();
void testAffine();
void testProjective();
private:
Mat img1;
};
void RegTest::testShift()
{
Mat img2;
// Warp original image
Vec<double, 2> shift(5., 5.);
MapShift mapTest(shift);
mapTest.warp(img1, img2);
// Register
Ptr<Mapper> mapper = makePtr<MapperGradShift>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
Ptr<MapShift> 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<Map> mapInv(mapShift->inverseMap());
mapTest.compose(mapInv);
double shNorm = cv::norm(mapTest.getShift());
EXPECT_LE(shNorm, 0.1);
}
void RegTest::testEuclidean()
{
Mat img2;
// Warp original image
double theta = 3*CV_PI/180;
double cosT = cos(theta);
double sinT = sin(theta);
Matx<double, 2, 2> linTr(cosT, -sinT, sinT, cosT);
Vec<double, 2> shift(5., 5.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
// Register
Ptr<Mapper> mapper = makePtr<MapperGradEuclid>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
Ptr<MapAffine> 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<Map> mapInv(mapAff->inverseMap());
mapTest.compose(mapInv);
double shNorm = cv::norm(mapTest.getShift());
EXPECT_LE(shNorm, 0.1);
double linTrNorm = cv::norm(mapTest.getLinTr());
EXPECT_LE(linTrNorm, sqrt(2.) + 0.01);
EXPECT_GE(linTrNorm, sqrt(2.) - 0.01);
}
void RegTest::testSimilarity()
{
Mat img2;
// Warp original image
double theta = 3*CV_PI/180;
double scale = 0.95;
double a = scale*cos(theta);
double b = scale*sin(theta);
Matx<double, 2, 2> linTr(a, -b, b, a);
Vec<double, 2> shift(5., 5.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
// Register
Ptr<Mapper> mapper = makePtr<MapperGradSimilar>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
Ptr<MapAffine> 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<Map> mapInv(mapAff->inverseMap());
mapTest.compose(mapInv);
double shNorm = cv::norm(mapTest.getShift());
EXPECT_LE(shNorm, 0.1);
double linTrNorm = cv::norm(mapTest.getLinTr());
EXPECT_LE(linTrNorm, sqrt(2.) + 0.01);
EXPECT_GE(linTrNorm, sqrt(2.) - 0.01);
}
void RegTest::testAffine()
{
Mat img2;
// Warp original image
Matx<double, 2, 2> linTr(1., 0.1, -0.01, 1.);
Vec<double, 2> shift(1., 1.);
MapAffine mapTest(linTr, shift);
mapTest.warp(img1, img2);
// Register
Ptr<Mapper> mapper = makePtr<MapperGradAffine>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
Ptr<MapAffine> 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<Map> mapInv(mapAff->inverseMap());
mapTest.compose(mapInv);
double shNorm = cv::norm(mapTest.getShift());
EXPECT_LE(shNorm, 0.2);
double linTrNorm = cv::norm(mapTest.getLinTr());
EXPECT_LE(linTrNorm, sqrt(2.) + 0.01);
EXPECT_GE(linTrNorm, sqrt(2.) - 0.01);
}
void RegTest::testProjective()
{
Mat img2;
// Warp original image
Matx<double, 3, 3> projTr(1., 0., 0., 0., 1., 0., 0.0001, 0.0001, 1);
MapProjec mapTest(projTr);
mapTest.warp(img1, img2);
// Register
Ptr<Mapper> mapper = makePtr<MapperGradProj>();
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
// Print result
Ptr<MapProjec> 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<Map> mapInv(mapProj->inverseMap());
mapTest.compose(mapInv);
double projNorm = cv::norm(mapTest.getProjTr());
EXPECT_LE(projNorm, sqrt(3.) + 0.01);
EXPECT_GE(projNorm, sqrt(3.) - 0.01);
}
void RegTest::loadImage(int dstDataType)
{
const string imageName = cvtest::TS::ptr()->get_data_path() + "reg/home.png";
img1 = imread(imageName, -1);
ASSERT_TRUE(!img1.empty());
img1.convertTo(img1, dstDataType);
}
TEST_F(RegTest, shift)
{
loadImage();
testShift();
}
TEST_F(RegTest, euclidean)
{
loadImage();
testEuclidean();
}
TEST_F(RegTest, similarity)
{
loadImage();
testSimilarity();
}
TEST_F(RegTest, affine)
{
loadImage();
testAffine();
}
TEST_F(RegTest, projective)
{
loadImage();
testProjective();
}
TEST_F(RegTest, projective_dt64fc3)
{
loadImage(CV_64FC3);
testProjective();
}
TEST_F(RegTest, projective_dt64fc1)
{
loadImage(CV_64FC1);
testProjective();
}
}} // namespace