Skip to content

Commit ea6fd75

Browse files
author
Kirill Kornyakov
committed
Merge pull request #5 from alfonsosanchezbeato/master
Intensity based registration module
2 parents 46b2cb2 + e198072 commit ea6fd75

35 files changed

+3235
-0
lines changed

modules/reg/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
set(the_description "Image Registration")
2+
ocv_define_module(reg opencv_imgproc opencv_core)

modules/reg/doc/reg.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
**************************
2+
reg. Registration
3+
**************************
4+
5+
.. toctree::
6+
:maxdepth: 2
7+
8+
registration

modules/reg/doc/registration.rst

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Registration
2+
============
3+
4+
.. highlight:: cpp
5+
6+
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 [Szeliski06]_.
7+
8+
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.
9+
10+
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.
11+
12+
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
13+
implement pixel based methods, the module can be extended to support other methods that can calculate transformations between images (feature methods, optical flow, etc.).
14+
15+
Each class derived from Map implements a motion model, as follows:
16+
17+
* MapShift: Models a simple translation
18+
19+
* MapAffine: Models an affine transformation
20+
21+
* MapProject: Models a projective transformation
22+
23+
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.
24+
25+
The classes derived from Mapper are
26+
27+
* MapperGradShift: Gradient based alignment for calculating translations. It produces a MapShift (two parameters that correspond to the shift vector).
28+
29+
* 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.
30+
31+
* 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.
32+
33+
* MapperGradAffine: Gradient based alignment for an affine motion model. The number of parameters is six and the result is stored in a MapAffine object.
34+
35+
* MapperGradProj: Gradient based alignment for calculating projective transformations. The number of parameters is eight and the result is stored in a MapProject object.
36+
37+
* 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.
38+
39+
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
40+
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.
41+
42+
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.
43+
44+
In the module tests there are examples that show how to register a pair of images using any of the implemented mappers.
45+
46+
reg::Map
47+
--------
48+
Base class for modelling a Map between two images.
49+
50+
.. ocv:class:: reg::Map
51+
52+
The class is only used to define the common interface for any possible map.
53+
54+
55+
reg::Mapper
56+
-----------
57+
Base class for modelling an algorithm for calculating a .. ocv:class:: reg::Map.
58+
59+
.. ocv:class:: reg::Mapper
60+
61+
The class is only used to define the common interface for any possible mapping algorithm.
62+
63+
64+
65+
.. [Szeliski06] R. Szeliski. Image alignment and stitching: A tutorial. Foundations and Trends in Computer Graphics and Vision, vol. 2, no 1, pp. 1-104, 2006.
66+
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*M///////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4+
//
5+
// By downloading, copying, installing or using the software you agree to this license.
6+
// If you do not agree to this license, do not download, install,
7+
// copy or use the software.
8+
//
9+
// Copyright (C) 2013, Alfonso Sanchez-Beato, all rights reserved.
10+
// Third party copyrights are property of their respective owners.
11+
//
12+
// Redistribution and use in source and binary forms, with or without modification,
13+
// are permitted provided that the following conditions are met:
14+
//
15+
// * Redistribution's of source code must retain the above copyright notice,
16+
// this list of conditions and the following disclaimer.
17+
//
18+
// * Redistribution's in binary form must reproduce the above copyright notice,
19+
// this list of conditions and the following disclaimer in the documentation
20+
// and/or other materials provided with the distribution.
21+
//
22+
// * The name of the copyright holders may not be used to endorse or promote products
23+
// derived from this software without specific prior written permission.
24+
//
25+
// This software is provided by the copyright holders and contributors "as is" and
26+
// any express or implied warranties, including, but not limited to, the implied
27+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
28+
// In no event shall the contributors be liable for any direct,
29+
// indirect, incidental, special, exemplary, or consequential damages
30+
// (including, but not limited to, procurement of substitute goods or services;
31+
// loss of use, data, or profits; or business interruption) however caused
32+
// and on any theory of liability, whether in contract, strict liability,
33+
// or tort (including negligence or otherwise) arising in any way out of
34+
// the use of this software, even if advised of the possibility of such damage.
35+
//
36+
//M*/
37+
38+
#ifndef MAP_H_
39+
#define MAP_H_
40+
41+
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
42+
43+
namespace cv {
44+
namespace reg {
45+
46+
47+
/*!
48+
* Defines a map T from one coordinate system to another
49+
*/
50+
class CV_EXPORTS Map
51+
{
52+
public:
53+
/*!
54+
* Virtual destructor
55+
*/
56+
virtual ~Map(void);
57+
58+
/*!
59+
* Warps image to a new coordinate frame. The calculation is img2(x)=img1(T^{-1}(x)), as we
60+
* have to apply the inverse transformation to the points to move them to were the values
61+
* of img2 are.
62+
* \param[in] img1 Original image
63+
* \param[out] img2 Warped image
64+
*/
65+
virtual void warp(const cv::Mat& img1, cv::Mat& img2) const;
66+
67+
/*!
68+
* Warps image to a new coordinate frame. The calculation is img2(x)=img1(T(x)), so in fact
69+
* this is the inverse warping as we are taking the value of img1 with the forward
70+
* transformation of the points.
71+
* \param[in] img1 Original image
72+
* \param[out] img2 Warped image
73+
*/
74+
virtual void inverseWarp(const cv::Mat& img1, cv::Mat& img2) const = 0;
75+
76+
/*!
77+
* Calculates the inverse map
78+
* \return Inverse map
79+
*/
80+
virtual cv::Ptr<Map> inverseMap(void) const = 0;
81+
82+
/*!
83+
* Changes the map composing the current transformation with the one provided in the call.
84+
* The order is first the current transformation, then the input argument.
85+
* \param[in] map Transformation to compose with.
86+
*/
87+
virtual void compose(const Map& map) = 0;
88+
89+
/*!
90+
* Scales the map by a given factor as if the coordinates system is expanded/compressed
91+
* by that factor.
92+
* \param[in] factor Expansion if bigger than one, compression if smaller than one
93+
*/
94+
virtual void scale(double factor) = 0;
95+
};
96+
97+
98+
}} // namespace cv::reg
99+
100+
#endif // MAP_H_
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*M///////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4+
//
5+
// By downloading, copying, installing or using the software you agree to this license.
6+
// If you do not agree to this license, do not download, install,
7+
// copy or use the software.
8+
//
9+
// Copyright (C) 2013, Alfonso Sanchez-Beato, all rights reserved.
10+
// Third party copyrights are property of their respective owners.
11+
//
12+
// Redistribution and use in source and binary forms, with or without modification,
13+
// are permitted provided that the following conditions are met:
14+
//
15+
// * Redistribution's of source code must retain the above copyright notice,
16+
// this list of conditions and the following disclaimer.
17+
//
18+
// * Redistribution's in binary form must reproduce the above copyright notice,
19+
// this list of conditions and the following disclaimer in the documentation
20+
// and/or other materials provided with the distribution.
21+
//
22+
// * The name of the copyright holders may not be used to endorse or promote products
23+
// derived from this software without specific prior written permission.
24+
//
25+
// This software is provided by the copyright holders and contributors "as is" and
26+
// any express or implied warranties, including, but not limited to, the implied
27+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
28+
// In no event shall the contributors be liable for any direct,
29+
// indirect, incidental, special, exemplary, or consequential damages
30+
// (including, but not limited to, procurement of substitute goods or services;
31+
// loss of use, data, or profits; or business interruption) however caused
32+
// and on any theory of liability, whether in contract, strict liability,
33+
// or tort (including negligence or otherwise) arising in any way out of
34+
// the use of this software, even if advised of the possibility of such damage.
35+
//
36+
//M*/
37+
38+
#ifndef MAPAFFINE_H_
39+
#define MAPAFFINE_H_
40+
41+
#include "map.hpp"
42+
43+
namespace cv {
44+
namespace reg {
45+
46+
47+
/*!
48+
* Defines an affine transformation
49+
*/
50+
class CV_EXPORTS MapAffine : public Map
51+
{
52+
public:
53+
/*!
54+
* Default constructor builds an identity map
55+
*/
56+
MapAffine(void);
57+
58+
/*!
59+
* Constructor providing explicit values
60+
* \param[in] linTr Linear part of the affine transformation
61+
* \param[in] shift Displacement part of the affine transformation
62+
*/
63+
MapAffine(const cv::Matx<double, 2, 2>& linTr, const cv::Vec<double, 2>& shift);
64+
65+
/*!
66+
* Destructor
67+
*/
68+
~MapAffine(void);
69+
70+
void inverseWarp(const cv::Mat& img1, cv::Mat& img2) const;
71+
72+
cv::Ptr<Map> inverseMap(void) const;
73+
74+
void compose(const Map& map);
75+
76+
void scale(double factor);
77+
78+
/*!
79+
* Return linear part of the affine transformation
80+
* \return Linear part of the affine transformation
81+
*/
82+
const cv::Matx<double, 2, 2>& getLinTr() const {
83+
return linTr_;
84+
}
85+
86+
/*!
87+
* Return displacement part of the affine transformation
88+
* \return Displacement part of the affine transformation
89+
*/
90+
const cv::Vec<double, 2>& getShift() const {
91+
return shift_;
92+
}
93+
94+
private:
95+
cv::Matx<double, 2, 2> linTr_;
96+
cv::Vec<double, 2> shift_;
97+
};
98+
99+
100+
}} // namespace cv::reg
101+
102+
#endif // MAPAFFINE_H_
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*M///////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4+
//
5+
// By downloading, copying, installing or using the software you agree to this license.
6+
// If you do not agree to this license, do not download, install,
7+
// copy or use the software.
8+
//
9+
// Copyright (C) 2013, Alfonso Sanchez-Beato, all rights reserved.
10+
// Third party copyrights are property of their respective owners.
11+
//
12+
// Redistribution and use in source and binary forms, with or without modification,
13+
// are permitted provided that the following conditions are met:
14+
//
15+
// * Redistribution's of source code must retain the above copyright notice,
16+
// this list of conditions and the following disclaimer.
17+
//
18+
// * Redistribution's in binary form must reproduce the above copyright notice,
19+
// this list of conditions and the following disclaimer in the documentation
20+
// and/or other materials provided with the distribution.
21+
//
22+
// * The name of the copyright holders may not be used to endorse or promote products
23+
// derived from this software without specific prior written permission.
24+
//
25+
// This software is provided by the copyright holders and contributors "as is" and
26+
// any express or implied warranties, including, but not limited to, the implied
27+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
28+
// In no event shall the contributors be liable for any direct,
29+
// indirect, incidental, special, exemplary, or consequential damages
30+
// (including, but not limited to, procurement of substitute goods or services;
31+
// loss of use, data, or profits; or business interruption) however caused
32+
// and on any theory of liability, whether in contract, strict liability,
33+
// or tort (including negligence or otherwise) arising in any way out of
34+
// the use of this software, even if advised of the possibility of such damage.
35+
//
36+
//M*/
37+
38+
#ifndef MAPPER_H_
39+
#define MAPPER_H_
40+
41+
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
42+
#include "map.hpp"
43+
44+
namespace cv {
45+
namespace reg {
46+
47+
/*
48+
* Encapsulates ways of calculating mappings between two images
49+
*/
50+
class CV_EXPORTS Mapper
51+
{
52+
public:
53+
virtual ~Mapper(void) {}
54+
55+
/*
56+
* Calculate mapping between two images
57+
* \param[in] img1 Reference image
58+
* \param[in] img2 Warped image
59+
* \param[in,out] res Map from img1 to img2, stored in a smart pointer. If present as input,
60+
* it is an initial rough estimation that the mapper will try to refine.
61+
*/
62+
virtual void calculate(const cv::Mat& img1, const cv::Mat& img2, cv::Ptr<Map>& res) const = 0;
63+
64+
/*
65+
* Returns a map compatible with the Mapper class
66+
* \return Pointer to identity Map
67+
*/
68+
virtual cv::Ptr<Map> getMap(void) const = 0;
69+
70+
protected:
71+
/*
72+
* Calculates gradient and difference between images
73+
* \param[in] img1 Image one
74+
* \param[in] img2 Image two
75+
* \param[out] Ix Gradient x-coordinate
76+
* \param[out] Iy Gradient y-coordinate
77+
* \param[out] It Difference of images
78+
*/
79+
void gradient(const cv::Mat& img1, const cv::Mat& img2,
80+
cv::Mat& Ix, cv::Mat& Iy, cv::Mat& It) const;
81+
82+
/*
83+
* Fills matrices with pixel coordinates of an image
84+
* \param[in] img Image
85+
* \param[out] grid_r Row (y-coordinate)
86+
* \param[out] grid_c Column (x-coordinate)
87+
*/
88+
void grid(const Mat& img, Mat& grid_r, Mat& grid_c) const;
89+
90+
/*
91+
* Per-element square of a matrix
92+
* \param[in] mat1 Input matrix
93+
* \return mat1[i,j]^2
94+
*/
95+
cv::Mat sqr(const cv::Mat& mat1) const
96+
{
97+
cv::Mat res;
98+
res.create(mat1.size(), mat1.type());
99+
res = mat1.mul(mat1);
100+
return res;
101+
}
102+
};
103+
104+
105+
}} // namespace cv::reg
106+
107+
#endif // MAPPER_H_
108+

0 commit comments

Comments
 (0)