DGtal  1.2.0
MeaningfulScaleAnalysis.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file MeaningfulScaleAnalysis.ih
19  * @author Bertrand Kerautret (\c kerautre@loria.fr )
20  * LORIA (CNRS, UMR 7503), University of Nancy, France
21  *
22  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
23  * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24  *
25  * @date 2015/12/27
26  *
27  * Implementation of inline methods defined in MeaningfulScaleAnalysis.h
28  *
29  * This file is part of the DGtal library.
30  */
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 // IMPLEMENTATION of inline methods.
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 //////////////////////////////////////////////////////////////////////////////
37 #include <cstdlib>
38 #include "DGtal/math/SimpleLinearRegression.h"
39 //////////////////////////////////////////////////////////////////////////////
40 
41 
42 
43 ///////////////////////////////////////////////////////////////////////////////
44 // Implementation of inline methods //
45 
46 template<typename TProfile>
47 DGtal::MeaningfulScaleAnalysis<TProfile>::MeaningfulScaleAnalysis( ConstAlias<Profile> aProfile): myProfile(aProfile)
48 {
49 }
50 
51 
52 template<typename TProfile>
53 DGtal::MeaningfulScaleAnalysis<TProfile>::~MeaningfulScaleAnalysis()
54 {
55 }
56 
57 
58 template<typename TProfile>
59 void
60 DGtal::MeaningfulScaleAnalysis<TProfile>::computeMeaningfulScales ( std::vector< std::pair< unsigned int,
61  unsigned int > > & intervals,
62  const unsigned int minSize,
63  const double maxSlope,
64  const double minSlope ) const
65 {
66  std::vector<typename TProfile::Value> x;
67  std::vector<typename TProfile::Value> y;
68  myProfile.getProfile( x, y );
69  unsigned int l = 0;
70  for ( unsigned int k = 1; k < x.size(); ++k )
71  {
72  double slope = ( y[ k ] - y[ k - 1 ] ) / ( x[ k ] - x[ k - 1 ] );
73  if ( ( slope > maxSlope )
74  || ( slope < minSlope )
75  || ( (k+1) == x.size() ) )
76  {
77  if ( ( k - 1 - l ) >= minSize )
78  intervals.push_back( std::make_pair( l+1, k ) );
79  l = k;
80  }
81  }
82 }
83 
84 template<typename TProfile>
85 std::pair<bool, double>
86 DGtal::MeaningfulScaleAnalysis<TProfile>::getSlopeFromMeaningfulScales(const double maxSlope,
87  const double minSlope,
88  const unsigned int minSize) const {
89  std::pair<bool, double> resuSlope(false, 0.0);
90  std::vector< std::pair< unsigned int, unsigned int > > vectIntervals;
91  this->computeMeaningfulScales(vectIntervals, minSize, maxSlope, minSlope);
92  std::vector<typename TProfile::Value> vx;
93  std::vector<typename TProfile::Value> vy;
94 
95  myProfile.getProfile( vx, vy );
96  // no meaningfulScale interval:
97 
98  if(vectIntervals.size()!=0 && vectIntervals.at(0).first<vectIntervals.at(0).second )
99  {
100  resuSlope.first=true;
101  }
102  else
103  {
104  std::pair<unsigned int, unsigned int> interAll(1, vx.size());
105  vectIntervals.push_back(interAll);
106  }
107  SimpleLinearRegression SLR;
108 
109  unsigned int mfsBeg = vectIntervals.at(0).first-1;
110  unsigned int mfsEnd = vectIntervals.at(0).second-1;
111 
112  // Only two sampled points
113  if ( mfsEnd-mfsBeg == 1 )
114  {
115  Z2i::RealPoint pt1(vx.at(mfsBeg),vy.at(mfsBeg));
116  Z2i::RealPoint pt2(vx.at(mfsEnd),vy.at(mfsEnd));
117  double slope = (pt2[1] - pt1[1])/(pt2[0] -pt1[0]);
118  resuSlope.second = slope;
119  return resuSlope;
120  }
121  for(unsigned int i=mfsBeg; i<=mfsEnd; i++)
122  {
123  SLR.addSample(vx.at(i), vy.at(i));
124  }
125  SLR.computeRegression();
126  resuSlope.second = SLR.slope();
127  return resuSlope;
128 }
129 
130 
131 
132 template<typename TProfile>
133 unsigned int
134 DGtal::MeaningfulScaleAnalysis<TProfile>::noiseLevel ( const unsigned int minSize,
135  const double maxSlope,
136  const double minSlope ) const
137 {
138  std::vector< std::pair< unsigned int, unsigned int > > intervals;
139  this->computeMeaningfulScales( intervals, minSize, maxSlope, minSlope );
140  return ( intervals.size() != 0 )
141  ? intervals[ 0 ].first
142  : 0;
143 }
144 
145 
146 
147 
148 template<typename TProfile>
149 unsigned int
150 DGtal::MeaningfulScaleAnalysis<TProfile>::lowerBoundedNoiseLevel( const unsigned int minSize,
151  const double maxSlope,
152  const double minSlope,
153  const double lowerBoundAtScale1,
154  const double lowerBoundSlope ) const
155 {
156  std::vector< std::pair< unsigned int, unsigned int > > intervals;
157  this->computeMeaningfulScales( intervals, minSize, maxSlope, minSlope );
158  std::vector<typename TProfile::Value> x;
159  std::vector<typename TProfile::Value> y;
160  myProfile.getProfile( x, y );
161  for ( unsigned int i = 0; i < intervals.size(); ++i )
162  {
163  bool above = true;
164  for ( unsigned int k = intervals[ i ].first; ( k <= intervals[ i ].second ); ++k )
165  {
166  if ( y[ k ] < ( lowerBoundAtScale1 + lowerBoundSlope*x[ k ] ) )
167  {
168  above = false;
169  break;
170  }
171  }
172  if ( above ) return intervals[ i ].first;
173  }
174  // Failure. No detected noise level.
175  return 0;
176 }
177 
178 
179 ///////////////////////////////////////////////////////////////////////////////
180 // Implementation of inline functions and external operators //
181 
182 /**
183  * Overloads 'operator<<' for displaying objects of class 'MeaningfulScaleAnalysis'.
184  * @param out the output stream where the object is written.
185  * @param object the object of class 'MeaningfulScaleAnalysis' to write.
186  * @return the output stream after the writing.
187  */
188 template<typename TProfile>
189 inline
190 std::ostream&
191 DGtal::operator<< ( std::ostream & out,
192  const MeaningfulScaleAnalysis<TProfile> & object )
193 {
194  object.selfDisplay ( out );
195  return out;
196 }
197 
198 // //
199 ///////////////////////////////////////////////////////////////////////////////
200 
201