-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBlobResult.cpp
executable file
·874 lines (805 loc) · 24.4 KB
/
BlobResult.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
/************************************************************************
BlobResult.cpp
FUNCIONALITAT: Implementació de la classe CBlobResult
AUTOR: Inspecta S.L.
MODIFICACIONS (Modificació, Autor, Data):
**************************************************************************/
#include <limits.h>
#include <stdio.h>
#include <functional>
#include <algorithm>
#include "BlobResult.h"
#include "BlobExtraction.h"
#ifdef _DEBUG
#include <afx.h> //suport per a CStrings
#include <afxwin.h> //suport per a AfxMessageBox
#endif
/**************************************************************************
Constructors / Destructors
**************************************************************************/
/**
- FUNCIÓ: CBlobResult
- FUNCIONALITAT: Constructor estandard.
- PARÀMETRES:
- RESULTAT:
- Crea un CBlobResult sense cap blob
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 20-07-2004.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: CBlobResult
- FUNCTIONALITY: Standard constructor
- PARAMETERS:
- RESULT:
- creates an empty set of blobs
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlobResult::CBlobResult()
{
m_blobs = blob_vector();
}
/**
- FUNCIÓ: CBlobResult
- FUNCIONALITAT: Constructor a partir d'una imatge. Inicialitza la seqüència de blobs
amb els blobs resultants de l'anàlisi de blobs de la imatge.
- PARÀMETRES:
- source: imatge d'on s'extreuran els blobs
- mask: màscara a aplicar. Només es calcularan els blobs on la màscara sigui
diferent de 0. Els blobs que toquin a un pixel 0 de la màscara seran
considerats exteriors.
- threshold: llindar que s'aplicarà a la imatge source abans de calcular els blobs
- findmoments: indica si s'han de calcular els moments de cada blob
- RESULTAT:
- objecte CBlobResult amb els blobs de la imatge source
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: CBlob
- FUNCTIONALITY: Constructor from an image. Fills an object with all the blobs in
the image
- PARAMETERS:
- source: image to extract the blobs from
- mask: optional mask to apply. The blobs will be extracted where the mask is
not 0. All the neighbouring blobs where the mask is 0 will be extern blobs
- threshold: threshold level to apply to the image before computing blobs
- findmoments: true to calculate the blob moments (slower)
- RESULT:
- object with all the blobs in the image. It throws an EXCEPCIO_CALCUL_BLOBS
if some error appears in the BlobAnalysis function
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlobResult::CBlobResult(IplImage *source, IplImage *mask, int threshold, bool findmoments)
{
bool success;
try
{
// cridem la funció amb el marc a true=1=blanc (així no unirà els blobs externs)
success = BlobAnalysis(source,(uchar)threshold,mask,true,findmoments, m_blobs );
}
catch(...)
{
success = false;
}
if( !success ) throw EXCEPCIO_CALCUL_BLOBS;
}
/**
- FUNCIÓ: CBlobResult
- FUNCIONALITAT: Constructor de còpia. Inicialitza la seqüència de blobs
amb els blobs del paràmetre.
- PARÀMETRES:
- source: objecte que es copiarà
- RESULTAT:
- objecte CBlobResult amb els blobs de l'objecte source
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: CBlobResult
- FUNCTIONALITY: Copy constructor
- PARAMETERS:
- source: object to copy
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlobResult::CBlobResult( const CBlobResult &source )
{
m_blobs = blob_vector( source.GetNumBlobs() );
// creem el nou a partir del passat com a paràmetre
m_blobs = blob_vector( source.GetNumBlobs() );
// copiem els blobs de l'origen a l'actual
blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
blob_vector::iterator pBlobsDst = m_blobs.begin();
while( pBlobsSrc != source.m_blobs.end() )
{
// no podem cridar a l'operador = ja que blob_vector és un
// vector de CBlob*. Per tant, creem un blob nou a partir del
// blob original
*pBlobsDst = new CBlob(**pBlobsSrc);
pBlobsSrc++;
pBlobsDst++;
}
}
/**
- FUNCIÓ: ~CBlobResult
- FUNCIONALITAT: Destructor estandard.
- PARÀMETRES:
- RESULTAT:
- Allibera la memòria reservada de cadascun dels blobs de la classe
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: ~CBlobResult
- FUNCTIONALITY: Destructor
- PARAMETERS:
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlobResult::~CBlobResult()
{
ClearBlobs();
}
/**************************************************************************
Operadors / Operators
**************************************************************************/
/**
- FUNCIÓ: operador =
- FUNCIONALITAT: Assigna un objecte source a l'actual
- PARÀMETRES:
- source: objecte a assignar
- RESULTAT:
- Substitueix els blobs actuals per els de l'objecte source
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: Assigment operator
- FUNCTIONALITY:
- PARAMETERS:
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlobResult& CBlobResult::operator=(const CBlobResult& source)
{
// si ja són el mateix, no cal fer res
if (this != &source)
{
// alliberem el conjunt de blobs antic
for( int i = 0; i < GetNumBlobs(); i++ )
{
delete m_blobs[i];
}
m_blobs.clear();
// creem el nou a partir del passat com a paràmetre
m_blobs = blob_vector( source.GetNumBlobs() );
// copiem els blobs de l'origen a l'actual
blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
blob_vector::iterator pBlobsDst = m_blobs.begin();
while( pBlobsSrc != source.m_blobs.end() )
{
// no podem cridar a l'operador = ja que blob_vector és un
// vector de CBlob*. Per tant, creem un blob nou a partir del
// blob original
*pBlobsDst = new CBlob(**pBlobsSrc);
pBlobsSrc++;
pBlobsDst++;
}
}
return *this;
}
/**
- FUNCIÓ: operador +
- FUNCIONALITAT: Concatena els blobs de dos CBlobResult
- PARÀMETRES:
- source: d'on s'agafaran els blobs afegits a l'actual
- RESULTAT:
- retorna un nou CBlobResult amb els dos CBlobResult concatenats
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- NOTA: per la implementació, els blobs del paràmetre es posen en ordre invers
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: + operator
- FUNCTIONALITY: Joins the blobs in source with the current ones
- PARAMETERS:
- source: object to copy the blobs
- RESULT:
- object with the actual blobs and the source blobs
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlobResult CBlobResult::operator+( const CBlobResult& source )
{
//creem el resultat a partir dels blobs actuals
CBlobResult resultat( *this );
// reservem memòria per als nous blobs
resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() );
// declarem els iterador per recòrrer els blobs d'origen i desti
blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
// insertem els blobs de l'origen a l'actual
while( pBlobsSrc != source.m_blobs.end() )
{
pBlobsDst--;
*pBlobsDst = new CBlob(**pBlobsSrc);
pBlobsSrc++;
}
return resultat;
}
/**************************************************************************
Operacions / Operations
**************************************************************************/
/**
- FUNCIÓ: AddBlob
- FUNCIONALITAT: Afegeix un blob al conjunt
- PARÀMETRES:
- blob: blob a afegir
- RESULTAT:
- modifica el conjunt de blobs actual
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 2006/03/01
- MODIFICACIÓ: Data. Autor. Descripció.
*/
void CBlobResult::AddBlob( CBlob *blob )
{
if( blob != NULL )
m_blobs.push_back( new CBlob( blob ) );
}
#ifdef MATRIXCV_ACTIU
/**
- FUNCIÓ: GetResult
- FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe
- PARÀMETRES:
- evaluador: Qualsevol objecte derivat de COperadorBlob
- RESULTAT:
- Retorna un array de double's amb el resultat per cada blob
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: GetResult
- FUNCTIONALITY: Computes the function evaluador on all the blobs of the class
and returns a vector with the result
- PARAMETERS:
- evaluador: function to apply to each blob (any object derived from the
COperadorBlob class )
- RESULT:
- vector with all the results in the same order as the blobs
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
double_vector CBlobResult::GetResult( funcio_calculBlob *evaluador ) const
{
if( GetNumBlobs() <= 0 )
{
return double_vector();
}
// definim el resultat
double_vector result = double_vector( GetNumBlobs() );
// i iteradors sobre els blobs i el resultat
double_vector::iterator itResult = result.GetIterator();
blob_vector::const_iterator itBlobs = m_blobs.begin();
// avaluem la funció en tots els blobs
while( itBlobs != m_blobs.end() )
{
*itResult = (*evaluador)(**itBlobs);
itBlobs++;
itResult++;
}
return result;
}
#endif
/**
- FUNCIÓ: GetSTLResult
- FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe
- PARÀMETRES:
- evaluador: Qualsevol objecte derivat de COperadorBlob
- RESULTAT:
- Retorna un array de double's STL amb el resultat per cada blob
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: GetResult
- FUNCTIONALITY: Computes the function evaluador on all the blobs of the class
and returns a vector with the result
- PARAMETERS:
- evaluador: function to apply to each blob (any object derived from the
COperadorBlob class )
- RESULT:
- vector with all the results in the same order as the blobs
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
double_stl_vector CBlobResult::GetSTLResult( funcio_calculBlob *evaluador ) const
{
if( GetNumBlobs() <= 0 )
{
return double_stl_vector();
}
// definim el resultat
double_stl_vector result = double_stl_vector( GetNumBlobs() );
// i iteradors sobre els blobs i el resultat
double_stl_vector::iterator itResult = result.begin();
blob_vector::const_iterator itBlobs = m_blobs.begin();
// avaluem la funció en tots els blobs
while( itBlobs != m_blobs.end() )
{
*itResult = (*evaluador)(**itBlobs);
itBlobs++;
itResult++;
}
return result;
}
/**
- FUNCIÓ: GetNumber
- FUNCIONALITAT: Calcula el resultat especificat sobre un únic blob de la classe
- PARÀMETRES:
- evaluador: Qualsevol objecte derivat de COperadorBlob
- indexblob: número de blob del que volem calcular el resultat.
- RESULTAT:
- Retorna un double amb el resultat
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: GetNumber
- FUNCTIONALITY: Computes the function evaluador on a blob of the class
- PARAMETERS:
- indexBlob: index of the blob to compute the function
- evaluador: function to apply to each blob (any object derived from the
COperadorBlob class )
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
double CBlobResult::GetNumber( int indexBlob, funcio_calculBlob *evaluador ) const
{
if( indexBlob < 0 || indexBlob >= GetNumBlobs() )
RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
return (*evaluador)( *m_blobs[indexBlob] );
}
/////////////////////////// FILTRAT DE BLOBS ////////////////////////////////////
/**
- FUNCIÓ: Filter
- FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb només
els blobs que han passat el filtre.
El filtrat es basa en especificar condicions sobre un resultat dels blobs
i seleccionar (o excloure) aquells blobs que no compleixen una determinada
condicio
- PARÀMETRES:
- dst: variable per deixar els blobs filtrats
- filterAction: acció de filtrat. Incloure els blobs trobats (B_INCLUDE),
o excloure els blobs trobats (B_EXCLUDE)
- evaluador: Funció per evaluar els blobs (qualsevol objecte derivat de COperadorBlob
- Condition: tipus de condició que ha de superar la mesura (FilterType)
sobre cada blob per a ser considerat.
B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
- LowLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
- HighLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
(només té sentit per a aquelles condicions que tenen dos valors
(B_INSIDE, per exemple).
- RESULTAT:
- Deixa els blobs resultants del filtrat a destination
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/**
- FUNCTION: Filter
- FUNCTIONALITY: Get some blobs from the class based on conditions on measures
of the blobs.
- PARAMETERS:
- dst: where to store the selected blobs
- filterAction: B_INCLUDE: include the blobs which pass the filter in the result
B_EXCLUDE: exclude the blobs which pass the filter in the result
- evaluador: Object to evaluate the blob
- Condition: How to decide if the result returned by evaluador on each blob
is included or not. It can be:
B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
- LowLimit: numerical value to evaluate the Condition on evaluador(blob)
- HighLimit: numerical value to evaluate the Condition on evaluador(blob).
Only useful for B_INSIDE and B_OUTSIDE
- RESULT:
- It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
the Condition on the result returned by evaluador on each blob
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
void CBlobResult::Filter(CBlobResult &dst,
int filterAction,
funcio_calculBlob *evaluador,
int condition,
double lowLimit, double highLimit /*=0*/)
{
int i, numBlobs;
bool resultavaluacio;
double_stl_vector avaluacioBlobs;
double_stl_vector::iterator itavaluacioBlobs;
if( GetNumBlobs() <= 0 ) return;
if( !evaluador ) return;
//avaluem els blobs amb la funció pertinent
avaluacioBlobs = GetSTLResult(evaluador);
itavaluacioBlobs = avaluacioBlobs.begin();
numBlobs = GetNumBlobs();
switch(condition)
{
case B_EQUAL:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio= *itavaluacioBlobs == lowLimit;
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_NOT_EQUAL:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio = *itavaluacioBlobs != lowLimit;
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_GREATER:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio= *itavaluacioBlobs > lowLimit;
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_LESS:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio= *itavaluacioBlobs < lowLimit;
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_GREATER_OR_EQUAL:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio= *itavaluacioBlobs>= lowLimit;
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_LESS_OR_EQUAL:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio= *itavaluacioBlobs <= lowLimit;
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_INSIDE:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio=( *itavaluacioBlobs >= lowLimit) && ( *itavaluacioBlobs <= highLimit);
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
case B_OUTSIDE:
for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
{
resultavaluacio=( *itavaluacioBlobs < lowLimit) || ( *itavaluacioBlobs > highLimit);
if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
( !resultavaluacio && filterAction == B_EXCLUDE ))
{
dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
}
}
break;
}
// en cas de voler filtrar un CBlobResult i deixar-ho en el mateix CBlobResult
// ( operacio inline )
if( &dst == this )
{
// esborrem els primers blobs ( que són els originals )
// ja que els tindrem replicats al final si passen el filtre
blob_vector::iterator itBlobs = m_blobs.begin();
for( int i = 0; i < numBlobs; i++ )
{
delete *itBlobs;
itBlobs++;
}
m_blobs.erase( m_blobs.begin(), itBlobs );
}
}
/**
- FUNCIÓ: GetBlob
- FUNCIONALITAT: Retorna un blob si aquest existeix (index != -1)
- PARÀMETRES:
- indexblob: index del blob a retornar
- RESULTAT:
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/*
- FUNCTION: GetBlob
- FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
- PARAMETERS:
- indexblob: index in the blob array
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CBlob CBlobResult::GetBlob(int indexblob) const
{
if( indexblob < 0 || indexblob >= GetNumBlobs() )
RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
return *m_blobs[indexblob];
}
CBlob *CBlobResult::GetBlob(int indexblob)
{
if( indexblob < 0 || indexblob >= GetNumBlobs() )
RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
return m_blobs[indexblob];
}
/**
- FUNCIÓ: GetNthBlob
- FUNCIONALITAT: Retorna l'enèssim blob segons un determinat criteri
- PARÀMETRES:
- criteri: criteri per ordenar els blobs (objectes derivats de COperadorBlob)
- nBlob: index del blob a retornar
- dst: on es retorna el resultat
- RESULTAT:
- retorna el blob nBlob a dst ordenant els blobs de la classe segons el criteri
en ordre DESCENDENT. Per exemple, per obtenir el blob major:
GetNthBlob( CBlobGetArea(), 0, blobMajor );
GetNthBlob( CBlobGetArea(), 1, blobMajor ); (segon blob més gran)
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/*
- FUNCTION: GetNthBlob
- FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
- PARAMETERS:
- criteri: criteria to order the blob array
- nBlob: index of the returned blob in the ordered blob array
- dst: where to store the result
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const
{
// verifiquem que no estem accedint fora el vector de blobs
if( nBlob < 0 || nBlob >= GetNumBlobs() )
{
//RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
dst = CBlob();
return;
}
double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
double valorEnessim;
//avaluem els blobs amb la funció pertinent
avaluacioBlobs = GetSTLResult(criteri);
avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() );
// obtenim els nBlob primers resultats (en ordre descendent)
std::partial_sort_copy( avaluacioBlobs.begin(),
avaluacioBlobs.end(),
avaluacioBlobsOrdenat.begin(),
avaluacioBlobsOrdenat.end(),
std::greater<double>() );
valorEnessim = avaluacioBlobsOrdenat[nBlob];
// busquem el primer blob que té el valor n-ssim
double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin();
bool trobatBlob = false;
int indexBlob = 0;
while( itAvaluacio != avaluacioBlobs.end() && !trobatBlob )
{
if( *itAvaluacio == valorEnessim )
{
trobatBlob = true;
dst = CBlob( GetBlob(indexBlob));
}
itAvaluacio++;
indexBlob++;
}
}
/**
- FUNCIÓ: ClearBlobs
- FUNCIONALITAT: Elimina tots els blobs de l'objecte
- PARÀMETRES:
- RESULTAT:
- Allibera tota la memòria dels blobs
- RESTRICCIONS:
- AUTOR: Ricard Borràs Navarra
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/*
- FUNCTION: ClearBlobs
- FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
- PARAMETERS:
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
void CBlobResult::ClearBlobs()
{
/*for( int i = 0; i < GetNumBlobs(); i++ )
{
delete m_blobs[i];
}*/
blob_vector::iterator itBlobs = m_blobs.begin();
while( itBlobs != m_blobs.end() )
{
delete *itBlobs;
itBlobs++;
}
m_blobs.clear();
}
/**
- FUNCIÓ: RaiseError
- FUNCIONALITAT: Funció per a notificar errors al l'usuari (en debug) i llença
les excepcions
- PARÀMETRES:
- errorCode: codi d'error
- RESULTAT:
- Ensenya un missatge a l'usuari (en debug) i llença una excepció
- RESTRICCIONS:
- AUTOR: Ricard Borràs Navarra
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/*
- FUNCTION: RaiseError
- FUNCTIONALITY: Error handling function
- PARAMETERS:
- errorCode: reason of the error
- RESULT:
- in _DEBUG version, shows a message box with the error. In release is silent.
In both cases throws an exception with the error.
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
void CBlobResult::RaiseError(const int errorCode) const
{
// estem en mode debug?
#ifdef _DEBUG
CString msg, format = "Error en CBlobResult: %s";
switch (errorCode)
{
case EXCEPTION_BLOB_OUT_OF_BOUNDS:
msg.Format(format, "Intentant accedir a un blob no existent");
break;
default:
msg.Format(format, "Codi d'error desconegut");
break;
}
AfxMessageBox(msg);
#endif
throw errorCode;
}
/**************************************************************************
Auxiliars / Auxiliary functions
**************************************************************************/
/**
- FUNCIÓ: PrintBlobs
- FUNCIONALITAT: Escriu els paràmetres (àrea, perímetre, exterior, mitjana)
de tots els blobs a un fitxer.
- PARÀMETRES:
- nom_fitxer: path complet del fitxer amb el resultat
- RESULTAT:
- RESTRICCIONS:
- AUTOR: Ricard Borràs
- DATA DE CREACIÓ: 25-05-2005.
- MODIFICACIÓ: Data. Autor. Descripció.
*/
/*
- FUNCTION: PrintBlobs
- FUNCTIONALITY: Prints some blob features in an ASCII file
- PARAMETERS:
- nom_fitxer: full path + filename to generate
- RESULT:
- RESTRICTIONS:
- AUTHOR: Ricard Borràs
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
void CBlobResult::PrintBlobs( char *nom_fitxer ) const
{
double_stl_vector area, /*perimetre,*/ exterior, mitjana, compacitat, longitud,
externPerimeter, perimetreConvex, perimetre;
int i;
FILE *fitxer_sortida;
area = GetSTLResult( CBlobGetArea());
perimetre = GetSTLResult( CBlobGetPerimeter());
exterior = GetSTLResult( CBlobGetExterior());
mitjana = GetSTLResult( CBlobGetMean());
compacitat = GetSTLResult(CBlobGetCompactness());
longitud = GetSTLResult( CBlobGetLength());
externPerimeter = GetSTLResult( CBlobGetExternPerimeter());
perimetreConvex = GetSTLResult( CBlobGetHullPerimeter());
fitxer_sortida = fopen( nom_fitxer, "w" );
for(i=0; i<GetNumBlobs(); i++)
{
fprintf( fitxer_sortida, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f extern)\t pconvex=%8.2f\t ext=%.0f\t m=%7.2f\t c=%3.2f\t l=%8.2f\n",
i, area[i], perimetre[i], externPerimeter[i], perimetreConvex[i], exterior[i], mitjana[i], compacitat[i], longitud[i] );
}
fclose( fitxer_sortida );
}