DGtal 1.4.0
Loading...
Searching...
No Matches
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
46template<typename TProfile>
47DGtal::MeaningfulScaleAnalysis<TProfile>::MeaningfulScaleAnalysis( ConstAlias<Profile> aProfile): myProfile(aProfile)
48{
49}
50
51
52template<typename TProfile>
53DGtal::MeaningfulScaleAnalysis<TProfile>::~MeaningfulScaleAnalysis()
54{
55}
56
57
58template<typename TProfile>
59void
60DGtal::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
84template<typename TProfile>
85std::pair<bool, double>
86DGtal::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
132template<typename TProfile>
133unsigned int
134DGtal::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
148template<typename TProfile>
149unsigned int
150DGtal::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 */
188template<typename TProfile>
189inline
190std::ostream&
191DGtal::operator<< ( std::ostream & out,
192 const MeaningfulScaleAnalysis<TProfile> & object )
193{
194 object.selfDisplay ( out );
195 return out;
196}
197
198// //
199///////////////////////////////////////////////////////////////////////////////
200
201