Project

General

Profile

Statistics
| Branch: | Revision:

root / vision / cvblobs8.3 / BlobOperators.cpp @ b11b2b30

History | View | Annotate | Download (14.2 KB)

1 b11b2b30 Tom Mullins
#include <limits.h>
2
#include "BlobOperators.h"
3
4
/***************************************************************************
5
  Implementaci? de les classes per al c?lcul de caracter?stiques sobre el blob
6

7
  Implementation of the helper classes to perform operations on blobs
8
/**************************************************************************/
9
10
/**
11
- FUNCTION: Moment
12
- FUNCTIONALITY: Calculates the pq moment of the blob
13
- PARAMETERS:
14
- RESULT:
15
        - returns the pq moment or 0 if the moment it is not implemented
16
- RESTRICTIONS:
17
        - Currently, implemented moments up to 3
18
- AUTHOR: Ricard Borr?s
19
- CREATION DATE: 20-07-2004.
20
- MODIFICATION: Date. Author. Description.
21
*/
22
double CBlobGetMoment::operator()(CBlob &blob)
23
{
24
        return blob.Moment(m_p, m_q);
25
}
26
27
/**
28
- FUNCI?: HullPerimeter
29
- FUNCIONALITAT: Calcula la longitud del perimetre convex del blob.
30
                           Fa servir la funci? d'OpenCV cvConvexHull2 per a 
31
                           calcular el perimetre convex.
32
                           
33
- PAR?METRES:
34
- RESULTAT:
35
        - retorna la longitud del per?metre convex del blob. Si el blob no t? coordenades
36
          associades retorna el per?metre normal del blob.
37
- RESTRICCIONS:
38
- AUTOR: Ricard Borr?s
39
- DATA DE CREACI?: 20-07-2004.
40
- MODIFICACI?: Data. Autor. Descripci?.
41
*/
42
/**
43
- FUNCTION: CBlobGetHullPerimeter
44
- FUNCTIONALITY: Calculates the convex hull perimeter of the blob
45
- PARAMETERS:
46
- RESULT:
47
        - returns the convex hull perimeter of the blob or the perimeter if the 
48
        blob edges could not be retrieved
49
- RESTRICTIONS:
50
- AUTHOR: Ricard Borr?s
51
- CREATION DATE: 25-05-2005.
52
- MODIFICATION: Date. Author. Description.
53
*/
54
double CBlobGetHullPerimeter::operator()(CBlob &blob)
55
{
56
        CvSeq *convexHull;
57
        double perimeter;
58
59
        convexHull = blob.GetConvexHull();
60
61
        if( convexHull )
62
                perimeter = fabs(cvArcLength(convexHull,CV_WHOLE_SEQ,1));
63
        else
64
                return 0;
65
66
        cvClearSeq(convexHull);
67
68
        return perimeter;
69
}
70
71
double CBlobGetHullArea::operator()(CBlob &blob)
72
{
73
        CvSeq *convexHull;
74
        double area;
75
76
        convexHull = blob.GetConvexHull();
77
78
        if( convexHull )
79
                area = fabs(cvContourArea(convexHull));
80
        else
81
                return 0;
82
83
        cvClearSeq(convexHull);
84
85
        return area;
86
}
87
88
/**
89
- FUNCTION: CBlobGetMinXatMinY
90
- FUNCTIONALITY: Calculates the minimum X on the minimum Y
91
- PARAMETERS:
92
- RESULT:
93
- RESTRICTIONS:
94
- AUTHOR: Ricard Borr?s
95
- CREATION DATE: 25-05-2005.
96
- MODIFICATION: Date. Author. Description.
97
*/
98
double CBlobGetMinXatMinY::operator()(CBlob &blob)
99
{
100
        double result = LONG_MAX;
101
        
102
        CvSeqReader reader;
103
        CvPoint actualPoint;
104
        t_PointList externContour;
105
        
106
        externContour = blob.GetExternalContour()->GetContourPoints();
107
        if( !externContour ) return result;
108
        cvStartReadSeq( externContour, &reader);
109
110
        for( int i=0; i< externContour->total; i++)
111
        {
112
                CV_READ_SEQ_ELEM( actualPoint, reader);
113
114
                if( (actualPoint.y == blob.MinY()) && (actualPoint.x < result) )
115
                {
116
                        result = actualPoint.x;
117
                }        
118
        }
119
120
        return result;
121
}
122
123
/**
124
- FUNCTION: CBlobGetMinXatMinY
125
- FUNCTIONALITY: Calculates the minimum Y on the maximum X
126
- PARAMETERS:
127
- RESULT:
128
- RESTRICTIONS:
129
- AUTHOR: Ricard Borr?s
130
- CREATION DATE: 25-05-2005.
131
- MODIFICATION: Date. Author. Description.
132
*/
133
double CBlobGetMinYatMaxX::operator()(CBlob &blob)
134
{
135
        double result = LONG_MAX;
136
        
137
        CvSeqReader reader;
138
        CvPoint actualPoint;
139
        t_PointList externContour;
140
        
141
        externContour = blob.GetExternalContour()->GetContourPoints();
142
        if( !externContour ) return result;
143
        cvStartReadSeq( externContour, &reader);
144
145
        for( int i=0; i< externContour->total; i++)
146
        {
147
                CV_READ_SEQ_ELEM( actualPoint, reader);
148
149
                if( (actualPoint.x == blob.MaxX()) && (actualPoint.y < result) )
150
                {
151
                        result = actualPoint.y;
152
                }        
153
        }
154
155
        return result;
156
}
157
158
/**
159
- FUNCTION: CBlobGetMaxXatMaxY
160
- FUNCTIONALITY: Calculates the maximum X on the maximum Y
161
- PARAMETERS:
162
- RESULT:
163
- RESTRICTIONS:
164
- AUTHOR: Ricard Borr?s
165
- CREATION DATE: 25-05-2005.
166
- MODIFICATION: Date. Author. Description.
167
*/
168
double CBlobGetMaxXatMaxY::operator()(CBlob &blob)
169
{
170
        double result = LONG_MIN;
171
        
172
        CvSeqReader reader;
173
        CvPoint actualPoint;
174
        t_PointList externContour;
175
        
176
        externContour = blob.GetExternalContour()->GetContourPoints();
177
        if( !externContour ) return result;
178
179
        cvStartReadSeq( externContour, &reader);
180
181
        for( int i=0; i< externContour->total; i++)
182
        {
183
                CV_READ_SEQ_ELEM( actualPoint, reader);
184
185
                if( (actualPoint.y == blob.MaxY()) && (actualPoint.x > result) )
186
                {
187
                        result = actualPoint.x;
188
                }        
189
        }
190
191
        return result;
192
}
193
194
/**
195
- FUNCTION: CBlobGetMaxYatMinX
196
- FUNCTIONALITY: Calculates the maximum Y on the minimum X
197
- PARAMETERS:
198
- RESULT:
199
- RESTRICTIONS:
200
- AUTHOR: Ricard Borr?s
201
- CREATION DATE: 25-05-2005.
202
- MODIFICATION: Date. Author. Description.
203
*/
204
double CBlobGetMaxYatMinX::operator()(CBlob &blob)
205
{
206
        double result = LONG_MIN;
207
        
208
        CvSeqReader reader;
209
        CvPoint actualPoint;
210
        t_PointList externContour;
211
        
212
        externContour = blob.GetExternalContour()->GetContourPoints();
213
        if( !externContour ) return result;
214
215
        cvStartReadSeq( externContour, &reader);
216
217
        
218
        for( int i=0; i< externContour->total; i++)
219
        {
220
                CV_READ_SEQ_ELEM( actualPoint, reader);
221
222
                if( (actualPoint.x == blob.MinX()) && (actualPoint.y > result) )
223
                {
224
                        result = actualPoint.y;
225
                }        
226
        }
227
228
        return result;
229
}
230
231
232
/**
233
- FUNCTION: CBlobGetElongation
234
- FUNCTIONALITY: Calculates the elongation of the blob ( length/breadth )
235
- PARAMETERS:
236
- RESULT:
237
- RESTRICTIONS:
238
        - See below to see how the lenght and the breadth are aproximated
239
- AUTHOR: Ricard Borr?s
240
- CREATION DATE: 25-05-2005.
241
- MODIFICATION: Date. Author. Description.
242
*/
243
double CBlobGetElongation::operator()(CBlob &blob)
244
{
245
        double ampladaC,longitudC,amplada,longitud;
246
247
        double tmp;
248
249
        tmp = blob.Perimeter()*blob.Perimeter() - 16*blob.Area();
250
251
        if( tmp > 0.0 )
252
                ampladaC = (double) (blob.Perimeter()+sqrt(tmp))/4;
253
        // error intr?nsec en els c?lculs de l'?rea i el per?metre 
254
        else
255
                ampladaC = (double) (blob.Perimeter())/4;
256
257
        if(ampladaC<=0.0) return 0;
258
        longitudC=(double) blob.Area()/ampladaC;
259
260
        longitud=MAX( longitudC , ampladaC );
261
        amplada=MIN( longitudC , ampladaC );
262
263
        return (double) longitud/amplada;
264
}
265
266
/**
267
        Retorna la compacitat del blob
268
*/
269
/**
270
- FUNCTION: CBlobGetCompactness
271
- FUNCTIONALITY: Calculates the compactness of the blob 
272
                            ( maximum for circle shaped blobs, minimum for the rest)
273
- PARAMETERS:
274
- RESULT:
275
- RESTRICTIONS:
276
- AUTHOR: Ricard Borr?s
277
- CREATION DATE: 25-05-2005.
278
- MODIFICATION: Date. Author. Description.
279
*/
280
double CBlobGetCompactness::operator()(CBlob &blob)
281
{
282
        if( blob.Area() != 0.0 )
283
                return (double) pow(blob.Perimeter(),2)/(4*CV_PI*blob.Area());
284
        else
285
                return 0.0;
286
}
287
288
/**
289
        Retorna la rugositat del blob
290
*/
291
/**
292
- FUNCTION: CBlobGetRoughness
293
- FUNCTIONALITY: Calculates the roughness of the blob 
294
                            ( ratio between perimeter and convex hull perimeter)
295
- PARAMETERS:
296
- RESULT:
297
- RESTRICTIONS:
298
- AUTHOR: Ricard Borr?s
299
- CREATION DATE: 25-05-2005.
300
- MODIFICATION: Date. Author. Description.
301
*/
302
double CBlobGetRoughness::operator()(CBlob &blob)
303
{
304
        CBlobGetHullPerimeter getHullPerimeter = CBlobGetHullPerimeter();
305
        
306
        double hullPerimeter = getHullPerimeter(blob);
307
308
        if( hullPerimeter != 0.0 )
309
                return blob.Perimeter() / hullPerimeter;//HullPerimeter();
310
311
        return 0.0;
312
}
313
314
/**
315
        Retorna la longitud del blob
316
*/
317
/**
318
- FUNCTION: CBlobGetLength
319
- FUNCTIONALITY: Calculates the lenght of the blob (the biggest axis of the blob)
320
- PARAMETERS:
321
- RESULT:
322
- RESTRICTIONS:
323
        - The lenght is an aproximation to the real lenght
324
- AUTHOR: Ricard Borr?s
325
- CREATION DATE: 25-05-2005.
326
- MODIFICATION: Date. Author. Description.
327
*/
328
double CBlobGetLength::operator()(CBlob &blob)
329
{
330
        double ampladaC,longitudC;
331
        double tmp;
332
333
        tmp = blob.Perimeter()*blob.Perimeter() - 16*blob.Area();
334
335
        if( tmp > 0.0 )
336
                ampladaC = (double) (blob.Perimeter()+sqrt(tmp))/4;
337
        // error intr?nsec en els c?lculs de l'?rea i el per?metre 
338
        else
339
                ampladaC = (double) (blob.Perimeter())/4;
340
341
        if(ampladaC<=0.0) return 0;
342
        longitudC=(double) blob.Area()/ampladaC;
343
344
        return MAX( longitudC , ampladaC );
345
}
346
347
/**
348
        Retorna l'amplada del blob
349
*/
350
/**
351
- FUNCTION: CBlobGetBreadth
352
- FUNCTIONALITY: Calculates the breadth of the blob (the smallest axis of the blob)
353
- PARAMETERS:
354
- RESULT:
355
- RESTRICTIONS:
356
        - The breadth is an aproximation to the real breadth
357
- AUTHOR: Ricard Borr?s
358
- CREATION DATE: 25-05-2005.
359
- MODIFICATION: Date. Author. Description.
360
*/
361
double CBlobGetBreadth::operator()(CBlob &blob)
362
{
363
        double ampladaC,longitudC;
364
        double tmp;
365
366
        tmp = blob.Perimeter()*blob.Perimeter() - 16*blob.Area();
367
368
        if( tmp > 0.0 )
369
                ampladaC = (double) (blob.Perimeter()+sqrt(tmp))/4;
370
        // error intr?nsec en els c?lculs de l'?rea i el per?metre 
371
        else
372
                ampladaC = (double) (blob.Perimeter())/4;
373
374
        if(ampladaC<=0.0) return 0;
375
        longitudC = (double) blob.Area()/ampladaC;
376
377
        return MIN( longitudC , ampladaC );
378
}
379
380
/**
381
        Calcula la dist?ncia entre un punt i el centre del blob
382
*/
383
/**
384
- FUNCTION: CBlobGetDistanceFromPoint
385
- FUNCTIONALITY: Calculates the euclidean distance between the blob center and 
386
                                 the point specified in the constructor
387
- PARAMETERS:
388
- RESULT:
389
- RESTRICTIONS:
390
- AUTHOR: Ricard Borr?s
391
- CREATION DATE: 25-05-2005.
392
- MODIFICATION: Date. Author. Description.
393
*/
394
double CBlobGetDistanceFromPoint::operator()(CBlob &blob)
395
{
396
        double xmitjana, ymitjana;
397
        CBlobGetXCenter getXCenter;
398
        CBlobGetYCenter getYCenter;
399
400
        xmitjana = m_x - getXCenter( blob );
401
        ymitjana = m_y - getYCenter( blob );
402
403
        return sqrt((xmitjana*xmitjana)+(ymitjana*ymitjana));
404
}
405
406
/**
407
- FUNCTION: BlobGetXYInside
408
- FUNCTIONALITY: Calculates whether a point is inside the
409
    rectangular bounding box of a blob
410
- PARAMETERS:
411
- RESULT:
412
        - returns 1 if it is inside; o if not
413
- RESTRICTIONS:
414
- AUTHOR: Francesc Pinyol Margalef
415
- CREATION DATE: 16-01-2006.
416
- MODIFICATION: Date. Author. Description.
417
*/
418
double CBlobGetXYInside::operator()(CBlob &blob)
419
{
420
        if( blob.GetExternalContour()->GetContourPoints() )
421
        {
422
                return cvPointPolygonTest( blob.GetExternalContour()->GetContourPoints(), m_p,0) >= 0;
423
        }
424
425
        return 0;
426
}
427
#ifdef BLOB_OBJECT_FACTORY
428
429
/**
430
- FUNCI?: RegistraTotsOperadors
431
- FUNCIONALITAT: Registrar tots els operadors definits a blob.h
432
- PAR?METRES:
433
        - fabricaOperadorsBlob: f?brica on es registraran els operadors
434
- RESULTAT:
435
        - Modifica l'objecte fabricaOperadorsBlob
436
- RESTRICCIONS:
437
        - Nom?s es registraran els operadors de blob.h. Si se'n volen afegir, cal afegir-los amb 
438
          el m?tode Register de la f?brica.
439
- AUTOR: rborras
440
- DATA DE CREACI?: 2006/05/18
441
- MODIFICACI?: Data. Autor. Descripci?.
442
*/
443
void RegistraTotsOperadors( t_OperadorBlobFactory &fabricaOperadorsBlob )
444
{
445
        // blob shape
446
        fabricaOperadorsBlob.Register( CBlobGetArea().GetNom(), Type2Type<CBlobGetArea>());
447
        fabricaOperadorsBlob.Register( CBlobGetBreadth().GetNom(), Type2Type<CBlobGetBreadth>());
448
        fabricaOperadorsBlob.Register( CBlobGetCompactness().GetNom(), Type2Type<CBlobGetCompactness>());
449
        fabricaOperadorsBlob.Register( CBlobGetElongation().GetNom(), Type2Type<CBlobGetElongation>());
450
        fabricaOperadorsBlob.Register( CBlobGetExterior().GetNom(), Type2Type<CBlobGetExterior>());
451
        fabricaOperadorsBlob.Register( CBlobGetLength().GetNom(), Type2Type<CBlobGetLength>());
452
        fabricaOperadorsBlob.Register( CBlobGetPerimeter().GetNom(), Type2Type<CBlobGetPerimeter>());
453
        fabricaOperadorsBlob.Register( CBlobGetRoughness().GetNom(), Type2Type<CBlobGetRoughness>());
454
455
        // blob color
456
        fabricaOperadorsBlob.Register( CBlobGetMean(NULL).GetNom(), Type2Type<CBlobGetMean>());
457
        fabricaOperadorsBlob.Register( CBlobGetStdDev(NULL).GetNom(), Type2Type<CBlobGetStdDev>());
458
459
        // extern pixels
460
        fabricaOperadorsBlob.Register( CBlobGetExternPerimeterRatio().GetNom(), Type2Type<CBlobGetExternPerimeterRatio>());
461
        fabricaOperadorsBlob.Register( CBlobGetExternHullPerimeterRatio().GetNom(), Type2Type<CBlobGetExternHullPerimeterRatio>());
462
        fabricaOperadorsBlob.Register( CBlobGetExternPerimeter().GetNom(), Type2Type<CBlobGetExternPerimeter>());
463
        
464
465
        // hull 
466
        fabricaOperadorsBlob.Register( CBlobGetHullPerimeter().GetNom(), Type2Type<CBlobGetHullPerimeter>());
467
        fabricaOperadorsBlob.Register( CBlobGetHullArea().GetNom(), Type2Type<CBlobGetHullArea>());
468
        
469
470
        // elipse info
471
        fabricaOperadorsBlob.Register( CBlobGetMajorAxisLength().GetNom(), Type2Type<CBlobGetMajorAxisLength>());
472
        fabricaOperadorsBlob.Register( CBlobGetMinorAxisLength().GetNom(), Type2Type<CBlobGetMinorAxisLength>());
473
        fabricaOperadorsBlob.Register( CBlobGetAxisRatio().GetNom(), Type2Type<CBlobGetAxisRatio>());
474
        fabricaOperadorsBlob.Register( CBlobGetOrientation().GetNom(), Type2Type<CBlobGetOrientation>());
475
        fabricaOperadorsBlob.Register( CBlobGetOrientationCos().GetNom(), Type2Type<CBlobGetOrientationCos>());
476
        fabricaOperadorsBlob.Register( CBlobGetAreaElipseRatio().GetNom(), Type2Type<CBlobGetAreaElipseRatio>());
477
478
        // min an max
479
        fabricaOperadorsBlob.Register( CBlobGetMaxX().GetNom(), Type2Type<CBlobGetMaxX>());
480
        fabricaOperadorsBlob.Register( CBlobGetMaxY().GetNom(), Type2Type<CBlobGetMaxY>());
481
        fabricaOperadorsBlob.Register( CBlobGetMinX().GetNom(), Type2Type<CBlobGetMinX>());
482
        fabricaOperadorsBlob.Register( CBlobGetMinY().GetNom(), Type2Type<CBlobGetMinY>());
483
484
        fabricaOperadorsBlob.Register( CBlobGetMaxXatMaxY().GetNom(), Type2Type<CBlobGetMaxXatMaxY>());
485
        fabricaOperadorsBlob.Register( CBlobGetMaxYatMinX().GetNom(), Type2Type<CBlobGetMaxYatMinX>());
486
        fabricaOperadorsBlob.Register( CBlobGetMinXatMinY().GetNom(), Type2Type<CBlobGetMinXatMinY>());
487
        fabricaOperadorsBlob.Register( CBlobGetMinYatMaxX().GetNom(), Type2Type<CBlobGetMinYatMaxX>());
488
489
        // coordinate info
490
        fabricaOperadorsBlob.Register( CBlobGetXYInside().GetNom(), Type2Type<CBlobGetXYInside>());
491
        fabricaOperadorsBlob.Register( CBlobGetDiffY().GetNom(), Type2Type<CBlobGetDiffY>());
492
        fabricaOperadorsBlob.Register( CBlobGetDiffX().GetNom(), Type2Type<CBlobGetDiffX>());
493
        fabricaOperadorsBlob.Register( CBlobGetXCenter().GetNom(), Type2Type<CBlobGetXCenter>());
494
        fabricaOperadorsBlob.Register( CBlobGetYCenter().GetNom(), Type2Type<CBlobGetYCenter>());
495
        fabricaOperadorsBlob.Register( CBlobGetDistanceFromPoint().GetNom(), Type2Type<CBlobGetDistanceFromPoint>());
496
497
        // moments
498
        fabricaOperadorsBlob.Register( CBlobGetMoment().GetNom(), Type2Type<CBlobGetMoment>());
499
500
}
501
502
#endif        //BLOB_OBJECT_FACTORY