vendor: OpenCV 5.0.0 snapshot at 755e50675d97db9b7d449d8bd6b09888646f6c6e
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
set(the_description "Image Registration")
|
||||
ocv_define_module(reg opencv_imgproc opencv_core WRAP python)
|
||||
@@ -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.
|
||||
|
||||
@@ -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.}
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 |
@@ -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;
|
||||
}
|
||||
Executable
+20
@@ -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())
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef OPENCV_REG_PRECOMP_H__
|
||||
#define OPENCV_REG_PRECOMP_H__
|
||||
|
||||
|
||||
#endif
|
||||
@@ -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")
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user