Loading...
Searching...
No Matches
SegmentStatisticsProber.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31#ifndef STATISTICS_PROBER_H
32#define STATISTICS_PROBER_H
33
34#include <ostream>
35#include <cmath>
36//#include "ImageOp.h"
37//#include "Coordinates.h"
38//#include "FilePng.h"
39#include "SegmentProber.h"
40
41namespace drain
42{
43namespace image
44{
45
47
53
54public:
55
57 clear();
58 };
59
61
63 virtual inline
64 void clear(){
65 size = 0;
66 sumX = 0;
67 sumY = 0;
68 sumXX = 0;
69 sumYY = 0;
70 sumXY = 0;
71 _updateNeeded = true;
72 };
73
75 virtual inline
76 void add(const int &i, const int &j){
77 ++size;
78 sumX += i;
79 sumY += j;
80 sumXX += i*i;
81 sumYY += j*j;
82 sumXY += i*j;
83 }
84
86
92 inline
93 double getSize() const {
94 return static_cast<double>(size);
95 };
96
98
104 inline
105 double getMeanX() const {
106 updateStats();
107 return cx;
108 };
109
111
117 inline
118 double getMeanY() const {
119 updateStats();
120 return cy; ;
121 };
122
124
130 inline
131 double getHorizontality() const {
132 updateStats();
133 return cxx / (cxx + cyy);
134 //return sqrt(cxx) / sqrt(cxx + cyy);
135 };
136
138 inline
139 double getVerticality() const {
140 updateStats();
141 return cyy / (cxx + cyy);
142 //return sqrt(cyy) / sqrt(cxx + cyy);
143 };
144
145
147
152 inline
153 double getVariance() const {
154 updateStats();
155 return cxx + cyy;
156 //return getVarianceHorz() + getVarianceVert();
157 };
158
159 inline
160 double getVarianceHorz() const {
161 updateStats();
162 return cxx;
163 };
164
165 inline
166 double getVarianceVert() const {
167 updateStats();
168 return cyy;
169 };
170
172
204 inline
205 double getSlimness() const {
206 return 2.0*M_PI*getVariance()/sizeD - 1.0;
207 };
208
210
213 /*
214 inline
215 double getAnnularity() const {
216 updateStats();
217 return getSlimness() * 2.0 * eigenValue2 / (eigenValue1 + eigenValue2);
218 };
219 */
220
221
223
229 inline
230 double getElongation() const {
231 updateStats();
232 return (eigenValue1 - eigenValue2) / (eigenValue1 + eigenValue2);
233 //return (eigenValue1 - eigenValue2) / eigenValue1;
234 };
235
236 inline
237 double getEigenValue1() const {
238 updateStats();
239 return eigenValue1;
240 };
241
242
243 inline
244 double getEigenValue2() const {
245 updateStats();
246 return eigenValue2;
247 };
248
249 inline
250 void toOstr(std::ostream & ostr) const {
251 ostr << '(' << getMeanX() << ',' << getMeanY() << ')' << ' ';
252 ostr << "s=" << getSize() << ',';
253 ostr << "h=" << getHorizontality() << ',';
254 ostr << "v=" << getVerticality() << ',';
255 ostr << "S=" << getVariance() << ',';
256 ostr << "C=" << '[' << cxx << ',' << cxy << ';' << cxy << ',' << cyy << ']' << ',';
257 ostr << "e12=" << getEigenValue1() << ',' << getEigenValue2() << ',';
258 //ostr << "TEMP=" << sqrt(cxxMcyy*cxxMcyy + 4.0*cxy2);
259 ostr << "e=" << getElongation() << ',';
260 ostr << "l=" << getSlimness() << ',';
261 }
262
263protected:
264
265
266 inline
267 void updateStats() const {
268
269 if (!_updateNeeded)
270 return;
271
272 sizeD = static_cast<double>(size);
273
274 cx = static_cast<double>(sumX)/sizeD;
275 cy = static_cast<double>(sumY)/sizeD;
276
277 if (size == 1){
278 cxx = 1.0;
279 cyy = 1.0;
280 cxy = 0.0;
281 }
282 else {
283 cxx = static_cast<double>(sumXX)/sizeD - cx*cx;
284 cxy = static_cast<double>(sumXY)/sizeD - cx*cy;
285 cyy = static_cast<double>(sumYY)/sizeD - cy*cy;
286 }
287
288
290 const double epsilon = 0.00001;
291 if ((cxy > -epsilon) && (cxy < epsilon)){
292 if (cxx > cyy){ // ensure eigenValue1 > eigenValue2
293 eigenValue1 = cxx;
294 eigenVector1x = 1.0;
295 eigenVector1y = 0.0;
296 eigenValue2 = cyy;
297 eigenVector2x = 0.0;
298 eigenVector2y = 1.0;
299 }
300 else {
301 eigenValue1 = cyy;
302 eigenVector1x = 0.0;
303 eigenVector1y = 1.0;
304 eigenValue2 = cxx;
305 eigenVector2x = 1.0;
306 eigenVector2y = 0.0;
307 }
308 }
309 else {
310
311 /*
312 *
313 *
314 */
315
316 double cxy2 = cxy*cxy;
317 double cxxPcyy = cxx+cyy;
318 double cxxMcyy = cxx-cyy;
319 double temp,scale;
320
321 temp = sqrt(cxxMcyy*cxxMcyy + 4.0*cxy2);
322 eigenValue1 = (cxxPcyy + temp)/2.0;
323 eigenValue2 = (cxxPcyy - temp)/2.0;
324 // std::cerr << '(' << cx << ',' << cy << ')' << ' ';
325 // std::cerr << "E12,t=" << eigenValue1 << ',' << eigenValue2 << ',' << temp << '\n';
326
327 temp = cxx-eigenValue1;
328 scale = sqrt(cxy2 + temp*temp);
329 eigenVector1x = temp/scale;
330 eigenVector1y = cxy/scale;
331
332 temp = cxx-eigenValue2;
333 scale = sqrt(cxy2 + temp*temp);
334 eigenVector2x = temp/scale;
335 eigenVector2y = cxy/scale;
336 }
337
338 //elongation = eigenValue2 / eigenValue1;
339 _updateNeeded = false;
340 }
341
342 mutable bool _updateNeeded;
343
345 long int size;
346
348 long sumX, sumY;
349
351 long sumXX, sumYY, sumXY;
352
354 mutable double sizeD;
355
357 mutable double cx;
358
360 mutable double cy;
361
363 mutable double cxx, cyy, cxy;
364
365 mutable double eigenValue1;
366 mutable double eigenVector1x;
367 mutable double eigenVector1y;
368 mutable double eigenValue2;
369 mutable double eigenVector2x;
370 mutable double eigenVector2y;
371 mutable double elongation;
372};
373
374
375
376inline
377std::ostream & operator<<(std::ostream & ostr, const SegmentStatistics & s){
378 s.toOstr(ostr);
379 return ostr;
380}
381
382
384
390template <class T, class D>
391class SegmentStatisticsProber : public SegmentProber<T,D,SegmentProberConf<T,D> > {
392
393public:
394
395 typedef T src_t;
396 typedef D dst_t;
397 //typedef SegmentProberConf<T,D> conf_t;
398
399 SegmentStatisticsProber(const Channel &s, Channel & d, const std::string statistics="s") : SegmentProber<T,D,SegmentProberConf<T,D> >(s,d), stats(statistics) {
400 };
401
402 virtual
404
405 const std::string & stats;
406
407 SegmentStatistics statistics;
408
409 virtual inline
410 bool isValidSegment(int i, int j) const {
411 // this->src;
412 // this->conf;
413 // this->src.template get<src_t>(i,j);
414 // return this->conf.isValidIntensity(12345);
415 return this->conf.isValidIntensity(this->src.template get<src_t>(i,j));
416 }
417
418protected:
419
420 virtual
421 inline
422 void clear(){
423 statistics.clear();
424 };
425
426
427 virtual
428 inline
429 void update(int i, int j){
430 this->statistics.add(i,j);
431 }
432
433
434};
435
436
437template <class T, class D>
438std::ostream & operator<<(std::ostream & ostr, const SegmentStatisticsProber<T,D> & prober){
439 ostr << (const SegmentProber<T,D,SegmentProberConf<T,D> > &)prober << '\t';
440 ostr << prober.statistics;
441 return ostr;
442}
443
444
445
446}
447}
448#endif /* SEGMENSTATS_H_ */
449
450
451// Drain
Image with static geometry.
Definition ImageChannel.h:58
bool isValidIntensity(S x) const
Criterion.
Definition SegmentProber.h:79
A recursive method for visiting pixels of a segment in an image.
Definition SegmentProber.h:98
A helper class applied by FloodFillOp and SegmentAreaOp.
Definition SegmentStatisticsProber.h:391
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentStatisticsProber.h:410
virtual void update(int i, int j)
Application dependent operation performed in each segment location (i,j).
Definition SegmentStatisticsProber.h:429
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition SegmentStatisticsProber.h:422
A structure for accumulating coordinates and computing statistics thereof: area, centroid,...
Definition SegmentStatisticsProber.h:52
double getSlimness() const
Returns the proportion in which the variance equals the variance of an annulus.
Definition SegmentStatisticsProber.h:205
double getMeanY() const
Returns the horizontal coordinate of centre of mass.
Definition SegmentStatisticsProber.h:118
void updateStats() const
Definition SegmentStatisticsProber.h:267
double cy
Center of mass, y coordinate.
Definition SegmentStatisticsProber.h:360
long sumXX
Sum of squared coordinates.
Definition SegmentStatisticsProber.h:351
double getMeanX() const
Returns the horizontal coordinate of centre of mass.
Definition SegmentStatisticsProber.h:105
double getElongation() const
Returns the proportion in which the variance equals the variance of an annulus.
Definition SegmentStatisticsProber.h:230
double sizeD
Size in double precision.
Definition SegmentStatisticsProber.h:354
double getSize() const
Returns the size of the segment.
Definition SegmentStatisticsProber.h:93
virtual void clear()
Resets the statistics.
Definition SegmentStatisticsProber.h:64
double getHorizontality() const
Returns the horizontal variance $\sigma_x$ scaled with total variance $\sigma_x + \sigma_y$....
Definition SegmentStatisticsProber.h:131
double cx
Center of mass, x coordinate.
Definition SegmentStatisticsProber.h:357
double getVariance() const
Returns the total variance of the pixel coordinates.
Definition SegmentStatisticsProber.h:153
double getVerticality() const
Returns the vertical variance scaled with total variance. Takes values in [0,1].
Definition SegmentStatisticsProber.h:139
virtual void add(const int &i, const int &j)
Accumulate location (i,j) in the statistics.
Definition SegmentStatisticsProber.h:76
long sumX
Sum of coordinates.
Definition SegmentStatisticsProber.h:348
long int size
Size of segment (area).
Definition SegmentStatisticsProber.h:345
double cxx
Elements of covariance matrix.
Definition SegmentStatisticsProber.h:363
Definition DataSelector.cpp:1277