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 <sstream>
35#include <ostream>
36#include <cmath>
37//#include "ImageOp.h"
38//#include "Coordinates.h"
39//#include "FilePng.h"
40#include "SegmentProber.h"
41
42namespace drain
43{
44namespace image
45{
46
48
54
55public:
56
58 clear();
59 };
60
62
64 virtual inline
65 void clear(){
66 size = 0;
67 sumX = 0;
68 sumY = 0;
69 sumXX = 0;
70 sumYY = 0;
71 sumXY = 0;
72 _updateNeeded = true;
73 };
74
76 virtual inline
77 void add(const int &i, const int &j){
78 ++size;
79 sumX += i;
80 sumY += j;
81 sumXX += i*i;
82 sumYY += j*j;
83 sumXY += i*j;
84 }
85
87
93 inline
94 double getSize() const {
95 return static_cast<double>(size);
96 };
97
99
105 inline
106 double getMeanX() const {
107 updateStats();
108 return cx;
109 };
110
112
118 inline
119 double getMeanY() const {
120 updateStats();
121 return cy; ;
122 };
123
125
131 inline
132 double getHorizontality() const {
133 updateStats();
134 return cxx / (cxx + cyy);
135 //return sqrt(cxx) / sqrt(cxx + cyy);
136 };
137
139 inline
140 double getVerticality() const {
141 updateStats();
142 return cyy / (cxx + cyy);
143 //return sqrt(cyy) / sqrt(cxx + cyy);
144 };
145
146
148
153 inline
154 double getVariance() const {
155 updateStats();
156 return cxx + cyy;
157 //return getVarianceHorz() + getVarianceVert();
158 };
159
160 inline
161 double getVarianceHorz() const {
162 updateStats();
163 return cxx;
164 };
165
166 inline
167 double getVarianceVert() const {
168 updateStats();
169 return cyy;
170 };
171
173
205 inline
206 double getSlimness() const {
207 return 2.0*M_PI*getVariance()/sizeD - 1.0;
208 };
209
211
214 /*
215 inline
216 double getAnnularity() const {
217 updateStats();
218 return getSlimness() * 2.0 * eigenValue2 / (eigenValue1 + eigenValue2);
219 };
220 */
221
222
224
230 inline
231 double getElongation() const {
232 updateStats();
233 return (eigenValue1 - eigenValue2) / (eigenValue1 + eigenValue2);
234 //return (eigenValue1 - eigenValue2) / eigenValue1;
235 };
236
237 inline
238 double getEigenValue1() const {
239 updateStats();
240 return eigenValue1;
241 };
242
243
244 inline
245 double getEigenValue2() const {
246 updateStats();
247 return eigenValue2;
248 };
249
250 inline
251 void toOstr(std::ostream & ostr) const {
252 ostr << '(' << getMeanX() << ',' << getMeanY() << ')' << ' ';
253 ostr << "s=" << getSize() << ',';
254 ostr << "h=" << getHorizontality() << ',';
255 ostr << "v=" << getVerticality() << ',';
256 ostr << "S=" << getVariance() << ',';
257 ostr << "C=" << '[' << cxx << ',' << cxy << ';' << cxy << ',' << cyy << ']' << ',';
258 ostr << "e12=" << getEigenValue1() << ',' << getEigenValue2() << ',';
259 //ostr << "TEMP=" << sqrt(cxxMcyy*cxxMcyy + 4.0*cxy2);
260 ostr << "e=" << getElongation() << ',';
261 ostr << "l=" << getSlimness() << ',';
262 }
263
264protected:
265
266
267 inline
268 void updateStats() const {
269
270 if (!_updateNeeded)
271 return;
272
273 sizeD = static_cast<double>(size);
274
275 cx = static_cast<double>(sumX)/sizeD;
276 cy = static_cast<double>(sumY)/sizeD;
277
278 if (size == 1){
279 cxx = 1.0;
280 cyy = 1.0;
281 cxy = 0.0;
282 }
283 else {
284 cxx = static_cast<double>(sumXX)/sizeD - cx*cx;
285 cxy = static_cast<double>(sumXY)/sizeD - cx*cy;
286 cyy = static_cast<double>(sumYY)/sizeD - cy*cy;
287 }
288
289
291 const double epsilon = 0.00001;
292 if ((cxy > -epsilon) && (cxy < epsilon)){
293 if (cxx > cyy){ // ensure eigenValue1 > eigenValue2
294 eigenValue1 = cxx;
295 eigenVector1x = 1.0;
296 eigenVector1y = 0.0;
297 eigenValue2 = cyy;
298 eigenVector2x = 0.0;
299 eigenVector2y = 1.0;
300 }
301 else {
302 eigenValue1 = cyy;
303 eigenVector1x = 0.0;
304 eigenVector1y = 1.0;
305 eigenValue2 = cxx;
306 eigenVector2x = 1.0;
307 eigenVector2y = 0.0;
308 }
309 }
310 else {
311
312 /*
313 *
314 *
315 */
316
317 double cxy2 = cxy*cxy;
318 double cxxPcyy = cxx+cyy;
319 double cxxMcyy = cxx-cyy;
320 double temp,scale;
321
322 temp = sqrt(cxxMcyy*cxxMcyy + 4.0*cxy2);
323 eigenValue1 = (cxxPcyy + temp)/2.0;
324 eigenValue2 = (cxxPcyy - temp)/2.0;
325 // std::cerr << '(' << cx << ',' << cy << ')' << ' ';
326 // std::cerr << "E12,t=" << eigenValue1 << ',' << eigenValue2 << ',' << temp << '\n';
327
328 temp = cxx-eigenValue1;
329 scale = sqrt(cxy2 + temp*temp);
330 eigenVector1x = temp/scale;
331 eigenVector1y = cxy/scale;
332
333 temp = cxx-eigenValue2;
334 scale = sqrt(cxy2 + temp*temp);
335 eigenVector2x = temp/scale;
336 eigenVector2y = cxy/scale;
337 }
338
339 //elongation = eigenValue2 / eigenValue1;
340 _updateNeeded = false;
341 }
342
343 mutable bool _updateNeeded;
344
346 long int size;
347
349 long sumX, sumY;
350
352 long sumXX, sumYY, sumXY;
353
355 mutable double sizeD;
356
358 mutable double cx;
359
361 mutable double cy;
362
364 mutable double cxx, cyy, cxy;
365
366 mutable double eigenValue1;
367 mutable double eigenVector1x;
368 mutable double eigenVector1y;
369 mutable double eigenValue2;
370 mutable double eigenVector2x;
371 mutable double eigenVector2y;
372 mutable double elongation;
373};
374
375
376
377inline
378std::ostream & operator<<(std::ostream & ostr, const SegmentStatistics & s){
379 s.toOstr(ostr);
380 return ostr;
381}
382
383
385
391template <class T, class D>
392class SegmentStatisticsProber : public SegmentProber<T,D,SegmentProberConf<T,D> > {
393
394public:
395
396 typedef T src_t;
397 typedef D dst_t;
398 //typedef SegmentProberConf<T,D> conf_t;
399
400 SegmentStatisticsProber(const Channel &s, Channel & d, const std::string statistics="s") : SegmentProber<T,D,SegmentProberConf<T,D> >(s,d), stats(statistics) {
401 };
402
403 virtual
405
406 const std::string & stats;
407
408 SegmentStatistics statistics;
409
410 virtual inline
411 bool isValidSegment(int i, int j) const {
412 // this->src;
413 // this->conf;
414 // this->src.template get<src_t>(i,j);
415 // return this->conf.isValidIntensity(12345);
416 return this->conf.isValidIntensity(this->src.template get<src_t>(i,j));
417 }
418
419protected:
420
421 virtual
422 inline
423 void clear(){
424 statistics.clear();
425 };
426
427
428 virtual
429 inline
430 void update(int i, int j){
431 this->statistics.add(i,j);
432 }
433
434
435};
436
437
438template <class T, class D>
439std::ostream & operator<<(std::ostream & ostr, const SegmentStatisticsProber<T,D> & prober){
440 ostr << (const SegmentProber<T,D,SegmentProberConf<T,D> > &)prober << '\t';
441 ostr << prober.statistics;
442 return ostr;
443}
444
445
446
447}
448}
449#endif /* SEGMENSTATS_H_ */
450
451
452// Drain
Image with static geometry.
Definition ImageChannel.h:60
bool isValidIntensity(S x) const
Criterion.
Definition SegmentProber.h:81
A recursive method for visiting pixels of a segment in an image.
Definition SegmentProber.h:100
A helper class applied by FloodFillOp and SegmentAreaOp.
Definition SegmentStatisticsProber.h:392
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentStatisticsProber.h:411
virtual void update(int i, int j)
Application dependent operation performed in each segment location (i,j).
Definition SegmentStatisticsProber.h:430
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition SegmentStatisticsProber.h:423
A structure for accumulating coordinates and computing statistics thereof: area, centroid,...
Definition SegmentStatisticsProber.h:53
double getSlimness() const
Returns the proportion in which the variance equals the variance of an annulus.
Definition SegmentStatisticsProber.h:206
double getMeanY() const
Returns the horizontal coordinate of centre of mass.
Definition SegmentStatisticsProber.h:119
void updateStats() const
Definition SegmentStatisticsProber.h:268
double cy
Center of mass, y coordinate.
Definition SegmentStatisticsProber.h:361
long sumXX
Sum of squared coordinates.
Definition SegmentStatisticsProber.h:352
double getMeanX() const
Returns the horizontal coordinate of centre of mass.
Definition SegmentStatisticsProber.h:106
double getElongation() const
Returns the proportion in which the variance equals the variance of an annulus.
Definition SegmentStatisticsProber.h:231
double sizeD
Size in double precision.
Definition SegmentStatisticsProber.h:355
double getSize() const
Returns the size of the segment.
Definition SegmentStatisticsProber.h:94
virtual void clear()
Resets the statistics.
Definition SegmentStatisticsProber.h:65
double getHorizontality() const
Returns the horizontal variance $\sigma_x$ scaled with total variance $\sigma_x + \sigma_y$....
Definition SegmentStatisticsProber.h:132
double cx
Center of mass, x coordinate.
Definition SegmentStatisticsProber.h:358
double getVariance() const
Returns the total variance of the pixel coordinates.
Definition SegmentStatisticsProber.h:154
double getVerticality() const
Returns the vertical variance scaled with total variance. Takes values in [0,1].
Definition SegmentStatisticsProber.h:140
virtual void add(const int &i, const int &j)
Accumulate location (i,j) in the statistics.
Definition SegmentStatisticsProber.h:77
long sumX
Sum of coordinates.
Definition SegmentStatisticsProber.h:349
long int size
Size of segment (area).
Definition SegmentStatisticsProber.h:346
double cxx
Elements of covariance matrix.
Definition SegmentStatisticsProber.h:364
Definition DataSelector.cpp:1277