Skip to content

Commit 1e35407

Browse files
committed
Merge pull request #1379 from terfendail:PeiLin
2 parents 9a5103c + 969bb1e commit 1e35407

File tree

7 files changed

+149
-0
lines changed

7 files changed

+149
-0
lines changed

modules/ximgproc/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ Extended Image Processing
1212
- Paillou Filter
1313
- Fast Line Detector
1414
- Deriche Filter
15+
- Pei&Lin Normalization

modules/ximgproc/include/opencv2/ximgproc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "ximgproc/paillou_filter.hpp"
5252
#include "ximgproc/fast_line_detector.hpp"
5353
#include "ximgproc/deriche_filter.hpp"
54+
#include "ximgproc/peilin.hpp"
5455

5556
/** @defgroup ximgproc Extended Image Processing
5657
@{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
#ifndef __OPENCV_PEILIN_HPP__
6+
#define __OPENCV_PEILIN_HPP__
7+
8+
#include <opencv2/core.hpp>
9+
10+
namespace cv
11+
{
12+
//! @addtogroup ximgproc
13+
//! @{
14+
15+
/**
16+
* @brief Calculates an affine transformation that normalize given image using Pei&Lin Normalization.
17+
*
18+
* Assume given image \f$I=T(\bar{I})\f$ where \f$\bar{I}\f$ is a normalized image and \f$T\f$ is an affine transformation distorting this image by translation, rotation, scaling and skew.
19+
* The function returns an affine transformation matrix corresponding to the transformation \f$T^{-1}\f$ described in [PeiLin95].
20+
* For more details about this implementation, please see
21+
* [PeiLin95] Soo-Chang Pei and Chao-Nan Lin. Image normalization for pattern recognition. Image and Vision Computing, Vol. 13, N.10, pp. 711-723, 1995.
22+
*
23+
* @param I Given transformed image.
24+
* @return Transformation matrix corresponding to inversed image transformation
25+
*/
26+
CV_EXPORTS Matx23d PeiLinNormalization ( InputArray I );
27+
/** @overload */
28+
CV_EXPORTS_W void PeiLinNormalization ( InputArray I, OutputArray T );
29+
}
30+
31+
#endif

modules/ximgproc/samples/peilin.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <opencv2/imgproc.hpp>
2+
#include <opencv2/highgui.hpp>
3+
#include <opencv2/ximgproc.hpp>
4+
5+
#include <iostream>
6+
7+
static void help()
8+
{
9+
std::cout << "\nThis program demonstrates Pei&Lin Normalization\n"
10+
"Usage:\n"
11+
"./peilin [image1_name -- default is ../data/peilin_plane.png] [image2_name -- default is ../data/peilin_shape.png]\n" << std::endl;
12+
}
13+
14+
static inline cv::Mat operator& ( const cv::Mat& lhs, const cv::Matx23d& rhs )
15+
{
16+
cv::Mat ret;
17+
cv::warpAffine ( lhs, ret, rhs, lhs.size(), cv::INTER_LINEAR );
18+
return ret;
19+
}
20+
21+
static inline cv::Mat operator& ( const cv::Matx23d& lhs, const cv::Mat& rhs )
22+
{
23+
cv::Mat ret;
24+
cv::warpAffine ( rhs, ret, lhs, rhs.size(), cv::INTER_LINEAR | cv::WARP_INVERSE_MAP );
25+
return ret;
26+
}
27+
28+
int main(int argc, char** argv)
29+
{
30+
cv::CommandLineParser parser(argc, argv, "{help h | | }{ @input1 | ../data/peilin_plane.png | }{ @input2 | ../data/peilin_plane.png | }");
31+
if (parser.has("help"))
32+
{
33+
help();
34+
return 0;
35+
}
36+
std::string filename1 = parser.get<std::string>("@input1");
37+
std::string filename2 = parser.get<std::string>("@input2");
38+
39+
cv::Mat I = cv::imread(filename1, 0);
40+
if (I.empty())
41+
{
42+
std::cout << "Couldn't open image " << filename1 << std::endl;
43+
return 0;
44+
}
45+
cv::Mat J = cv::imread(filename2, 0);
46+
if (J.empty())
47+
{
48+
std::cout << "Couldn't open image " << filename2 << std::endl;
49+
return 0;
50+
}
51+
cv::Mat N = I & cv::PeiLinNormalization ( I );
52+
cv::Mat D = cv::PeiLinNormalization ( J ) & I;
53+
cv::imshow ( "I", I );
54+
cv::imshow ( "N", N );
55+
cv::imshow ( "J", J );
56+
cv::imshow ( "D", D );
57+
cv::waitKey();
58+
return 0;
59+
}
662 Bytes
Loading
2.45 KB
Loading

modules/ximgproc/src/peilin.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
5+
#include "precomp.hpp"
6+
7+
namespace cv
8+
{
9+
10+
static inline Moments operator& ( const Moments & lhs, const Matx22d & rhs )
11+
{
12+
return Moments (
13+
lhs.m00,
14+
rhs ( 0, 0 ) * lhs.m10 + rhs ( 0, 1 ) * lhs.m01,
15+
rhs ( 1, 0 ) * lhs.m10 + rhs ( 1, 1 ) * lhs.m01,
16+
rhs ( 0, 0 ) * rhs ( 0, 0 ) * lhs.m20 + rhs ( 0, 1 ) * rhs ( 0, 1 ) * lhs.m02 + 2 * rhs ( 0, 0 ) * rhs ( 0, 1 ) * lhs.m11,
17+
rhs ( 0, 0 ) * rhs ( 1, 0 ) * lhs.m20 + rhs ( 0, 1 ) * rhs ( 1, 1 ) * lhs.m02 + ( rhs ( 0, 0 ) * rhs ( 1, 1 ) + rhs ( 0, 1 ) * rhs ( 1, 0 ) ) * lhs.m11,
18+
rhs ( 1, 0 ) * rhs ( 1, 0 ) * lhs.m20 + rhs ( 1, 1 ) * rhs ( 1, 1 ) * lhs.m02 + 2 * rhs ( 1, 0 ) * rhs ( 1, 1 ) * lhs.m11,
19+
rhs ( 0, 0 ) * rhs ( 0, 0 ) * rhs ( 0, 0 ) * lhs.m30 + 3 * rhs ( 0, 0 ) * rhs ( 0, 0 ) * rhs ( 0, 1 ) * lhs.m21 + 3 * rhs ( 0, 0 ) * rhs ( 0, 1 ) * rhs ( 0, 1 ) * lhs.m12 + rhs ( 0, 1 ) * rhs ( 0, 1 ) * rhs ( 0, 1 ) * lhs.m03,
20+
rhs ( 0, 0 ) * rhs ( 0, 0 ) * rhs ( 1, 0 ) * lhs.m30 + ( rhs ( 0, 0 ) * rhs ( 0, 0 ) * rhs ( 1, 1 ) + 2 * rhs ( 0, 0 ) * rhs ( 0, 1 ) * rhs ( 1, 0 ) ) * lhs.m21 + ( 2 * rhs ( 0, 0 ) * rhs ( 0, 1 ) * rhs ( 1, 1 ) + rhs ( 0, 1 ) * rhs ( 0, 1 ) * rhs ( 1, 0 ) ) * lhs.m12 + rhs ( 0, 1 ) * rhs ( 0, 1 ) * rhs ( 1, 1 ) * lhs.m03,
21+
rhs ( 0, 0 ) * rhs ( 1, 0 ) * rhs ( 1, 0 ) * lhs.m30 + ( rhs ( 1, 0 ) * rhs ( 1, 0 ) * rhs ( 0, 1 ) + 2 * rhs ( 0, 0 ) * rhs ( 1, 0 ) * rhs ( 1, 1 ) ) * lhs.m21 + ( 2 * rhs ( 0, 1 ) * rhs ( 1, 0 ) * rhs ( 1, 1 ) + rhs ( 1, 1 ) * rhs ( 1, 1 ) * rhs ( 0, 0 ) ) * lhs.m12 + rhs ( 0, 1 ) * rhs ( 1, 1 ) * rhs ( 1, 1 ) * lhs.m03,
22+
rhs ( 1, 0 ) * rhs ( 1, 0 ) * rhs ( 1, 0 ) * lhs.m30 + 3 * rhs ( 1, 0 ) * rhs ( 1, 0 ) * rhs ( 1, 1 ) * lhs.m21 + 3 * rhs ( 1, 0 ) * rhs ( 1, 1 ) * rhs ( 1, 1 ) * lhs.m12 + rhs ( 1, 1 ) * rhs ( 1, 1 ) * rhs ( 1, 1 ) * lhs.m03
23+
);
24+
}
25+
26+
static inline Matx23d operator| ( const Matx22d & lhs, const Matx21d & rhs )
27+
{
28+
return Matx23d ( lhs ( 0, 0 ), lhs ( 0, 1 ), rhs ( 0 ), lhs ( 1, 0 ), lhs ( 1, 1 ), rhs ( 1 ) );
29+
}
30+
31+
Matx23d PeiLinNormalization ( InputArray I )
32+
{
33+
const Moments M = moments ( I );
34+
const double l1 = ( M.mu20 / M.m00 + M.mu02 / M.m00 + sqrt ( ( M.mu20 / M.m00 - M.mu02 / M.m00 ) * ( M.mu20 / M.m00 - M.mu02 / M.m00 ) + 4 * M.mu11 / M.m00 * M.mu11 / M.m00 ) ) / 2;
35+
const double l2 = ( M.mu20 / M.m00 + M.mu02 / M.m00 - sqrt ( ( M.mu20 / M.m00 - M.mu02 / M.m00 ) * ( M.mu20 / M.m00 - M.mu02 / M.m00 ) + 4 * M.mu11 / M.m00 * M.mu11 / M.m00 ) ) / 2;
36+
const double ex = ( M.mu11 / M.m00 ) / sqrt ( ( l1 - M.mu20 / M.m00 ) * ( l1 - M.mu20 / M.m00 ) + M.mu11 / M.m00 * M.mu11 / M.m00 );
37+
const double ey = ( l1 - M.mu20 / M.m00 ) / sqrt ( ( l1 - M.mu20 / M.m00 ) * ( l1 - M.mu20 / M.m00 ) + M.mu11 / M.m00 * M.mu11 / M.m00 );
38+
const Matx22d E = Matx22d ( ex, ey, -ey, ex );
39+
const double p = min ( I.size().height, I.size().width ) / 8;
40+
const Matx22d W = Matx22d ( p / sqrt ( l1 ), 0, 0, p / sqrt ( l2 ) );
41+
const Matx21d c = Matx21d ( M.m10 / M.m00, M.m01 / M.m00 );
42+
const Matx21d i = Matx21d ( I.size().width / 2, I.size().height / 2 );
43+
const Moments N = M & W * E;
44+
const double t1 = N.mu12 + N.mu30;
45+
const double t2 = N.mu03 + N.mu21;
46+
const double phi = atan2 ( -t1, t2 );
47+
const double psi = ( -t1 * sin ( phi ) + t2 * cos ( phi ) >= 0 ) ? phi : ( phi + CV_PI );
48+
const Matx22d A = Matx22d ( cos ( psi ), sin ( psi ), -sin ( psi ), cos ( psi ) );
49+
return ( A * W * E ) | ( i - A * W * E * c );
50+
}
51+
52+
void PeiLinNormalization ( InputArray I, OutputArray T )
53+
{
54+
T.assign ( Mat ( PeiLinNormalization ( I ) ) );
55+
}
56+
57+
}

0 commit comments

Comments
 (0)