libcrn  3.9.5
A document image processing library
•All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNGradientMatching.cpp
Go to the documentation of this file.
1 /* Copyright 2015 Université Paris Descartes
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNGradientMatching.cpp
19  * \author Yann LEYDIER
20  */
21 
24 #include <CRNImage/CRNImageGray.h>
25 #include <CRNImage/CRNImageBW.h>
26 
27 using namespace crn;
28 
30  angles(ThetaChannel(igr)),
31  mask(Threshold(RhoChannel(igr), igr.GetMinModule())),
32  xbar(0),
33  ybar(0)
34 {
35  dmask = mask;
36  auto sel = MatrixInt(3, 3, 1);
37  sel[0][0] = sel[2][0] = sel[0][2] = sel[2][2] = 0;
38  dmask.Erode(sel);
39  auto npix = 0;
40  FOREACHPIXEL(x, y, mask)
41  if (mask.At(x, y))
42  {
43  npix += 1;
44  xbar += int(x);
45  ybar += int(y);
46  }
47  if (npix)
48  {
49  xbar /= npix;
50  ybar /= npix;
51  }
52  else
53  {
54  xbar = int(igr.GetWidth()) / 2;
55  ybar = int(igr.GetHeight()) / 2;
56  }
57 }
58 
59 static int diffgrad(const GradientModel &c1, const GradientModel &c2, int win) noexcept
60 {
61  const auto deltax = c1.xbar - c2.xbar;
62  const auto deltay = c1.ybar - c2.ybar;
63  auto mindiff = std::numeric_limits<int>::max();
64 
65  for (auto y_d = deltay - win; y_d <= deltay + win; ++y_d)
66  for (auto x_d = deltax - win; x_d <= deltax + win; ++x_d)
67  {
68  auto diff = 0;
69  for (auto y = 0; y < int(c1.mask.GetHeight()); ++y)
70  {
71  for (auto x = 0; x < int(c1.mask.GetWidth()); ++x)
72  {
73  if (!c1.mask.At(x, y))
74  continue;
75  int d;
76  if ((x >= x_d) && (x < x_d + int(c2.dmask.GetWidth())) &&
77  (y >= y_d) && (y < y_d + int(c2.dmask.GetHeight())) &&
78  c2.dmask.At(x - x_d, y - y_d))
79  {
80  d = AngularDistance(Angle<ByteAngle>(c1.angles.At(x, y)), Angle<ByteAngle>(c2.angles.At(x - x_d, y - y_d)));
81  }
82  else
83  {
84  d = 128;
85  }
86  diff += d;
87  if (diff > mindiff)
88  break;
89  }
90  if (diff > mindiff)
91  break;
92  }
93 
94  if (diff < mindiff)
95  {
96  mindiff = diff;
97  }
98  }
99  return mindiff;
100 }
101 
102 double crn::GradientModel::Distance(const GradientModel &img1, const GradientModel &img2, size_t window) noexcept
103 {
104  auto npix1 = 0;
105  for (auto p : img1.mask)
106  if (p)
107  npix1 += 1;
108  if (npix1 == 0) npix1 = 1;
109  auto npix2 = 0;
110  for (auto p : img2.mask)
111  if (p)
112  npix2 += 1;
113  if (npix2 == 0) npix2 = 1;
114  auto ndiff1 = diffgrad(img1, img2, int(window));
115  auto ndiff2 = diffgrad(img2, img1, int(window));
116  return Max(double(ndiff1) / npix1, double(ndiff2) / npix2);
117 }
118 
Unit::type AngularDistance(const Angle< Unit > &a1, const Angle< Unit > &a2) noexcept(std::is_nothrow_constructible< typename TypeInfo< typename Unit::type >::DiffType >::value &&std::is_nothrow_copy_assignable< typename TypeInfo< typename Unit::type >::DiffType >::value &&std::is_nothrow_constructible< typename Unit::type >::value)
Distance between two angles.
static double Distance(const GradientModel &img1, const GradientModel &img2, size_t window) noexcept
std::vector< pixel_type >::reference At(size_t x, size_t y) noexcept
Returns a reference to a pixel.
Definition: CRNImage.h:224
size_t GetHeight() const noexcept
Definition: CRNImage.h:74
GradientModel(const ImageGradient &igr)
Gradient descriptor.
const T & Max(const T &a, const T &b)
Returns the max of two values.
Definition: CRNMath.h:47
#define FOREACHPIXEL(x, y, img)
Convenience macro to sweep an image.
Definition: CRNImage.h:37
void Erode(const MatrixInt &strel, CMP cmp=std::less< pixel_type >{})
Morphological erosion.
Definition: CRNImage.hpp:827
A convenience class for angles units.
Integer matrix class.
Definition: CRNMatrixInt.h:40
ImageBW Threshold(const Image< T > &img, T thresh, CMP cmp=std::less< T >{})
Definition: CRNImageGray.h:204
Gradient image in polar form.
Image< typename Unit< T >::type > ThetaChannel(const Image< pixel::Polar2D< R, T >> &img)
Definition: CRNImage2D.h:67
size_t GetWidth() const noexcept
Definition: CRNImage.h:72
Image< R > RhoChannel(const Image< pixel::Polar2D< R, T >> &img)
Definition: CRNImage2D.h:55