some more changes
[profile/ivi/opencv.git] / modules / legacy / include / opencv2 / legacy.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #ifndef __OPENCV_LEGACY_HPP__
43 #define __OPENCV_LEGACY_HPP__
44
45 #include "opencv2/imgproc/imgproc_c.h"
46 #include "opencv2/calib3d/calib3d_c.h"
47 #include "opencv2/ml.hpp"
48
49 #ifdef __cplusplus
50 #include "opencv2/features2d.hpp"
51 extern "C" {
52 #endif
53
54 CVAPI(CvSeq*) cvSegmentImage( const CvArr* srcarr, CvArr* dstarr,
55                                     double canny_threshold,
56                                     double ffill_threshold,
57                                     CvMemStorage* storage );
58
59 /****************************************************************************************\
60 *                                  Eigen objects                                         *
61 \****************************************************************************************/
62
63 typedef int (CV_CDECL * CvCallback)(int index, void* buffer, void* user_data);
64 typedef union
65 {
66     CvCallback callback;
67     void* data;
68 }
69 CvInput;
70
71 #define CV_EIGOBJ_NO_CALLBACK     0
72 #define CV_EIGOBJ_INPUT_CALLBACK  1
73 #define CV_EIGOBJ_OUTPUT_CALLBACK 2
74 #define CV_EIGOBJ_BOTH_CALLBACK   3
75
76 /* Calculates covariation matrix of a set of arrays */
77 CVAPI(void)  cvCalcCovarMatrixEx( int nObjects, void* input, int ioFlags,
78                                   int ioBufSize, uchar* buffer, void* userData,
79                                   IplImage* avg, float* covarMatrix );
80
81 /* Calculates eigen values and vectors of covariation matrix of a set of
82    arrays */
83 CVAPI(void)  cvCalcEigenObjects( int nObjects, void* input, void* output,
84                                  int ioFlags, int ioBufSize, void* userData,
85                                  CvTermCriteria* calcLimit, IplImage* avg,
86                                  float* eigVals );
87
88 /* Calculates dot product (obj - avg) * eigObj (i.e. projects image to eigen vector) */
89 CVAPI(double)  cvCalcDecompCoeff( IplImage* obj, IplImage* eigObj, IplImage* avg );
90
91 /* Projects image to eigen space (finds all decomposion coefficients */
92 CVAPI(void)  cvEigenDecomposite( IplImage* obj, int nEigObjs, void* eigInput,
93                                  int ioFlags, void* userData, IplImage* avg,
94                                  float* coeffs );
95
96 /* Projects original objects used to calculate eigen space basis to that space */
97 CVAPI(void)  cvEigenProjection( void* eigInput, int nEigObjs, int ioFlags,
98                                 void* userData, float* coeffs, IplImage* avg,
99                                 IplImage* proj );
100
101 /****************************************************************************************\
102 *                                       1D/2D HMM                                        *
103 \****************************************************************************************/
104
105 typedef struct CvImgObsInfo
106 {
107     int obs_x;
108     int obs_y;
109     int obs_size;
110     float* obs;//consequtive observations
111
112     int* state;/* arr of pairs superstate/state to which observation belong */
113     int* mix;  /* number of mixture to which observation belong */
114
115 } CvImgObsInfo;/*struct for 1 image*/
116
117 typedef CvImgObsInfo Cv1DObsInfo;
118
119 typedef struct CvEHMMState
120 {
121     int num_mix;        /*number of mixtures in this state*/
122     float* mu;          /*mean vectors corresponding to each mixture*/
123     float* inv_var;     /* square root of inversed variances corresp. to each mixture*/
124     float* log_var_val; /* sum of 0.5 (LN2PI + ln(variance[i]) ) for i=1,n */
125     float* weight;      /*array of mixture weights. Summ of all weights in state is 1. */
126
127 } CvEHMMState;
128
129 typedef struct CvEHMM
130 {
131     int level; /* 0 - lowest(i.e its states are real states), ..... */
132     int num_states; /* number of HMM states */
133     float*  transP;/*transition probab. matrices for states */
134     float** obsProb; /* if level == 0 - array of brob matrices corresponding to hmm
135                         if level == 1 - martix of matrices */
136     union
137     {
138         CvEHMMState* state; /* if level == 0 points to real states array,
139                                if not - points to embedded hmms */
140         struct CvEHMM* ehmm; /* pointer to an embedded model or NULL, if it is a leaf */
141     } u;
142
143 } CvEHMM;
144
145 /*CVAPI(int)  icvCreate1DHMM( CvEHMM** this_hmm,
146                                    int state_number, int* num_mix, int obs_size );
147
148 CVAPI(int)  icvRelease1DHMM( CvEHMM** phmm );
149
150 CVAPI(int)  icvUniform1DSegm( Cv1DObsInfo* obs_info, CvEHMM* hmm );
151
152 CVAPI(int)  icvInit1DMixSegm( Cv1DObsInfo** obs_info_array, int num_img, CvEHMM* hmm);
153
154 CVAPI(int)  icvEstimate1DHMMStateParams( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm);
155
156 CVAPI(int)  icvEstimate1DObsProb( CvImgObsInfo* obs_info, CvEHMM* hmm );
157
158 CVAPI(int)  icvEstimate1DTransProb( Cv1DObsInfo** obs_info_array,
159                                            int num_seq,
160                                            CvEHMM* hmm );
161
162 CVAPI(float)  icvViterbi( Cv1DObsInfo* obs_info, CvEHMM* hmm);
163
164 CVAPI(int)  icv1DMixSegmL2( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm );*/
165
166 /*********************************** Embedded HMMs *************************************/
167
168 /* Creates 2D HMM */
169 CVAPI(CvEHMM*)  cvCreate2DHMM( int* stateNumber, int* numMix, int obsSize );
170
171 /* Releases HMM */
172 CVAPI(void)  cvRelease2DHMM( CvEHMM** hmm );
173
174 #define CV_COUNT_OBS(roi, win, delta, numObs )                                       \
175 {                                                                                    \
176    (numObs)->width  =((roi)->width  -(win)->width  +(delta)->width)/(delta)->width;  \
177    (numObs)->height =((roi)->height -(win)->height +(delta)->height)/(delta)->height;\
178 }
179
180 /* Creates storage for observation vectors */
181 CVAPI(CvImgObsInfo*)  cvCreateObsInfo( CvSize numObs, int obsSize );
182
183 /* Releases storage for observation vectors */
184 CVAPI(void)  cvReleaseObsInfo( CvImgObsInfo** obs_info );
185
186
187 /* The function takes an image on input and and returns the sequnce of observations
188    to be used with an embedded HMM; Each observation is top-left block of DCT
189    coefficient matrix */
190 CVAPI(void)  cvImgToObs_DCT( const CvArr* arr, float* obs, CvSize dctSize,
191                              CvSize obsSize, CvSize delta );
192
193
194 /* Uniformly segments all observation vectors extracted from image */
195 CVAPI(void)  cvUniformImgSegm( CvImgObsInfo* obs_info, CvEHMM* ehmm );
196
197 /* Does mixture segmentation of the states of embedded HMM */
198 CVAPI(void)  cvInitMixSegm( CvImgObsInfo** obs_info_array,
199                             int num_img, CvEHMM* hmm );
200
201 /* Function calculates means, variances, weights of every Gaussian mixture
202    of every low-level state of embedded HMM */
203 CVAPI(void)  cvEstimateHMMStateParams( CvImgObsInfo** obs_info_array,
204                                        int num_img, CvEHMM* hmm );
205
206 /* Function computes transition probability matrices of embedded HMM
207    given observations segmentation */
208 CVAPI(void)  cvEstimateTransProb( CvImgObsInfo** obs_info_array,
209                                   int num_img, CvEHMM* hmm );
210
211 /* Function computes probabilities of appearing observations at any state
212    (i.e. computes P(obs|state) for every pair(obs,state)) */
213 CVAPI(void)  cvEstimateObsProb( CvImgObsInfo* obs_info,
214                                 CvEHMM* hmm );
215
216 /* Runs Viterbi algorithm for embedded HMM */
217 CVAPI(float)  cvEViterbi( CvImgObsInfo* obs_info, CvEHMM* hmm );
218
219
220 /* Function clusters observation vectors from several images
221    given observations segmentation.
222    Euclidean distance used for clustering vectors.
223    Centers of clusters are given means of every mixture */
224 CVAPI(void)  cvMixSegmL2( CvImgObsInfo** obs_info_array,
225                           int num_img, CvEHMM* hmm );
226
227 /****************************************************************************************\
228 *               A few functions from old stereo gesture recognition demosions            *
229 \****************************************************************************************/
230
231 /* Creates hand mask image given several points on the hand */
232 CVAPI(void)  cvCreateHandMask( CvSeq* hand_points,
233                                    IplImage *img_mask, CvRect *roi);
234
235 /* Finds hand region in range image data */
236 CVAPI(void)  cvFindHandRegion (CvPoint3D32f* points, int count,
237                                 CvSeq* indexs,
238                                 float* line, CvSize2D32f size, int flag,
239                                 CvPoint3D32f* center,
240                                 CvMemStorage* storage, CvSeq **numbers);
241
242 /* Finds hand region in range image data (advanced version) */
243 CVAPI(void)  cvFindHandRegionA( CvPoint3D32f* points, int count,
244                                 CvSeq* indexs,
245                                 float* line, CvSize2D32f size, int jc,
246                                 CvPoint3D32f* center,
247                                 CvMemStorage* storage, CvSeq **numbers);
248
249 /* Calculates the cooficients of the homography matrix */
250 CVAPI(void)  cvCalcImageHomography( float* line, CvPoint3D32f* center,
251                                     float* intrinsic, float* homography );
252
253 /****************************************************************************************\
254 *                           More operations on sequences                                 *
255 \****************************************************************************************/
256
257 /*****************************************************************************************/
258
259 #define CV_CURRENT_INT( reader ) (*((int *)(reader).ptr))
260 #define CV_PREV_INT( reader ) (*((int *)(reader).prev_elem))
261
262 #define  CV_GRAPH_WEIGHTED_VERTEX_FIELDS() CV_GRAPH_VERTEX_FIELDS()\
263     float weight;
264
265 #define  CV_GRAPH_WEIGHTED_EDGE_FIELDS() CV_GRAPH_EDGE_FIELDS()
266
267 typedef struct CvGraphWeightedVtx
268 {
269     CV_GRAPH_WEIGHTED_VERTEX_FIELDS()
270 } CvGraphWeightedVtx;
271
272 typedef struct CvGraphWeightedEdge
273 {
274     CV_GRAPH_WEIGHTED_EDGE_FIELDS()
275 } CvGraphWeightedEdge;
276
277 typedef enum CvGraphWeightType
278 {
279     CV_NOT_WEIGHTED,
280     CV_WEIGHTED_VTX,
281     CV_WEIGHTED_EDGE,
282     CV_WEIGHTED_ALL
283 } CvGraphWeightType;
284
285
286 /* Calculates histogram of a contour */
287 CVAPI(void)  cvCalcPGH( const CvSeq* contour, CvHistogram* hist );
288
289 #define CV_DOMINANT_IPAN 1
290
291 /* Finds high-curvature points of the contour */
292 CVAPI(CvSeq*) cvFindDominantPoints( CvSeq* contour, CvMemStorage* storage,
293                                    int method CV_DEFAULT(CV_DOMINANT_IPAN),
294                                    double parameter1 CV_DEFAULT(0),
295                                    double parameter2 CV_DEFAULT(0),
296                                    double parameter3 CV_DEFAULT(0),
297                                    double parameter4 CV_DEFAULT(0));
298
299 /*****************************************************************************************/
300
301
302 /*******************************Stereo correspondence*************************************/
303
304 typedef struct CvCliqueFinder
305 {
306     CvGraph* graph;
307     int**    adj_matr;
308     int N; //graph size
309
310     // stacks, counters etc/
311     int k; //stack size
312     int* current_comp;
313     int** All;
314
315     int* ne;
316     int* ce;
317     int* fixp; //node with minimal disconnections
318     int* nod;
319     int* s; //for selected candidate
320     int status;
321     int best_score;
322     int weighted;
323     int weighted_edges;
324     float best_weight;
325     float* edge_weights;
326     float* vertex_weights;
327     float* cur_weight;
328     float* cand_weight;
329
330 } CvCliqueFinder;
331
332 #define CLIQUE_TIME_OFF 2
333 #define CLIQUE_FOUND 1
334 #define CLIQUE_END   0
335
336 /*CVAPI(void) cvStartFindCliques( CvGraph* graph, CvCliqueFinder* finder, int reverse,
337                                    int weighted CV_DEFAULT(0),  int weighted_edges CV_DEFAULT(0));
338 CVAPI(int) cvFindNextMaximalClique( CvCliqueFinder* finder, int* clock_rest CV_DEFAULT(0) );
339 CVAPI(void) cvEndFindCliques( CvCliqueFinder* finder );
340
341 CVAPI(void) cvBronKerbosch( CvGraph* graph );*/
342
343
344 /*F///////////////////////////////////////////////////////////////////////////////////////
345 //
346 //    Name:    cvSubgraphWeight
347 //    Purpose: finds weight of subgraph in a graph
348 //    Context:
349 //    Parameters:
350 //      graph - input graph.
351 //      subgraph - sequence of pairwise different ints.  These are indices of vertices of subgraph.
352 //      weight_type - describes the way we measure weight.
353 //            one of the following:
354 //            CV_NOT_WEIGHTED - weight of a clique is simply its size
355 //            CV_WEIGHTED_VTX - weight of a clique is the sum of weights of its vertices
356 //            CV_WEIGHTED_EDGE - the same but edges
357 //            CV_WEIGHTED_ALL - the same but both edges and vertices
358 //      weight_vtx - optional vector of floats, with size = graph->total.
359 //            If weight_type is either CV_WEIGHTED_VTX or CV_WEIGHTED_ALL
360 //            weights of vertices must be provided.  If weight_vtx not zero
361 //            these weights considered to be here, otherwise function assumes
362 //            that vertices of graph are inherited from CvGraphWeightedVtx.
363 //      weight_edge - optional matrix of floats, of width and height = graph->total.
364 //            If weight_type is either CV_WEIGHTED_EDGE or CV_WEIGHTED_ALL
365 //            weights of edges ought to be supplied.  If weight_edge is not zero
366 //            function finds them here, otherwise function expects
367 //            edges of graph to be inherited from CvGraphWeightedEdge.
368 //            If this parameter is not zero structure of the graph is determined from matrix
369 //            rather than from CvGraphEdge's.  In particular, elements corresponding to
370 //            absent edges should be zero.
371 //    Returns:
372 //      weight of subgraph.
373 //    Notes:
374 //F*/
375 /*CVAPI(float) cvSubgraphWeight( CvGraph *graph, CvSeq *subgraph,
376                                   CvGraphWeightType weight_type CV_DEFAULT(CV_NOT_WEIGHTED),
377                                   CvVect32f weight_vtx CV_DEFAULT(0),
378                                   CvMatr32f weight_edge CV_DEFAULT(0) );*/
379
380
381 /*F///////////////////////////////////////////////////////////////////////////////////////
382 //
383 //    Name:    cvFindCliqueEx
384 //    Purpose: tries to find clique with maximum possible weight in a graph
385 //    Context:
386 //    Parameters:
387 //      graph - input graph.
388 //      storage - memory storage to be used by the result.
389 //      is_complementary - optional flag showing whether function should seek for clique
390 //            in complementary graph.
391 //      weight_type - describes our notion about weight.
392 //            one of the following:
393 //            CV_NOT_WEIGHTED - weight of a clique is simply its size
394 //            CV_WEIGHTED_VTX - weight of a clique is the sum of weights of its vertices
395 //            CV_WEIGHTED_EDGE - the same but edges
396 //            CV_WEIGHTED_ALL - the same but both edges and vertices
397 //      weight_vtx - optional vector of floats, with size = graph->total.
398 //            If weight_type is either CV_WEIGHTED_VTX or CV_WEIGHTED_ALL
399 //            weights of vertices must be provided.  If weight_vtx not zero
400 //            these weights considered to be here, otherwise function assumes
401 //            that vertices of graph are inherited from CvGraphWeightedVtx.
402 //      weight_edge - optional matrix of floats, of width and height = graph->total.
403 //            If weight_type is either CV_WEIGHTED_EDGE or CV_WEIGHTED_ALL
404 //            weights of edges ought to be supplied.  If weight_edge is not zero
405 //            function finds them here, otherwise function expects
406 //            edges of graph to be inherited from CvGraphWeightedEdge.
407 //            Note that in case of CV_WEIGHTED_EDGE or CV_WEIGHTED_ALL
408 //            nonzero is_complementary implies nonzero weight_edge.
409 //      start_clique - optional sequence of pairwise different ints.  They are indices of
410 //            vertices that shall be present in the output clique.
411 //      subgraph_of_ban - optional sequence of (maybe equal) ints.  They are indices of
412 //            vertices that shall not be present in the output clique.
413 //      clique_weight_ptr - optional output parameter.  Weight of found clique stored here.
414 //      num_generations - optional number of generations in evolutionary part of algorithm,
415 //            zero forces to return first found clique.
416 //      quality - optional parameter determining degree of required quality/speed tradeoff.
417 //            Must be in the range from 0 to 9.
418 //            0 is fast and dirty, 9 is slow but hopefully yields good clique.
419 //    Returns:
420 //      sequence of pairwise different ints.
421 //      These are indices of vertices that form found clique.
422 //    Notes:
423 //      in cases of CV_WEIGHTED_EDGE and CV_WEIGHTED_ALL weights should be nonnegative.
424 //      start_clique has a priority over subgraph_of_ban.
425 //F*/
426 /*CVAPI(CvSeq*) cvFindCliqueEx( CvGraph *graph, CvMemStorage *storage,
427                                  int is_complementary CV_DEFAULT(0),
428                                  CvGraphWeightType weight_type CV_DEFAULT(CV_NOT_WEIGHTED),
429                                  CvVect32f weight_vtx CV_DEFAULT(0),
430                                  CvMatr32f weight_edge CV_DEFAULT(0),
431                                  CvSeq *start_clique CV_DEFAULT(0),
432                                  CvSeq *subgraph_of_ban CV_DEFAULT(0),
433                                  float *clique_weight_ptr CV_DEFAULT(0),
434                                  int num_generations CV_DEFAULT(3),
435                                  int quality CV_DEFAULT(2) );*/
436
437
438 #define CV_UNDEF_SC_PARAM         12345 //default value of parameters
439
440 #define CV_IDP_BIRCHFIELD_PARAM1  25
441 #define CV_IDP_BIRCHFIELD_PARAM2  5
442 #define CV_IDP_BIRCHFIELD_PARAM3  12
443 #define CV_IDP_BIRCHFIELD_PARAM4  15
444 #define CV_IDP_BIRCHFIELD_PARAM5  25
445
446
447 #define  CV_DISPARITY_BIRCHFIELD  0
448
449
450 /*F///////////////////////////////////////////////////////////////////////////
451 //
452 //    Name:    cvFindStereoCorrespondence
453 //    Purpose: find stereo correspondence on stereo-pair
454 //    Context:
455 //    Parameters:
456 //      leftImage - left image of stereo-pair (format 8uC1).
457 //      rightImage - right image of stereo-pair (format 8uC1).
458 //   mode - mode of correspondence retrieval (now CV_DISPARITY_BIRCHFIELD only)
459 //      dispImage - destination disparity image
460 //      maxDisparity - maximal disparity
461 //      param1, param2, param3, param4, param5 - parameters of algorithm
462 //    Returns:
463 //    Notes:
464 //      Images must be rectified.
465 //      All images must have format 8uC1.
466 //F*/
467 CVAPI(void)
468 cvFindStereoCorrespondence(
469                    const  CvArr* leftImage, const  CvArr* rightImage,
470                    int     mode,
471                    CvArr*  dispImage,
472                    int     maxDisparity,
473                    double  param1 CV_DEFAULT(CV_UNDEF_SC_PARAM),
474                    double  param2 CV_DEFAULT(CV_UNDEF_SC_PARAM),
475                    double  param3 CV_DEFAULT(CV_UNDEF_SC_PARAM),
476                    double  param4 CV_DEFAULT(CV_UNDEF_SC_PARAM),
477                    double  param5 CV_DEFAULT(CV_UNDEF_SC_PARAM) );
478
479 /*****************************************************************************************/
480 /************ Epiline functions *******************/
481
482
483
484 typedef struct CvStereoLineCoeff
485 {
486     double Xcoef;
487     double XcoefA;
488     double XcoefB;
489     double XcoefAB;
490
491     double Ycoef;
492     double YcoefA;
493     double YcoefB;
494     double YcoefAB;
495
496     double Zcoef;
497     double ZcoefA;
498     double ZcoefB;
499     double ZcoefAB;
500 }CvStereoLineCoeff;
501
502
503 typedef struct CvCamera
504 {
505     float   imgSize[2]; /* size of the camera view, used during calibration */
506     float   matrix[9]; /* intinsic camera parameters:  [ fx 0 cx; 0 fy cy; 0 0 1 ] */
507     float   distortion[4]; /* distortion coefficients - two coefficients for radial distortion
508                               and another two for tangential: [ k1 k2 p1 p2 ] */
509     float   rotMatr[9];
510     float   transVect[3]; /* rotation matrix and transition vector relatively
511                              to some reference point in the space. */
512 } CvCamera;
513
514 typedef struct CvStereoCamera
515 {
516     CvCamera* camera[2]; /* two individual camera parameters */
517     float fundMatr[9]; /* fundamental matrix */
518
519     /* New part for stereo */
520     CvPoint3D32f epipole[2];
521     CvPoint2D32f quad[2][4]; /* coordinates of destination quadrangle after
522                                 epipolar geometry rectification */
523     double coeffs[2][3][3];/* coefficients for transformation */
524     CvPoint2D32f border[2][4];
525     CvSize warpSize;
526     CvStereoLineCoeff* lineCoeffs;
527     int needSwapCameras;/* flag set to 1 if need to swap cameras for good reconstruction */
528     float rotMatrix[9];
529     float transVector[3];
530 } CvStereoCamera;
531
532
533 typedef struct CvContourOrientation
534 {
535     float egvals[2];
536     float egvects[4];
537
538     float max, min; // minimum and maximum projections
539     int imax, imin;
540 } CvContourOrientation;
541
542 #define CV_CAMERA_TO_WARP 1
543 #define CV_WARP_TO_CAMERA 2
544
545 CVAPI(int) icvConvertWarpCoordinates(double coeffs[3][3],
546                                 CvPoint2D32f* cameraPoint,
547                                 CvPoint2D32f* warpPoint,
548                                 int direction);
549
550 CVAPI(int) icvGetSymPoint3D(  CvPoint3D64f pointCorner,
551                             CvPoint3D64f point1,
552                             CvPoint3D64f point2,
553                             CvPoint3D64f *pointSym2);
554
555 CVAPI(void) icvGetPieceLength3D(CvPoint3D64f point1,CvPoint3D64f point2,double* dist);
556
557 CVAPI(int) icvCompute3DPoint(    double alpha,double betta,
558                             CvStereoLineCoeff* coeffs,
559                             CvPoint3D64f* point);
560
561 CVAPI(int) icvCreateConvertMatrVect( double*     rotMatr1,
562                                 double*     transVect1,
563                                 double*     rotMatr2,
564                                 double*     transVect2,
565                                 double*     convRotMatr,
566                                 double*     convTransVect);
567
568 CVAPI(int) icvConvertPointSystem(CvPoint3D64f  M2,
569                             CvPoint3D64f* M1,
570                             double*     rotMatr,
571                             double*     transVect
572                             );
573
574 CVAPI(int) icvComputeCoeffForStereo(  CvStereoCamera* stereoCamera);
575
576 CVAPI(int) icvGetCrossPieceVector(CvPoint2D32f p1_start,CvPoint2D32f p1_end,CvPoint2D32f v2_start,CvPoint2D32f v2_end,CvPoint2D32f *cross);
577 CVAPI(int) icvGetCrossLineDirect(CvPoint2D32f p1,CvPoint2D32f p2,float a,float b,float c,CvPoint2D32f* cross);
578 CVAPI(float) icvDefinePointPosition(CvPoint2D32f point1,CvPoint2D32f point2,CvPoint2D32f point);
579 CVAPI(int) icvStereoCalibration( int numImages,
580                             int* nums,
581                             CvSize imageSize,
582                             CvPoint2D32f* imagePoints1,
583                             CvPoint2D32f* imagePoints2,
584                             CvPoint3D32f* objectPoints,
585                             CvStereoCamera* stereoparams
586                            );
587
588
589 CVAPI(int) icvComputeRestStereoParams(CvStereoCamera *stereoparams);
590
591 CVAPI(void) cvComputePerspectiveMap( const double coeffs[3][3], CvArr* rectMapX, CvArr* rectMapY );
592
593 CVAPI(int) icvComCoeffForLine(   CvPoint2D64f point1,
594                             CvPoint2D64f point2,
595                             CvPoint2D64f point3,
596                             CvPoint2D64f point4,
597                             double*    camMatr1,
598                             double*    rotMatr1,
599                             double*    transVect1,
600                             double*    camMatr2,
601                             double*    rotMatr2,
602                             double*    transVect2,
603                             CvStereoLineCoeff*    coeffs,
604                             int* needSwapCameras);
605
606 CVAPI(int) icvGetDirectionForPoint(  CvPoint2D64f point,
607                                 double* camMatr,
608                                 CvPoint3D64f* direct);
609
610 CVAPI(int) icvGetCrossLines(CvPoint3D64f point11,CvPoint3D64f point12,
611                        CvPoint3D64f point21,CvPoint3D64f point22,
612                        CvPoint3D64f* midPoint);
613
614 CVAPI(int) icvComputeStereoLineCoeffs(   CvPoint3D64f pointA,
615                                     CvPoint3D64f pointB,
616                                     CvPoint3D64f pointCam1,
617                                     double gamma,
618                                     CvStereoLineCoeff*    coeffs);
619
620 /*CVAPI(int) icvComputeFundMatrEpipoles ( double* camMatr1,
621                                     double*     rotMatr1,
622                                     double*     transVect1,
623                                     double*     camMatr2,
624                                     double*     rotMatr2,
625                                     double*     transVect2,
626                                     CvPoint2D64f* epipole1,
627                                     CvPoint2D64f* epipole2,
628                                     double*     fundMatr);*/
629
630 CVAPI(int) icvGetAngleLine( CvPoint2D64f startPoint, CvSize imageSize,CvPoint2D64f *point1,CvPoint2D64f *point2);
631
632 CVAPI(void) icvGetCoefForPiece(   CvPoint2D64f p_start,CvPoint2D64f p_end,
633                         double *a,double *b,double *c,
634                         int* result);
635
636 /*CVAPI(void) icvGetCommonArea( CvSize imageSize,
637                     CvPoint2D64f epipole1,CvPoint2D64f epipole2,
638                     double* fundMatr,
639                     double* coeff11,double* coeff12,
640                     double* coeff21,double* coeff22,
641                     int* result);*/
642
643 CVAPI(void) icvComputeeInfiniteProject1(double*    rotMatr,
644                                      double*    camMatr1,
645                                      double*    camMatr2,
646                                      CvPoint2D32f point1,
647                                      CvPoint2D32f *point2);
648
649 CVAPI(void) icvComputeeInfiniteProject2(double*    rotMatr,
650                                      double*    camMatr1,
651                                      double*    camMatr2,
652                                      CvPoint2D32f* point1,
653                                      CvPoint2D32f point2);
654
655 CVAPI(void) icvGetCrossDirectDirect(  double* direct1,double* direct2,
656                             CvPoint2D64f *cross,int* result);
657
658 CVAPI(void) icvGetCrossPieceDirect(   CvPoint2D64f p_start,CvPoint2D64f p_end,
659                             double a,double b,double c,
660                             CvPoint2D64f *cross,int* result);
661
662 CVAPI(void) icvGetCrossPiecePiece( CvPoint2D64f p1_start,CvPoint2D64f p1_end,
663                             CvPoint2D64f p2_start,CvPoint2D64f p2_end,
664                             CvPoint2D64f* cross,
665                             int* result);
666
667 CVAPI(void) icvGetPieceLength(CvPoint2D64f point1,CvPoint2D64f point2,double* dist);
668
669 CVAPI(void) icvGetCrossRectDirect(    CvSize imageSize,
670                             double a,double b,double c,
671                             CvPoint2D64f *start,CvPoint2D64f *end,
672                             int* result);
673
674 CVAPI(void) icvProjectPointToImage(   CvPoint3D64f point,
675                             double* camMatr,double* rotMatr,double* transVect,
676                             CvPoint2D64f* projPoint);
677
678 CVAPI(void) icvGetQuadsTransform( CvSize        imageSize,
679                         double*     camMatr1,
680                         double*     rotMatr1,
681                         double*     transVect1,
682                         double*     camMatr2,
683                         double*     rotMatr2,
684                         double*     transVect2,
685                         CvSize*       warpSize,
686                         double quad1[4][2],
687                         double quad2[4][2],
688                         double*     fundMatr,
689                         CvPoint3D64f* epipole1,
690                         CvPoint3D64f* epipole2
691                         );
692
693 CVAPI(void) icvGetQuadsTransformStruct(  CvStereoCamera* stereoCamera);
694
695 CVAPI(void) icvComputeStereoParamsForCameras(CvStereoCamera* stereoCamera);
696
697 CVAPI(void) icvGetCutPiece(   double* areaLineCoef1,double* areaLineCoef2,
698                     CvPoint2D64f epipole,
699                     CvSize imageSize,
700                     CvPoint2D64f* point11,CvPoint2D64f* point12,
701                     CvPoint2D64f* point21,CvPoint2D64f* point22,
702                     int* result);
703
704 CVAPI(void) icvGetMiddleAnglePoint(   CvPoint2D64f basePoint,
705                             CvPoint2D64f point1,CvPoint2D64f point2,
706                             CvPoint2D64f* midPoint);
707
708 CVAPI(void) icvGetNormalDirect(double* direct,CvPoint2D64f point,double* normDirect);
709
710 CVAPI(double) icvGetVect(CvPoint2D64f basePoint,CvPoint2D64f point1,CvPoint2D64f point2);
711
712 CVAPI(void) icvProjectPointToDirect(  CvPoint2D64f point,double* lineCoeff,
713                             CvPoint2D64f* projectPoint);
714
715 CVAPI(void) icvGetDistanceFromPointToDirect( CvPoint2D64f point,double* lineCoef,double*dist);
716
717 CVAPI(IplImage*) icvCreateIsometricImage( IplImage* src, IplImage* dst,
718                               int desired_depth, int desired_num_channels );
719
720 CVAPI(void) cvDeInterlace( const CvArr* frame, CvArr* fieldEven, CvArr* fieldOdd );
721
722 /*CVAPI(int) icvSelectBestRt(           int           numImages,
723                                     int*          numPoints,
724                                     CvSize        imageSize,
725                                     CvPoint2D32f* imagePoints1,
726                                     CvPoint2D32f* imagePoints2,
727                                     CvPoint3D32f* objectPoints,
728
729                                     CvMatr32f     cameraMatrix1,
730                                     CvVect32f     distortion1,
731                                     CvMatr32f     rotMatrs1,
732                                     CvVect32f     transVects1,
733
734                                     CvMatr32f     cameraMatrix2,
735                                     CvVect32f     distortion2,
736                                     CvMatr32f     rotMatrs2,
737                                     CvVect32f     transVects2,
738
739                                     CvMatr32f     bestRotMatr,
740                                     CvVect32f     bestTransVect
741                                     );*/
742
743
744 /****************************************************************************************\
745 *                                     Contour Tree                                       *
746 \****************************************************************************************/
747
748 /* Contour tree header */
749 typedef struct CvContourTree
750 {
751     CV_SEQUENCE_FIELDS()
752     CvPoint p1;            /* the first point of the binary tree root segment */
753     CvPoint p2;            /* the last point of the binary tree root segment */
754 } CvContourTree;
755
756 /* Builds hierarhical representation of a contour */
757 CVAPI(CvContourTree*)  cvCreateContourTree( const CvSeq* contour,
758                                             CvMemStorage* storage,
759                                             double threshold );
760
761 /* Reconstruct (completelly or partially) contour a from contour tree */
762 CVAPI(CvSeq*)  cvContourFromContourTree( const CvContourTree* tree,
763                                          CvMemStorage* storage,
764                                          CvTermCriteria criteria );
765
766 /* Compares two contour trees */
767 enum { CV_CONTOUR_TREES_MATCH_I1 = 1 };
768
769 CVAPI(double)  cvMatchContourTrees( const CvContourTree* tree1,
770                                     const CvContourTree* tree2,
771                                     int method, double threshold );
772
773 /****************************************************************************************\
774 *                                   Contour Morphing                                     *
775 \****************************************************************************************/
776
777 /* finds correspondence between two contours */
778 CvSeq* cvCalcContoursCorrespondence( const CvSeq* contour1,
779                                      const CvSeq* contour2,
780                                      CvMemStorage* storage);
781
782 /* morphs contours using the pre-calculated correspondence:
783    alpha=0 ~ contour1, alpha=1 ~ contour2 */
784 CvSeq* cvMorphContours( const CvSeq* contour1, const CvSeq* contour2,
785                         CvSeq* corr, double alpha,
786                         CvMemStorage* storage );
787
788
789 /****************************************************************************************\
790 *                                   Active Contours                                      *
791 \****************************************************************************************/
792
793 #define  CV_VALUE  1
794 #define  CV_ARRAY  2
795 /* Updates active contour in order to minimize its cummulative
796    (internal and external) energy. */
797 CVAPI(void)  cvSnakeImage( const IplImage* image, CvPoint* points,
798                            int  length, float* alpha,
799                            float* beta, float* gamma,
800                            int coeff_usage, CvSize  win,
801                            CvTermCriteria criteria, int calc_gradient CV_DEFAULT(1));
802
803 /****************************************************************************************\
804 *                                    Texture Descriptors                                 *
805 \****************************************************************************************/
806
807 #define CV_GLCM_OPTIMIZATION_NONE                   -2
808 #define CV_GLCM_OPTIMIZATION_LUT                    -1
809 #define CV_GLCM_OPTIMIZATION_HISTOGRAM              0
810
811 #define CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST    10
812 #define CV_GLCMDESC_OPTIMIZATION_ALLOWTRIPLENEST    11
813 #define CV_GLCMDESC_OPTIMIZATION_HISTOGRAM          4
814
815 #define CV_GLCMDESC_ENTROPY                         0
816 #define CV_GLCMDESC_ENERGY                          1
817 #define CV_GLCMDESC_HOMOGENITY                      2
818 #define CV_GLCMDESC_CONTRAST                        3
819 #define CV_GLCMDESC_CLUSTERTENDENCY                 4
820 #define CV_GLCMDESC_CLUSTERSHADE                    5
821 #define CV_GLCMDESC_CORRELATION                     6
822 #define CV_GLCMDESC_CORRELATIONINFO1                7
823 #define CV_GLCMDESC_CORRELATIONINFO2                8
824 #define CV_GLCMDESC_MAXIMUMPROBABILITY              9
825
826 #define CV_GLCM_ALL                                 0
827 #define CV_GLCM_GLCM                                1
828 #define CV_GLCM_DESC                                2
829
830 typedef struct CvGLCM CvGLCM;
831
832 CVAPI(CvGLCM*) cvCreateGLCM( const IplImage* srcImage,
833                                 int stepMagnitude,
834                                 const int* stepDirections CV_DEFAULT(0),
835                                 int numStepDirections CV_DEFAULT(0),
836                                 int optimizationType CV_DEFAULT(CV_GLCM_OPTIMIZATION_NONE));
837
838 CVAPI(void) cvReleaseGLCM( CvGLCM** GLCM, int flag CV_DEFAULT(CV_GLCM_ALL));
839
840 CVAPI(void) cvCreateGLCMDescriptors( CvGLCM* destGLCM,
841                                         int descriptorOptimizationType
842                                         CV_DEFAULT(CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST));
843
844 CVAPI(double) cvGetGLCMDescriptor( CvGLCM* GLCM, int step, int descriptor );
845
846 CVAPI(void) cvGetGLCMDescriptorStatistics( CvGLCM* GLCM, int descriptor,
847                                               double* average, double* standardDeviation );
848
849 CVAPI(IplImage*) cvCreateGLCMImage( CvGLCM* GLCM, int step );
850
851 /****************************************************************************************\
852 *                                  Face eyes&mouth tracking                              *
853 \****************************************************************************************/
854
855
856 typedef struct CvFaceTracker CvFaceTracker;
857
858 #define CV_NUM_FACE_ELEMENTS    3
859 enum CV_FACE_ELEMENTS
860 {
861     CV_FACE_MOUTH = 0,
862     CV_FACE_LEFT_EYE = 1,
863     CV_FACE_RIGHT_EYE = 2
864 };
865
866 CVAPI(CvFaceTracker*) cvInitFaceTracker(CvFaceTracker* pFaceTracking, const IplImage* imgGray,
867                                                 CvRect* pRects, int nRects);
868 CVAPI(int) cvTrackFace( CvFaceTracker* pFaceTracker, IplImage* imgGray,
869                               CvRect* pRects, int nRects,
870                               CvPoint* ptRotate, double* dbAngleRotate);
871 CVAPI(void) cvReleaseFaceTracker(CvFaceTracker** ppFaceTracker);
872
873
874 typedef struct CvFace
875 {
876     CvRect MouthRect;
877     CvRect LeftEyeRect;
878     CvRect RightEyeRect;
879 } CvFaceData;
880
881 CvSeq * cvFindFace(IplImage * Image,CvMemStorage* storage);
882 CvSeq * cvPostBoostingFindFace(IplImage * Image,CvMemStorage* storage);
883
884
885 /****************************************************************************************\
886 *                                         3D Tracker                                     *
887 \****************************************************************************************/
888
889 typedef unsigned char CvBool;
890
891 typedef struct Cv3dTracker2dTrackedObject
892 {
893     int id;
894     CvPoint2D32f p; // pgruebele: So we do not loose precision, this needs to be float
895 } Cv3dTracker2dTrackedObject;
896
897 CV_INLINE Cv3dTracker2dTrackedObject cv3dTracker2dTrackedObject(int id, CvPoint2D32f p)
898 {
899     Cv3dTracker2dTrackedObject r;
900     r.id = id;
901     r.p = p;
902     return r;
903 }
904
905 typedef struct Cv3dTrackerTrackedObject
906 {
907     int id;
908     CvPoint3D32f p;             // location of the tracked object
909 } Cv3dTrackerTrackedObject;
910
911 CV_INLINE Cv3dTrackerTrackedObject cv3dTrackerTrackedObject(int id, CvPoint3D32f p)
912 {
913     Cv3dTrackerTrackedObject r;
914     r.id = id;
915     r.p = p;
916     return r;
917 }
918
919 typedef struct Cv3dTrackerCameraInfo
920 {
921     CvBool valid;
922     float mat[4][4];              /* maps camera coordinates to world coordinates */
923     CvPoint2D32f principal_point; /* copied from intrinsics so this structure */
924                                   /* has all the info we need */
925 } Cv3dTrackerCameraInfo;
926
927 typedef struct Cv3dTrackerCameraIntrinsics
928 {
929     CvPoint2D32f principal_point;
930     float focal_length[2];
931     float distortion[4];
932 } Cv3dTrackerCameraIntrinsics;
933
934 CVAPI(CvBool) cv3dTrackerCalibrateCameras(int num_cameras,
935                      const Cv3dTrackerCameraIntrinsics camera_intrinsics[], /* size is num_cameras */
936                      CvSize etalon_size,
937                      float square_size,
938                      IplImage *samples[],                                   /* size is num_cameras */
939                      Cv3dTrackerCameraInfo camera_info[]);                  /* size is num_cameras */
940
941 CVAPI(int)  cv3dTrackerLocateObjects(int num_cameras, int num_objects,
942                    const Cv3dTrackerCameraInfo camera_info[],        /* size is num_cameras */
943                    const Cv3dTracker2dTrackedObject tracking_info[], /* size is num_objects*num_cameras */
944                    Cv3dTrackerTrackedObject tracked_objects[]);      /* size is num_objects */
945 /****************************************************************************************
946  tracking_info is a rectangular array; one row per camera, num_objects elements per row.
947  The id field of any unused slots must be -1. Ids need not be ordered or consecutive. On
948  completion, the return value is the number of objects located; i.e., the number of objects
949  visible by more than one camera. The id field of any unused slots in tracked objects is
950  set to -1.
951 ****************************************************************************************/
952
953
954 /****************************************************************************************\
955 *                           Skeletons and Linear-Contour Models                          *
956 \****************************************************************************************/
957
958 typedef enum CvLeeParameters
959 {
960     CV_LEE_INT = 0,
961     CV_LEE_FLOAT = 1,
962     CV_LEE_DOUBLE = 2,
963     CV_LEE_AUTO = -1,
964     CV_LEE_ERODE = 0,
965     CV_LEE_ZOOM = 1,
966     CV_LEE_NON = 2
967 } CvLeeParameters;
968
969 #define CV_NEXT_VORONOISITE2D( SITE ) ((SITE)->edge[0]->site[((SITE)->edge[0]->site[0] == (SITE))])
970 #define CV_PREV_VORONOISITE2D( SITE ) ((SITE)->edge[1]->site[((SITE)->edge[1]->site[0] == (SITE))])
971 #define CV_FIRST_VORONOIEDGE2D( SITE ) ((SITE)->edge[0])
972 #define CV_LAST_VORONOIEDGE2D( SITE ) ((SITE)->edge[1])
973 #define CV_NEXT_VORONOIEDGE2D( EDGE, SITE ) ((EDGE)->next[(EDGE)->site[0] != (SITE)])
974 #define CV_PREV_VORONOIEDGE2D( EDGE, SITE ) ((EDGE)->next[2 + ((EDGE)->site[0] != (SITE))])
975 #define CV_VORONOIEDGE2D_BEGINNODE( EDGE, SITE ) ((EDGE)->node[((EDGE)->site[0] != (SITE))])
976 #define CV_VORONOIEDGE2D_ENDNODE( EDGE, SITE ) ((EDGE)->node[((EDGE)->site[0] == (SITE))])
977 #define CV_TWIN_VORONOISITE2D( SITE, EDGE ) ( (EDGE)->site[((EDGE)->site[0] == (SITE))])
978
979 #define CV_VORONOISITE2D_FIELDS()    \
980     struct CvVoronoiNode2D *node[2]; \
981     struct CvVoronoiEdge2D *edge[2];
982
983 typedef struct CvVoronoiSite2D
984 {
985     CV_VORONOISITE2D_FIELDS()
986     struct CvVoronoiSite2D *next[2];
987 } CvVoronoiSite2D;
988
989 #define CV_VORONOIEDGE2D_FIELDS()    \
990     struct CvVoronoiNode2D *node[2]; \
991     struct CvVoronoiSite2D *site[2]; \
992     struct CvVoronoiEdge2D *next[4];
993
994 typedef struct CvVoronoiEdge2D
995 {
996     CV_VORONOIEDGE2D_FIELDS()
997 } CvVoronoiEdge2D;
998
999 #define CV_VORONOINODE2D_FIELDS()       \
1000     CV_SET_ELEM_FIELDS(CvVoronoiNode2D) \
1001     CvPoint2D32f pt;                    \
1002     float radius;
1003
1004 typedef struct CvVoronoiNode2D
1005 {
1006     CV_VORONOINODE2D_FIELDS()
1007 } CvVoronoiNode2D;
1008
1009 #define CV_VORONOIDIAGRAM2D_FIELDS() \
1010     CV_GRAPH_FIELDS()                \
1011     CvSet *sites;
1012
1013 typedef struct CvVoronoiDiagram2D
1014 {
1015     CV_VORONOIDIAGRAM2D_FIELDS()
1016 } CvVoronoiDiagram2D;
1017
1018 /* Computes Voronoi Diagram for given polygons with holes */
1019 CVAPI(int)  cvVoronoiDiagramFromContour(CvSeq* ContourSeq,
1020                                            CvVoronoiDiagram2D** VoronoiDiagram,
1021                                            CvMemStorage* VoronoiStorage,
1022                                            CvLeeParameters contour_type CV_DEFAULT(CV_LEE_INT),
1023                                            int contour_orientation CV_DEFAULT(-1),
1024                                            int attempt_number CV_DEFAULT(10));
1025
1026 /* Computes Voronoi Diagram for domains in given image */
1027 CVAPI(int)  cvVoronoiDiagramFromImage(IplImage* pImage,
1028                                          CvSeq** ContourSeq,
1029                                          CvVoronoiDiagram2D** VoronoiDiagram,
1030                                          CvMemStorage* VoronoiStorage,
1031                                          CvLeeParameters regularization_method CV_DEFAULT(CV_LEE_NON),
1032                                          float approx_precision CV_DEFAULT(CV_LEE_AUTO));
1033
1034 /* Deallocates the storage */
1035 CVAPI(void) cvReleaseVoronoiStorage(CvVoronoiDiagram2D* VoronoiDiagram,
1036                                           CvMemStorage** pVoronoiStorage);
1037
1038 /*********************** Linear-Contour Model ****************************/
1039
1040 struct CvLCMEdge;
1041 struct CvLCMNode;
1042
1043 typedef struct CvLCMEdge
1044 {
1045     CV_GRAPH_EDGE_FIELDS()
1046     CvSeq* chain;
1047     float width;
1048     int index1;
1049     int index2;
1050 } CvLCMEdge;
1051
1052 typedef struct CvLCMNode
1053 {
1054     CV_GRAPH_VERTEX_FIELDS()
1055     CvContour* contour;
1056 } CvLCMNode;
1057
1058
1059 /* Computes hybrid model from Voronoi Diagram */
1060 CVAPI(CvGraph*) cvLinearContorModelFromVoronoiDiagram(CvVoronoiDiagram2D* VoronoiDiagram,
1061                                                          float maxWidth);
1062
1063 /* Releases hybrid model storage */
1064 CVAPI(int) cvReleaseLinearContorModelStorage(CvGraph** Graph);
1065
1066
1067 /* two stereo-related functions */
1068
1069 CVAPI(void) cvInitPerspectiveTransform( CvSize size, const CvPoint2D32f vertex[4], double matrix[3][3],
1070                                               CvArr* rectMap );
1071
1072 /*CVAPI(void) cvInitStereoRectification( CvStereoCamera* params,
1073                                              CvArr* rectMap1, CvArr* rectMap2,
1074                                              int do_undistortion );*/
1075
1076 /*************************** View Morphing Functions ************************/
1077
1078 typedef struct CvMatrix3
1079 {
1080     float m[3][3];
1081 } CvMatrix3;
1082
1083 /* The order of the function corresponds to the order they should appear in
1084    the view morphing pipeline */
1085
1086 /* Finds ending points of scanlines on left and right images of stereo-pair */
1087 CVAPI(void)  cvMakeScanlines( const CvMatrix3* matrix, CvSize  img_size,
1088                               int*  scanlines1, int*  scanlines2,
1089                               int*  lengths1, int*  lengths2,
1090                               int*  line_count );
1091
1092 /* Grab pixel values from scanlines and stores them sequentially
1093    (some sort of perspective image transform) */
1094 CVAPI(void)  cvPreWarpImage( int       line_count,
1095                              IplImage* img,
1096                              uchar*    dst,
1097                              int*      dst_nums,
1098                              int*      scanlines);
1099
1100 /* Approximate each grabbed scanline by a sequence of runs
1101    (lossy run-length compression) */
1102 CVAPI(void)  cvFindRuns( int    line_count,
1103                          uchar* prewarp1,
1104                          uchar* prewarp2,
1105                          int*   line_lengths1,
1106                          int*   line_lengths2,
1107                          int*   runs1,
1108                          int*   runs2,
1109                          int*   num_runs1,
1110                          int*   num_runs2);
1111
1112 /* Compares two sets of compressed scanlines */
1113 CVAPI(void)  cvDynamicCorrespondMulti( int  line_count,
1114                                        int* first,
1115                                        int* first_runs,
1116                                        int* second,
1117                                        int* second_runs,
1118                                        int* first_corr,
1119                                        int* second_corr);
1120
1121 /* Finds scanline ending coordinates for some intermediate "virtual" camera position */
1122 CVAPI(void)  cvMakeAlphaScanlines( int*  scanlines1,
1123                                    int*  scanlines2,
1124                                    int*  scanlinesA,
1125                                    int*  lengths,
1126                                    int   line_count,
1127                                    float alpha);
1128
1129 /* Blends data of the left and right image scanlines to get
1130    pixel values of "virtual" image scanlines */
1131 CVAPI(void)  cvMorphEpilinesMulti( int    line_count,
1132                                    uchar* first_pix,
1133                                    int*   first_num,
1134                                    uchar* second_pix,
1135                                    int*   second_num,
1136                                    uchar* dst_pix,
1137                                    int*   dst_num,
1138                                    float  alpha,
1139                                    int*   first,
1140                                    int*   first_runs,
1141                                    int*   second,
1142                                    int*   second_runs,
1143                                    int*   first_corr,
1144                                    int*   second_corr);
1145
1146 /* Does reverse warping of the morphing result to make
1147    it fill the destination image rectangle */
1148 CVAPI(void)  cvPostWarpImage( int       line_count,
1149                               uchar*    src,
1150                               int*      src_nums,
1151                               IplImage* img,
1152                               int*      scanlines);
1153
1154 /* Deletes Moire (missed pixels that appear due to discretization) */
1155 CVAPI(void)  cvDeleteMoire( IplImage*  img );
1156
1157
1158 typedef struct CvConDensation
1159 {
1160     int MP;
1161     int DP;
1162     float* DynamMatr;       /* Matrix of the linear Dynamics system  */
1163     float* State;           /* Vector of State                       */
1164     int SamplesNum;         /* Number of the Samples                 */
1165     float** flSamples;      /* arr of the Sample Vectors             */
1166     float** flNewSamples;   /* temporary array of the Sample Vectors */
1167     float* flConfidence;    /* Confidence for each Sample            */
1168     float* flCumulative;    /* Cumulative confidence                 */
1169     float* Temp;            /* Temporary vector                      */
1170     float* RandomSample;    /* RandomVector to update sample set     */
1171     struct CvRandState* RandS; /* Array of structures to generate random vectors */
1172 } CvConDensation;
1173
1174 /* Creates ConDensation filter state */
1175 CVAPI(CvConDensation*)  cvCreateConDensation( int dynam_params,
1176                                              int measure_params,
1177                                              int sample_count );
1178
1179 /* Releases ConDensation filter state */
1180 CVAPI(void)  cvReleaseConDensation( CvConDensation** condens );
1181
1182 /* Updates ConDensation filter by time (predict future state of the system) */
1183 CVAPI(void)  cvConDensUpdateByTime( CvConDensation* condens);
1184
1185 /* Initializes ConDensation filter samples  */
1186 CVAPI(void)  cvConDensInitSampleSet( CvConDensation* condens, CvMat* lower_bound, CvMat* upper_bound );
1187
1188 CV_INLINE int iplWidth( const IplImage* img )
1189 {
1190     return !img ? 0 : !img->roi ? img->width : img->roi->width;
1191 }
1192
1193 CV_INLINE int iplHeight( const IplImage* img )
1194 {
1195     return !img ? 0 : !img->roi ? img->height : img->roi->height;
1196 }
1197
1198 #ifdef __cplusplus
1199 }
1200 #endif
1201
1202 #ifdef __cplusplus
1203
1204 /****************************************************************************************\
1205 *                                   Calibration engine                                   *
1206 \****************************************************************************************/
1207
1208 typedef enum CvCalibEtalonType
1209 {
1210     CV_CALIB_ETALON_USER = -1,
1211     CV_CALIB_ETALON_CHESSBOARD = 0,
1212     CV_CALIB_ETALON_CHECKERBOARD = CV_CALIB_ETALON_CHESSBOARD
1213 }
1214 CvCalibEtalonType;
1215
1216 class CV_EXPORTS CvCalibFilter
1217 {
1218 public:
1219     /* Constructor & destructor */
1220     CvCalibFilter();
1221     virtual ~CvCalibFilter();
1222
1223     /* Sets etalon type - one for all cameras.
1224        etalonParams is used in case of pre-defined etalons (such as chessboard).
1225        Number of elements in etalonParams is determined by etalonType.
1226        E.g., if etalon type is CV_ETALON_TYPE_CHESSBOARD then:
1227          etalonParams[0] is number of squares per one side of etalon
1228          etalonParams[1] is number of squares per another side of etalon
1229          etalonParams[2] is linear size of squares in the board in arbitrary units.
1230        pointCount & points are used in case of
1231        CV_CALIB_ETALON_USER (user-defined) etalon. */
1232     virtual bool
1233         SetEtalon( CvCalibEtalonType etalonType, double* etalonParams,
1234                    int pointCount = 0, CvPoint2D32f* points = 0 );
1235
1236     /* Retrieves etalon parameters/or and points */
1237     virtual CvCalibEtalonType
1238         GetEtalon( int* paramCount = 0, const double** etalonParams = 0,
1239                    int* pointCount = 0, const CvPoint2D32f** etalonPoints = 0 ) const;
1240
1241     /* Sets number of cameras calibrated simultaneously. It is equal to 1 initially */
1242     virtual void SetCameraCount( int cameraCount );
1243
1244     /* Retrieves number of cameras */
1245     int GetCameraCount() const { return cameraCount; }
1246
1247     /* Starts cameras calibration */
1248     virtual bool SetFrames( int totalFrames );
1249
1250     /* Stops cameras calibration */
1251     virtual void Stop( bool calibrate = false );
1252
1253     /* Retrieves number of cameras */
1254     bool IsCalibrated() const { return isCalibrated; }
1255
1256     /* Feeds another serie of snapshots (one per each camera) to filter.
1257        Etalon points on these images are found automatically.
1258        If the function can't locate points, it returns false */
1259     virtual bool FindEtalon( IplImage** imgs );
1260
1261     /* The same but takes matrices */
1262     virtual bool FindEtalon( CvMat** imgs );
1263
1264     /* Lower-level function for feeding filter with already found etalon points.
1265        Array of point arrays for each camera is passed. */
1266     virtual bool Push( const CvPoint2D32f** points = 0 );
1267
1268     /* Returns total number of accepted frames and, optionally,
1269        total number of frames to collect */
1270     virtual int GetFrameCount( int* framesTotal = 0 ) const;
1271
1272     /* Retrieves camera parameters for specified camera.
1273        If camera is not calibrated the function returns 0 */
1274     virtual const CvCamera* GetCameraParams( int idx = 0 ) const;
1275
1276     virtual const CvStereoCamera* GetStereoParams() const;
1277
1278     /* Sets camera parameters for all cameras */
1279     virtual bool SetCameraParams( CvCamera* params );
1280
1281     /* Saves all camera parameters to file */
1282     virtual bool SaveCameraParams( const char* filename );
1283
1284     /* Loads all camera parameters from file */
1285     virtual bool LoadCameraParams( const char* filename );
1286
1287     /* Undistorts images using camera parameters. Some of src pointers can be NULL. */
1288     virtual bool Undistort( IplImage** src, IplImage** dst );
1289
1290     /* Undistorts images using camera parameters. Some of src pointers can be NULL. */
1291     virtual bool Undistort( CvMat** src, CvMat** dst );
1292
1293     /* Returns array of etalon points detected/partally detected
1294        on the latest frame for idx-th camera */
1295     virtual bool GetLatestPoints( int idx, CvPoint2D32f** pts,
1296                                                   int* count, bool* found );
1297
1298     /* Draw the latest detected/partially detected etalon */
1299     virtual void DrawPoints( IplImage** dst );
1300
1301     /* Draw the latest detected/partially detected etalon */
1302     virtual void DrawPoints( CvMat** dst );
1303
1304     virtual bool Rectify( IplImage** srcarr, IplImage** dstarr );
1305     virtual bool Rectify( CvMat** srcarr, CvMat** dstarr );
1306
1307 protected:
1308
1309     enum { MAX_CAMERAS = 3 };
1310
1311     /* etalon data */
1312     CvCalibEtalonType  etalonType;
1313     int     etalonParamCount;
1314     double* etalonParams;
1315     int     etalonPointCount;
1316     CvPoint2D32f* etalonPoints;
1317     CvSize  imgSize;
1318     CvMat*  grayImg;
1319     CvMat*  tempImg;
1320     CvMemStorage* storage;
1321
1322     /* camera data */
1323     int     cameraCount;
1324     CvCamera cameraParams[MAX_CAMERAS];
1325     CvStereoCamera stereo;
1326     CvPoint2D32f* points[MAX_CAMERAS];
1327     CvMat*  undistMap[MAX_CAMERAS][2];
1328     CvMat*  undistImg;
1329     int     latestCounts[MAX_CAMERAS];
1330     CvPoint2D32f* latestPoints[MAX_CAMERAS];
1331     CvMat*  rectMap[MAX_CAMERAS][2];
1332
1333     /* Added by Valery */
1334     //CvStereoCamera stereoParams;
1335
1336     int     maxPoints;
1337     int     framesTotal;
1338     int     framesAccepted;
1339     bool    isCalibrated;
1340 };
1341
1342 #include <iosfwd>
1343 #include <limits>
1344
1345 class CV_EXPORTS CvImage
1346 {
1347 public:
1348     CvImage() : image(0), refcount(0) {}
1349     CvImage( CvSize _size, int _depth, int _channels )
1350     {
1351         image = cvCreateImage( _size, _depth, _channels );
1352         refcount = image ? new int(1) : 0;
1353     }
1354
1355     CvImage( IplImage* img ) : image(img)
1356     {
1357         refcount = image ? new int(1) : 0;
1358     }
1359
1360     CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
1361     {
1362         if( refcount ) ++(*refcount);
1363     }
1364
1365     CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
1366     { load( filename, imgname, color ); }
1367
1368     CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
1369     { read( fs, mapname, imgname ); }
1370
1371     CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
1372     { read( fs, seqname, idx ); }
1373
1374     ~CvImage()
1375     {
1376         if( refcount && !(--*refcount) )
1377         {
1378             cvReleaseImage( &image );
1379             delete refcount;
1380         }
1381     }
1382
1383     CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
1384
1385     void create( CvSize _size, int _depth, int _channels )
1386     {
1387         if( !image || !refcount ||
1388            image->width != _size.width || image->height != _size.height ||
1389            image->depth != _depth || image->nChannels != _channels )
1390             attach( cvCreateImage( _size, _depth, _channels ));
1391     }
1392
1393     void release() { detach(); }
1394     void clear() { detach(); }
1395
1396     void attach( IplImage* img, bool use_refcount=true )
1397     {
1398         if( refcount && --*refcount == 0 )
1399         {
1400             cvReleaseImage( &image );
1401             delete refcount;
1402         }
1403         image = img;
1404         refcount = use_refcount && image ? new int(1) : 0;
1405     }
1406
1407     void detach()
1408     {
1409         if( refcount && --*refcount == 0 )
1410         {
1411             cvReleaseImage( &image );
1412             delete refcount;
1413         }
1414         image = 0;
1415         refcount = 0;
1416     }
1417
1418     bool load( const char* filename, const char* imgname=0, int color=-1 );
1419     bool read( CvFileStorage* fs, const char* mapname, const char* imgname );
1420     bool read( CvFileStorage* fs, const char* seqname, int idx );
1421     void save( const char* filename, const char* imgname, const int* params=0 );
1422     void write( CvFileStorage* fs, const char* imgname );
1423
1424     void show( const char* window_name );
1425     bool is_valid() { return image != 0; }
1426
1427     int width() const { return image ? image->width : 0; }
1428     int height() const { return image ? image->height : 0; }
1429
1430     CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
1431
1432     CvSize roi_size() const
1433     {
1434         return !image ? cvSize(0,0) :
1435         !image->roi ? cvSize(image->width,image->height) :
1436         cvSize(image->roi->width, image->roi->height);
1437     }
1438
1439     CvRect roi() const
1440     {
1441         return !image ? cvRect(0,0,0,0) :
1442         !image->roi ? cvRect(0,0,image->width,image->height) :
1443         cvRect(image->roi->xOffset,image->roi->yOffset,
1444                image->roi->width,image->roi->height);
1445     }
1446
1447     int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
1448
1449     void set_roi(CvRect _roi) { cvSetImageROI(image,_roi); }
1450     void reset_roi() { cvResetImageROI(image); }
1451     void set_coi(int _coi) { cvSetImageCOI(image,_coi); }
1452     int depth() const { return image ? image->depth : 0; }
1453     int channels() const { return image ? image->nChannels : 0; }
1454     int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
1455
1456     uchar* data() { return image ? (uchar*)image->imageData : 0; }
1457     const uchar* data() const { return image ? (const uchar*)image->imageData : 0; }
1458     int step() const { return image ? image->widthStep : 0; }
1459     int origin() const { return image ? image->origin : 0; }
1460
1461     uchar* roi_row(int y)
1462     {
1463         assert(0<=y);
1464         assert(!image ?
1465                1 : image->roi ?
1466                y<image->roi->height : y<image->height);
1467
1468         return !image ? 0 :
1469         !image->roi ?
1470         (uchar*)(image->imageData + y*image->widthStep) :
1471         (uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
1472                  image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
1473     }
1474
1475     const uchar* roi_row(int y) const
1476     {
1477         assert(0<=y);
1478         assert(!image ?
1479                1 : image->roi ?
1480                y<image->roi->height : y<image->height);
1481
1482         return !image ? 0 :
1483         !image->roi ?
1484         (const uchar*)(image->imageData + y*image->widthStep) :
1485         (const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
1486                        image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
1487     }
1488
1489     operator const IplImage* () const { return image; }
1490     operator IplImage* () { return image; }
1491
1492     CvImage& operator = (const CvImage& img)
1493     {
1494         if( img.refcount )
1495             ++*img.refcount;
1496         if( refcount && !(--*refcount) )
1497             cvReleaseImage( &image );
1498         image=img.image;
1499         refcount=img.refcount;
1500         return *this;
1501     }
1502
1503 protected:
1504     IplImage* image;
1505     int* refcount;
1506 };
1507
1508
1509 class CV_EXPORTS CvMatrix
1510 {
1511 public:
1512     CvMatrix() : matrix(0) {}
1513     CvMatrix( int _rows, int _cols, int _type )
1514     { matrix = cvCreateMat( _rows, _cols, _type ); }
1515
1516     CvMatrix( int _rows, int _cols, int _type, CvMat* hdr,
1517              void* _data=0, int _step=CV_AUTOSTEP )
1518     { matrix = cvInitMatHeader( hdr, _rows, _cols, _type, _data, _step ); }
1519
1520     CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
1521
1522     CvMatrix( int _rows, int _cols, int _type, void* _data, int _step=CV_AUTOSTEP )
1523     { matrix = cvCreateMatHeader( _rows, _cols, _type );
1524         cvSetData( matrix, _data, _step ); }
1525
1526     CvMatrix( CvMat* m )
1527     { matrix = m; }
1528
1529     CvMatrix( const CvMatrix& m )
1530     {
1531         matrix = m.matrix;
1532         addref();
1533     }
1534
1535     CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
1536     {  load( filename, matname, color ); }
1537
1538     CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
1539     {  read( fs, mapname, matname ); }
1540
1541     CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
1542     {  read( fs, seqname, idx ); }
1543
1544     ~CvMatrix()
1545     {
1546         release();
1547     }
1548
1549     CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
1550
1551     void set( CvMat* m, bool add_ref )
1552     {
1553         release();
1554         matrix = m;
1555         if( add_ref )
1556             addref();
1557     }
1558
1559     void create( int _rows, int _cols, int _type )
1560     {
1561         if( !matrix || !matrix->refcount ||
1562            matrix->rows != _rows || matrix->cols != _cols ||
1563            CV_MAT_TYPE(matrix->type) != _type )
1564             set( cvCreateMat( _rows, _cols, _type ), false );
1565     }
1566
1567     void addref() const
1568     {
1569         if( matrix )
1570         {
1571             if( matrix->hdr_refcount )
1572                 ++matrix->hdr_refcount;
1573             else if( matrix->refcount )
1574                 ++*matrix->refcount;
1575         }
1576     }
1577
1578     void release()
1579     {
1580         if( matrix )
1581         {
1582             if( matrix->hdr_refcount )
1583             {
1584                 if( --matrix->hdr_refcount == 0 )
1585                     cvReleaseMat( &matrix );
1586             }
1587             else if( matrix->refcount )
1588             {
1589                 if( --*matrix->refcount == 0 )
1590                     cvFree( &matrix->refcount );
1591             }
1592             matrix = 0;
1593         }
1594     }
1595
1596     void clear()
1597     {
1598         release();
1599     }
1600
1601     bool load( const char* filename, const char* matname=0, int color=-1 );
1602     bool read( CvFileStorage* fs, const char* mapname, const char* matname );
1603     bool read( CvFileStorage* fs, const char* seqname, int idx );
1604     void save( const char* filename, const char* matname, const int* params=0 );
1605     void write( CvFileStorage* fs, const char* matname );
1606
1607     void show( const char* window_name );
1608
1609     bool is_valid() { return matrix != 0; }
1610
1611     int rows() const { return matrix ? matrix->rows : 0; }
1612     int cols() const { return matrix ? matrix->cols : 0; }
1613
1614     CvSize size() const
1615     {
1616         return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
1617     }
1618
1619     int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; }
1620     int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; }
1621     int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; }
1622     int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; }
1623
1624     uchar* data() { return matrix ? matrix->data.ptr : 0; }
1625     const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
1626     int step() const { return matrix ? matrix->step : 0; }
1627
1628     void set_data( void* _data, int _step=CV_AUTOSTEP )
1629     { cvSetData( matrix, _data, _step ); }
1630
1631     uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
1632     const uchar* row(int i) const
1633     { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
1634
1635     operator const CvMat* () const { return matrix; }
1636     operator CvMat* () { return matrix; }
1637
1638     CvMatrix& operator = (const CvMatrix& _m)
1639     {
1640         _m.addref();
1641         release();
1642         matrix = _m.matrix;
1643         return *this;
1644     }
1645
1646 protected:
1647     CvMat* matrix;
1648 };
1649
1650 /****************************************************************************************\
1651  *                                       CamShiftTracker                                  *
1652  \****************************************************************************************/
1653
1654 class CV_EXPORTS CvCamShiftTracker
1655 {
1656 public:
1657
1658     CvCamShiftTracker();
1659     virtual ~CvCamShiftTracker();
1660
1661     /**** Characteristics of the object that are calculated by track_object method *****/
1662     float   get_orientation() const // orientation of the object in degrees
1663     { return m_box.angle; }
1664     float   get_length() const // the larger linear size of the object
1665     { return m_box.size.height; }
1666     float   get_width() const // the smaller linear size of the object
1667     { return m_box.size.width; }
1668     CvPoint2D32f get_center() const // center of the object
1669     { return m_box.center; }
1670     CvRect get_window() const // bounding rectangle for the object
1671     { return m_comp.rect; }
1672
1673     /*********************** Tracking parameters ************************/
1674     int     get_threshold() const // thresholding value that applied to back project
1675     { return m_threshold; }
1676
1677     int     get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets
1678     { return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }
1679
1680     int     get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel
1681     { return m_min_ch_val[channel]; }
1682
1683     int     get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel
1684     { return m_max_ch_val[channel]; }
1685
1686     // set initial object rectangle (must be called before initial calculation of the histogram)
1687     bool    set_window( CvRect window)
1688     { m_comp.rect = window; return true; }
1689
1690     bool    set_threshold( int threshold ) // threshold applied to the histogram bins
1691     { m_threshold = threshold; return true; }
1692
1693     bool    set_hist_bin_range( int dim, int min_val, int max_val );
1694
1695     bool    set_hist_dims( int c_dims, int* dims );// set the histogram parameters
1696
1697     bool    set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel
1698     { m_min_ch_val[channel] = val; return true; }
1699     bool    set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel
1700     { m_max_ch_val[channel] = val; return true; }
1701
1702     /************************ The processing methods *********************************/
1703     // update object position
1704     virtual bool  track_object( const IplImage* cur_frame );
1705
1706     // update object histogram
1707     virtual bool  update_histogram( const IplImage* cur_frame );
1708
1709     // reset histogram
1710     virtual void  reset_histogram();
1711
1712     /************************ Retrieving internal data *******************************/
1713     // get back project image
1714     virtual IplImage* get_back_project()
1715     { return m_back_project; }
1716
1717     float query( int* bin ) const
1718     { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }
1719
1720 protected:
1721
1722     // internal method for color conversion: fills m_color_planes group
1723     virtual void color_transform( const IplImage* img );
1724
1725     CvHistogram* m_hist;
1726
1727     CvBox2D    m_box;
1728     CvConnectedComp m_comp;
1729
1730     float      m_hist_ranges_data[CV_MAX_DIM][2];
1731     float*     m_hist_ranges[CV_MAX_DIM];
1732
1733     int        m_min_ch_val[CV_MAX_DIM];
1734     int        m_max_ch_val[CV_MAX_DIM];
1735     int        m_threshold;
1736
1737     IplImage*  m_color_planes[CV_MAX_DIM];
1738     IplImage*  m_back_project;
1739     IplImage*  m_temp;
1740     IplImage*  m_mask;
1741 };
1742
1743 /****************************************************************************************\
1744 *                              Expectation - Maximization                                *
1745 \****************************************************************************************/
1746 struct CV_EXPORTS_W_MAP CvEMParams
1747 {
1748     CvEMParams();
1749     CvEMParams( int nclusters, int cov_mat_type=cv::EM::COV_MAT_DIAGONAL,
1750                 int start_step=cv::EM::START_AUTO_STEP,
1751                 CvTermCriteria term_crit=cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, FLT_EPSILON),
1752                 const CvMat* probs=0, const CvMat* weights=0, const CvMat* means=0, const CvMat** covs=0 );
1753
1754     CV_PROP_RW int nclusters;
1755     CV_PROP_RW int cov_mat_type;
1756     CV_PROP_RW int start_step;
1757     const CvMat* probs;
1758     const CvMat* weights;
1759     const CvMat* means;
1760     const CvMat** covs;
1761     CV_PROP_RW CvTermCriteria term_crit;
1762 };
1763
1764
1765 class CV_EXPORTS_W CvEM : public CvStatModel
1766 {
1767 public:
1768     // Type of covariation matrices
1769     enum { COV_MAT_SPHERICAL=cv::EM::COV_MAT_SPHERICAL,
1770            COV_MAT_DIAGONAL =cv::EM::COV_MAT_DIAGONAL,
1771            COV_MAT_GENERIC  =cv::EM::COV_MAT_GENERIC };
1772
1773     // The initial step
1774     enum { START_E_STEP=cv::EM::START_E_STEP,
1775            START_M_STEP=cv::EM::START_M_STEP,
1776            START_AUTO_STEP=cv::EM::START_AUTO_STEP };
1777
1778     CV_WRAP CvEM();
1779     CvEM( const CvMat* samples, const CvMat* sampleIdx=0,
1780           CvEMParams params=CvEMParams(), CvMat* labels=0 );
1781
1782     virtual ~CvEM();
1783
1784     virtual bool train( const CvMat* samples, const CvMat* sampleIdx=0,
1785                         CvEMParams params=CvEMParams(), CvMat* labels=0 );
1786
1787     virtual float predict( const CvMat* sample, CV_OUT CvMat* probs ) const;
1788
1789     CV_WRAP CvEM( const cv::Mat& samples, const cv::Mat& sampleIdx=cv::Mat(),
1790                   CvEMParams params=CvEMParams() );
1791
1792     CV_WRAP virtual bool train( const cv::Mat& samples,
1793                                 const cv::Mat& sampleIdx=cv::Mat(),
1794                                 CvEMParams params=CvEMParams(),
1795                                 CV_OUT cv::Mat* labels=0 );
1796
1797     CV_WRAP virtual float predict( const cv::Mat& sample, CV_OUT cv::Mat* probs=0 ) const;
1798     CV_WRAP virtual double calcLikelihood( const cv::Mat &sample ) const;
1799
1800     CV_WRAP int getNClusters() const;
1801     CV_WRAP cv::Mat getMeans() const;
1802     CV_WRAP void getCovs(CV_OUT std::vector<cv::Mat>& covs) const;
1803     CV_WRAP cv::Mat getWeights() const;
1804     CV_WRAP cv::Mat getProbs() const;
1805
1806     CV_WRAP inline double getLikelihood() const { return emObj.isTrained() ? logLikelihood : DBL_MAX; }
1807
1808     CV_WRAP virtual void clear();
1809
1810     int get_nclusters() const;
1811     const CvMat* get_means() const;
1812     const CvMat** get_covs() const;
1813     const CvMat* get_weights() const;
1814     const CvMat* get_probs() const;
1815
1816     inline double get_log_likelihood() const { return getLikelihood(); }
1817
1818     virtual void read( CvFileStorage* fs, CvFileNode* node );
1819     virtual void write( CvFileStorage* fs, const char* name ) const;
1820
1821 protected:
1822     void set_mat_hdrs();
1823
1824     cv::EM emObj;
1825     cv::Mat probs;
1826     double logLikelihood;
1827
1828     CvMat meansHdr;
1829     std::vector<CvMat> covsHdrs;
1830     std::vector<CvMat*> covsPtrs;
1831     CvMat weightsHdr;
1832     CvMat probsHdr;
1833 };
1834
1835 namespace cv
1836 {
1837
1838 typedef CvEMParams EMParams;
1839 typedef CvEM ExpectationMaximization;
1840
1841 /*!
1842  The Patch Generator class
1843  */
1844 class CV_EXPORTS PatchGenerator
1845 {
1846 public:
1847     PatchGenerator();
1848     PatchGenerator(double _backgroundMin, double _backgroundMax,
1849                    double _noiseRange, bool _randomBlur=true,
1850                    double _lambdaMin=0.6, double _lambdaMax=1.5,
1851                    double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
1852                    double _phiMin=-CV_PI, double _phiMax=CV_PI );
1853     void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
1854     void operator()(const Mat& image, const Mat& transform, Mat& patch,
1855                     Size patchSize, RNG& rng) const;
1856     void warpWholeImage(const Mat& image, Mat& matT, Mat& buf,
1857                         CV_OUT Mat& warped, int border, RNG& rng) const;
1858     void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
1859                                  CV_OUT Mat& transform, RNG& rng,
1860                                  bool inverse=false) const;
1861     void setAffineParam(double lambda, double theta, double phi);
1862
1863     double backgroundMin, backgroundMax;
1864     double noiseRange;
1865     bool randomBlur;
1866     double lambdaMin, lambdaMax;
1867     double thetaMin, thetaMax;
1868     double phiMin, phiMax;
1869 };
1870
1871
1872 class CV_EXPORTS LDetector
1873 {
1874 public:
1875     LDetector();
1876     LDetector(int _radius, int _threshold, int _nOctaves,
1877               int _nViews, double _baseFeatureSize, double _clusteringDistance);
1878     void operator()(const Mat& image,
1879                     CV_OUT std::vector<KeyPoint>& keypoints,
1880                     int maxCount=0, bool scaleCoords=true) const;
1881     void operator()(const std::vector<Mat>& pyr,
1882                     CV_OUT std::vector<KeyPoint>& keypoints,
1883                     int maxCount=0, bool scaleCoords=true) const;
1884     void getMostStable2D(const Mat& image, CV_OUT std::vector<KeyPoint>& keypoints,
1885                          int maxCount, const PatchGenerator& patchGenerator) const;
1886     void setVerbose(bool verbose);
1887
1888     void read(const FileNode& node);
1889     void write(FileStorage& fs, const String& name=String()) const;
1890
1891     int radius;
1892     int threshold;
1893     int nOctaves;
1894     int nViews;
1895     bool verbose;
1896
1897     double baseFeatureSize;
1898     double clusteringDistance;
1899 };
1900
1901 typedef LDetector YAPE;
1902
1903 class CV_EXPORTS FernClassifier
1904 {
1905 public:
1906     FernClassifier();
1907     FernClassifier(const FileNode& node);
1908     FernClassifier(const std::vector<std::vector<Point2f> >& points,
1909                    const std::vector<Mat>& refimgs,
1910                    const std::vector<std::vector<int> >& labels=std::vector<std::vector<int> >(),
1911                    int _nclasses=0, int _patchSize=PATCH_SIZE,
1912                    int _signatureSize=DEFAULT_SIGNATURE_SIZE,
1913                    int _nstructs=DEFAULT_STRUCTS,
1914                    int _structSize=DEFAULT_STRUCT_SIZE,
1915                    int _nviews=DEFAULT_VIEWS,
1916                    int _compressionMethod=COMPRESSION_NONE,
1917                    const PatchGenerator& patchGenerator=PatchGenerator());
1918     virtual ~FernClassifier();
1919     virtual void read(const FileNode& n);
1920     virtual void write(FileStorage& fs, const String& name=String()) const;
1921     virtual void trainFromSingleView(const Mat& image,
1922                                      const std::vector<KeyPoint>& keypoints,
1923                                      int _patchSize=PATCH_SIZE,
1924                                      int _signatureSize=DEFAULT_SIGNATURE_SIZE,
1925                                      int _nstructs=DEFAULT_STRUCTS,
1926                                      int _structSize=DEFAULT_STRUCT_SIZE,
1927                                      int _nviews=DEFAULT_VIEWS,
1928                                      int _compressionMethod=COMPRESSION_NONE,
1929                                      const PatchGenerator& patchGenerator=PatchGenerator());
1930     virtual void train(const std::vector<std::vector<Point2f> >& points,
1931                        const std::vector<Mat>& refimgs,
1932                        const std::vector<std::vector<int> >& labels=std::vector<std::vector<int> >(),
1933                        int _nclasses=0, int _patchSize=PATCH_SIZE,
1934                        int _signatureSize=DEFAULT_SIGNATURE_SIZE,
1935                        int _nstructs=DEFAULT_STRUCTS,
1936                        int _structSize=DEFAULT_STRUCT_SIZE,
1937                        int _nviews=DEFAULT_VIEWS,
1938                        int _compressionMethod=COMPRESSION_NONE,
1939                        const PatchGenerator& patchGenerator=PatchGenerator());
1940     virtual int operator()(const Mat& img, Point2f kpt, std::vector<float>& signature) const;
1941     virtual int operator()(const Mat& patch, std::vector<float>& signature) const;
1942     virtual void clear();
1943     virtual bool empty() const;
1944     void setVerbose(bool verbose);
1945
1946     int getClassCount() const;
1947     int getStructCount() const;
1948     int getStructSize() const;
1949     int getSignatureSize() const;
1950     int getCompressionMethod() const;
1951     Size getPatchSize() const;
1952
1953     struct Feature
1954     {
1955         uchar x1, y1, x2, y2;
1956         Feature() : x1(0), y1(0), x2(0), y2(0) {}
1957         Feature(int _x1, int _y1, int _x2, int _y2)
1958         : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)
1959         {}
1960         template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
1961         { return patch(y1,x1) > patch(y2, x2); }
1962     };
1963
1964     enum
1965     {
1966         PATCH_SIZE = 31,
1967         DEFAULT_STRUCTS = 50,
1968         DEFAULT_STRUCT_SIZE = 9,
1969         DEFAULT_VIEWS = 5000,
1970         DEFAULT_SIGNATURE_SIZE = 176,
1971         COMPRESSION_NONE = 0,
1972         COMPRESSION_RANDOM_PROJ = 1,
1973         COMPRESSION_PCA = 2,
1974         DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE
1975     };
1976
1977 protected:
1978     virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,
1979                          int _nstructs, int _structSize,
1980                          int _nviews, int _compressionMethod);
1981     virtual void finalize(RNG& rng);
1982     virtual int getLeaf(int fidx, const Mat& patch) const;
1983
1984     bool verbose;
1985     int nstructs;
1986     int structSize;
1987     int nclasses;
1988     int signatureSize;
1989     int compressionMethod;
1990     int leavesPerStruct;
1991     Size patchSize;
1992     std::vector<Feature> features;
1993     std::vector<int> classCounters;
1994     std::vector<float> posteriors;
1995 };
1996
1997
1998 /****************************************************************************************\
1999  *                                 Calonder Classifier                                    *
2000  \****************************************************************************************/
2001
2002 struct RTreeNode;
2003
2004 struct CV_EXPORTS BaseKeypoint
2005 {
2006     int x;
2007     int y;
2008     IplImage* image;
2009
2010     BaseKeypoint()
2011     : x(0), y(0), image(NULL)
2012     {}
2013
2014     BaseKeypoint(int _x, int _y, IplImage* _image)
2015     : x(_x), y(_y), image(_image)
2016     {}
2017 };
2018
2019 class CV_EXPORTS RandomizedTree
2020 {
2021 public:
2022     friend class RTreeClassifier;
2023
2024     static const uchar PATCH_SIZE = 32;
2025     static const int DEFAULT_DEPTH = 9;
2026     static const int DEFAULT_VIEWS = 5000;
2027     static const size_t DEFAULT_REDUCED_NUM_DIM = 176;
2028     static float GET_LOWER_QUANT_PERC() { return .03f; }
2029     static float GET_UPPER_QUANT_PERC() { return .92f; }
2030
2031     RandomizedTree();
2032     ~RandomizedTree();
2033
2034     void train(std::vector<BaseKeypoint> const& base_set, RNG &rng,
2035                int depth, int views, size_t reduced_num_dim, int num_quant_bits);
2036     void train(std::vector<BaseKeypoint> const& base_set, RNG &rng,
2037                PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim,
2038                int num_quant_bits);
2039
2040     // following two funcs are EXPERIMENTAL (do not use unless you know exactly what you do)
2041     static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0);
2042     static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst);
2043
2044     // patch_data must be a 32x32 array (no row padding)
2045     float* getPosterior(uchar* patch_data);
2046     const float* getPosterior(uchar* patch_data) const;
2047     uchar* getPosterior2(uchar* patch_data);
2048     const uchar* getPosterior2(uchar* patch_data) const;
2049
2050     void read(const char* file_name, int num_quant_bits);
2051     void read(std::istream &is, int num_quant_bits);
2052     void write(const char* file_name) const;
2053     void write(std::ostream &os) const;
2054
2055     int classes() { return classes_; }
2056     int depth() { return depth_; }
2057
2058     //void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; }
2059     void discardFloatPosteriors() { freePosteriors(1); }
2060
2061     inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
2062
2063     // debug
2064     void savePosteriors(String url, bool append=false);
2065     void savePosteriors2(String url, bool append=false);
2066
2067 private:
2068     int classes_;
2069     int depth_;
2070     int num_leaves_;
2071     std::vector<RTreeNode> nodes_;
2072     float **posteriors_;        // 16-bytes aligned posteriors
2073     uchar **posteriors2_;     // 16-bytes aligned posteriors
2074     std::vector<int> leaf_counts_;
2075
2076     void createNodes(int num_nodes, RNG &rng);
2077     void allocPosteriorsAligned(int num_leaves, int num_classes);
2078     void freePosteriors(int which);    // which: 1=posteriors_, 2=posteriors2_, 3=both
2079     void init(int classes, int depth, RNG &rng);
2080     void addExample(int class_id, uchar* patch_data);
2081     void finalize(size_t reduced_num_dim, int num_quant_bits);
2082     int getIndex(uchar* patch_data) const;
2083     inline float* getPosteriorByIndex(int index);
2084     inline const float* getPosteriorByIndex(int index) const;
2085     inline uchar* getPosteriorByIndex2(int index);
2086     inline const uchar* getPosteriorByIndex2(int index) const;
2087     //void makeRandomMeasMatrix(float *cs_phi, PHI_DISTR_TYPE dt, size_t reduced_num_dim);
2088     void convertPosteriorsToChar();
2089     void makePosteriors2(int num_quant_bits);
2090     void compressLeaves(size_t reduced_num_dim);
2091     void estimateQuantPercForPosteriors(float perc[2]);
2092 };
2093
2094
2095 inline uchar* getData(IplImage* image)
2096 {
2097     return reinterpret_cast<uchar*>(image->imageData);
2098 }
2099
2100 inline float* RandomizedTree::getPosteriorByIndex(int index)
2101 {
2102     return const_cast<float*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex(index));
2103 }
2104
2105 inline const float* RandomizedTree::getPosteriorByIndex(int index) const
2106 {
2107     return posteriors_[index];
2108 }
2109
2110 inline uchar* RandomizedTree::getPosteriorByIndex2(int index)
2111 {
2112     return const_cast<uchar*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex2(index));
2113 }
2114
2115 inline const uchar* RandomizedTree::getPosteriorByIndex2(int index) const
2116 {
2117     return posteriors2_[index];
2118 }
2119
2120 struct CV_EXPORTS RTreeNode
2121 {
2122     short offset1, offset2;
2123
2124     RTreeNode() {}
2125     RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
2126     : offset1(y1*RandomizedTree::PATCH_SIZE + x1),
2127     offset2(y2*RandomizedTree::PATCH_SIZE + x2)
2128     {}
2129
2130     //! Left child on 0, right child on 1
2131     inline bool operator() (uchar* patch_data) const
2132     {
2133         return patch_data[offset1] > patch_data[offset2];
2134     }
2135 };
2136
2137 class CV_EXPORTS RTreeClassifier
2138 {
2139 public:
2140     static const int DEFAULT_TREES = 48;
2141     static const size_t DEFAULT_NUM_QUANT_BITS = 4;
2142
2143     RTreeClassifier();
2144     void train(std::vector<BaseKeypoint> const& base_set,
2145                RNG &rng,
2146                int num_trees = RTreeClassifier::DEFAULT_TREES,
2147                int depth = RandomizedTree::DEFAULT_DEPTH,
2148                int views = RandomizedTree::DEFAULT_VIEWS,
2149                size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM,
2150                int num_quant_bits = DEFAULT_NUM_QUANT_BITS);
2151     void train(std::vector<BaseKeypoint> const& base_set,
2152                RNG &rng,
2153                PatchGenerator &make_patch,
2154                int num_trees = RTreeClassifier::DEFAULT_TREES,
2155                int depth = RandomizedTree::DEFAULT_DEPTH,
2156                int views = RandomizedTree::DEFAULT_VIEWS,
2157                size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM,
2158                int num_quant_bits = DEFAULT_NUM_QUANT_BITS);
2159
2160     // sig must point to a memory block of at least classes()*sizeof(float|uchar) bytes
2161     void getSignature(IplImage *patch, uchar *sig) const;
2162     void getSignature(IplImage *patch, float *sig) const;
2163     void getSparseSignature(IplImage *patch, float *sig, float thresh) const;
2164     // TODO: deprecated in favor of getSignature overload, remove
2165     void getFloatSignature(IplImage *patch, float *sig) const { getSignature(patch, sig); }
2166
2167     static int countNonZeroElements(float *vec, int n, double tol=1e-10);
2168     static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176);
2169     static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176);
2170
2171     inline int classes() const { return classes_; }
2172     inline int original_num_classes() const { return original_num_classes_; }
2173
2174     void setQuantization(int num_quant_bits);
2175     void discardFloatPosteriors();
2176
2177     void read(const char* file_name);
2178     void read(std::istream &is);
2179     void write(const char* file_name) const;
2180     void write(std::ostream &os) const;
2181
2182     // experimental and debug
2183     void saveAllFloatPosteriors(String file_url);
2184     void saveAllBytePosteriors(String file_url);
2185     void setFloatPosteriorsFromTextfile_176(String url);
2186     float countZeroElements();
2187
2188     std::vector<RandomizedTree> trees_;
2189
2190 private:
2191     int classes_;
2192     int num_quant_bits_;
2193     mutable uchar **posteriors_;
2194     mutable unsigned short *ptemp_;
2195     int original_num_classes_;
2196     bool keep_floats_;
2197 };
2198
2199 /****************************************************************************************\
2200 *                                     One-Way Descriptor                                 *
2201 \****************************************************************************************/
2202
2203 // CvAffinePose: defines a parameterized affine transformation of an image patch.
2204 // An image patch is rotated on angle phi (in degrees), then scaled lambda1 times
2205 // along horizontal and lambda2 times along vertical direction, and then rotated again
2206 // on angle (theta - phi).
2207 class CV_EXPORTS CvAffinePose
2208 {
2209 public:
2210     float phi;
2211     float theta;
2212     float lambda1;
2213     float lambda2;
2214 };
2215
2216 class CV_EXPORTS OneWayDescriptor
2217 {
2218 public:
2219     OneWayDescriptor();
2220     ~OneWayDescriptor();
2221
2222     // allocates memory for given descriptor parameters
2223     void Allocate(int pose_count, CvSize size, int nChannels);
2224
2225     // GenerateSamples: generates affine transformed patches with averaging them over small transformation variations.
2226     // If external poses and transforms were specified, uses them instead of generating random ones
2227     // - pose_count: the number of poses to be generated
2228     // - frontal: the input patch (can be a roi in a larger image)
2229     // - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1
2230     void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);
2231
2232     // GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations.
2233     // Uses precalculated transformed pca components.
2234     // - frontal: the input patch (can be a roi in a larger image)
2235     // - pca_hr_avg: pca average vector
2236     // - pca_hr_eigenvectors: pca eigenvectors
2237     // - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations
2238     //   pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors
2239     void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
2240                              CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
2241
2242     // sets the poses and corresponding transforms
2243     void SetTransforms(CvAffinePose* poses, CvMat** transforms);
2244
2245     // Initialize: builds a descriptor.
2246     // - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones
2247     // - frontal: input patch. Can be a roi in a larger image
2248     // - feature_name: the feature name to be associated with the descriptor
2249     // - norm: if 1, the affine transformed patches are normalized so that their sum is 1
2250     void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);
2251
2252     // InitializeFast: builds a descriptor using precomputed descriptors of pca components
2253     // - pose_count: the number of poses to build
2254     // - frontal: input patch. Can be a roi in a larger image
2255     // - feature_name: the feature name to be associated with the descriptor
2256     // - pca_hr_avg: average vector for PCA
2257     // - pca_hr_eigenvectors: PCA eigenvectors (one vector per row)
2258     // - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector
2259     // followed by the descriptors for eigenvectors
2260     void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
2261                         CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
2262
2263     // ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space
2264     // - patch: input image patch
2265     // - avg: PCA average vector
2266     // - eigenvectors: PCA eigenvectors, one per row
2267     // - pca_coeffs: output PCA coefficients
2268     void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;
2269
2270     // InitializePCACoeffs: projects all warped patches into PCA space
2271     // - avg: PCA average vector
2272     // - eigenvectors: PCA eigenvectors, one per row
2273     void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);
2274
2275     // EstimatePose: finds the closest match between an input patch and a set of patches with different poses
2276     // - patch: input image patch
2277     // - pose_idx: the output index of the closest pose
2278     // - distance: the distance to the closest pose (L2 distance)
2279     void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;
2280
2281     // EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses.
2282     // The distance between patches is computed in PCA space
2283     // - patch: input image patch
2284     // - pose_idx: the output index of the closest pose
2285     // - distance: distance to the closest pose (L2 distance in PCA space)
2286     // - avg: PCA average vector. If 0, matching without PCA is used
2287     // - eigenvectors: PCA eigenvectors, one per row
2288     void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;
2289
2290     // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch)
2291     CvSize GetPatchSize() const
2292     {
2293         return m_patch_size;
2294     }
2295
2296     // GetInputPatchSize: returns the required size of the patch that the descriptor is built from
2297     // (2 time larger than the patch after warping)
2298     CvSize GetInputPatchSize() const
2299     {
2300         return cvSize(m_patch_size.width*2, m_patch_size.height*2);
2301     }
2302
2303     // GetPatch: returns a patch corresponding to specified pose index
2304     // - index: pose index
2305     // - return value: the patch corresponding to specified pose index
2306     IplImage* GetPatch(int index);
2307
2308     // GetPose: returns a pose corresponding to specified pose index
2309     // - index: pose index
2310     // - return value: the pose corresponding to specified pose index
2311     CvAffinePose GetPose(int index) const;
2312
2313     // Save: saves all patches with different poses to a specified path
2314     void Save(const char* path);
2315
2316     // ReadByName: reads a descriptor from a file storage
2317     // - fs: file storage
2318     // - parent: parent node
2319     // - name: node name
2320     // - return value: 1 if succeeded, 0 otherwise
2321     int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);
2322
2323     // ReadByName: reads a descriptor from a file node
2324     // - parent: parent node
2325     // - name: node name
2326     // - return value: 1 if succeeded, 0 otherwise
2327     int ReadByName(const FileNode &parent, const char* name);
2328
2329     // Write: writes a descriptor into a file storage
2330     // - fs: file storage
2331     // - name: node name
2332     void Write(CvFileStorage* fs, const char* name);
2333
2334     // GetFeatureName: returns a name corresponding to a feature
2335     const char* GetFeatureName() const;
2336
2337     // GetCenter: returns the center of the feature
2338     CvPoint GetCenter() const;
2339
2340     void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};
2341     void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};
2342
2343     int GetPCADimLow() const;
2344     int GetPCADimHigh() const;
2345
2346     CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
2347
2348 protected:
2349     int m_pose_count; // the number of poses
2350     CvSize m_patch_size; // size of each image
2351     IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses
2352     IplImage* m_input_patch;
2353     IplImage* m_train_patch;
2354     CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses
2355     CvAffinePose* m_affine_poses; // an array of poses
2356     CvMat** m_transforms; // an array of affine transforms corresponding to poses
2357
2358     String m_feature_name; // the name of the feature associated with the descriptor
2359     CvPoint m_center; // the coordinates of the feature (the center of the input image ROI)
2360
2361     int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses
2362     int m_pca_dim_low; // the number of pca components to use for comparison
2363 };
2364
2365
2366 // OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors
2367 // and finding the nearest closest descriptor to an input feature
2368 class CV_EXPORTS OneWayDescriptorBase
2369 {
2370 public:
2371
2372     // creates an instance of OneWayDescriptor from a set of training files
2373     // - patch_size: size of the input (large) patch
2374     // - pose_count: the number of poses to generate for each descriptor
2375     // - train_path: path to training files
2376     // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
2377     // than patch_size each dimension
2378     // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
2379     // - pca_desc_config: the name of the file that contains descriptors of PCA components
2380     OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0,
2381                          const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
2382                          int pca_dim_high = 100, int pca_dim_low = 100);
2383
2384     OneWayDescriptorBase(CvSize patch_size, int pose_count, const String &pca_filename, const String &train_path = String(), const String &images_list = String(),
2385                          float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1,
2386                          int pca_dim_high = 100, int pca_dim_low = 100);
2387
2388
2389     virtual ~OneWayDescriptorBase();
2390     void clear ();
2391
2392
2393     // Allocate: allocates memory for a given number of descriptors
2394     void Allocate(int train_feature_count);
2395
2396     // AllocatePCADescriptors: allocates memory for pca descriptors
2397     void AllocatePCADescriptors();
2398
2399     // returns patch size
2400     CvSize GetPatchSize() const {return m_patch_size;};
2401     // returns the number of poses for each descriptor
2402     int GetPoseCount() const {return m_pose_count;};
2403
2404     // returns the number of pyramid levels
2405     int GetPyrLevels() const {return m_pyr_levels;};
2406
2407     // returns the number of descriptors
2408     int GetDescriptorCount() const {return m_train_feature_count;};
2409
2410     // CreateDescriptorsFromImage: creates descriptors for each of the input features
2411     // - src: input image
2412     // - features: input features
2413     // - pyr_levels: the number of pyramid levels
2414     void CreateDescriptorsFromImage(IplImage* src, const std::vector<KeyPoint>& features);
2415
2416     // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors
2417     void CreatePCADescriptors();
2418
2419     // returns a feature descriptor by feature index
2420     const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
2421
2422     // FindDescriptor: finds the closest descriptor
2423     // - patch: input image patch
2424     // - desc_idx: output index of the closest descriptor to the input patch
2425     // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
2426     // - distance: distance from the input patch to the closest feature pose
2427     // - _scales: scales of the input patch for each descriptor
2428     // - scale_ranges: input scales variation (float[2])
2429     void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const;
2430
2431     // - patch: input image patch
2432     // - n: number of the closest indexes
2433     // - desc_idxs: output indexes of the closest descriptor to the input patch (n)
2434     // - pose_idx: output indexes of the closest pose of the closest descriptor to the input patch (n)
2435     // - distances: distance from the input patch to the closest feature pose (n)
2436     // - _scales: scales of the input patch
2437     // - scale_ranges: input scales variation (float[2])
2438     void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
2439                         std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const;
2440
2441     // FindDescriptor: finds the closest descriptor
2442     // - src: input image
2443     // - pt: center of the feature
2444     // - desc_idx: output index of the closest descriptor to the input patch
2445     // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
2446     // - distance: distance from the input patch to the closest feature pose
2447     void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;
2448
2449     // InitializePoses: generates random poses
2450     void InitializePoses();
2451
2452     // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)
2453     void InitializeTransformsFromPoses();
2454
2455     // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses
2456     void InitializePoseTransforms();
2457
2458     // InitializeDescriptor: initializes a descriptor
2459     // - desc_idx: descriptor index
2460     // - train_image: image patch (ROI is supported)
2461     // - feature_label: feature textual label
2462     void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);
2463
2464     void InitializeDescriptor(int desc_idx, IplImage* train_image, const KeyPoint& keypoint, const char* feature_label);
2465
2466     // InitializeDescriptors: load features from an image and create descriptors for each of them
2467     void InitializeDescriptors(IplImage* train_image, const std::vector<KeyPoint>& features,
2468                                const char* feature_label = "", int desc_start_idx = 0);
2469
2470     // Write: writes this object to a file storage
2471     // - fs: output filestorage
2472     void Write (FileStorage &fs) const;
2473
2474     // Read: reads OneWayDescriptorBase object from a file node
2475     // - fn: input file node
2476     void Read (const FileNode &fn);
2477
2478     // LoadPCADescriptors: loads PCA descriptors from a file
2479     // - filename: input filename
2480     int LoadPCADescriptors(const char* filename);
2481
2482     // LoadPCADescriptors: loads PCA descriptors from a file node
2483     // - fn: input file node
2484     int LoadPCADescriptors(const FileNode &fn);
2485
2486     // SavePCADescriptors: saves PCA descriptors to a file
2487     // - filename: output filename
2488     void SavePCADescriptors(const char* filename);
2489
2490     // SavePCADescriptors: saves PCA descriptors to a file storage
2491     // - fs: output file storage
2492     void SavePCADescriptors(CvFileStorage* fs) const;
2493
2494     // GeneratePCA: calculate and save PCA components and descriptors
2495     // - img_path: path to training PCA images directory
2496     // - images_list: filename with filenames of training PCA images
2497     void GeneratePCA(const char* img_path, const char* images_list, int pose_count=500);
2498
2499     // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
2500     void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
2501
2502     // SetPCALow: sets the low resolution pca matrices (copied to internal structures)
2503     void SetPCALow(CvMat* avg, CvMat* eigenvectors);
2504
2505     int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
2506     {
2507         *avg = m_pca_avg;
2508         *eigenvectors = m_pca_eigenvectors;
2509         return m_pca_dim_low;
2510     };
2511
2512     int GetPCADimLow() const {return m_pca_dim_low;};
2513     int GetPCADimHigh() const {return m_pca_dim_high;};
2514
2515     void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
2516
2517     // GetPCAFilename: get default PCA filename
2518     static String GetPCAFilename () { return "pca.yml"; }
2519
2520     virtual bool empty() const { return m_train_feature_count <= 0 ? true : false; }
2521
2522 protected:
2523     CvSize m_patch_size; // patch size
2524     int m_pose_count; // the number of poses for each descriptor
2525     int m_train_feature_count; // the number of the training features
2526     OneWayDescriptor* m_descriptors; // array of train feature descriptors
2527     CvMat* m_pca_avg; // PCA average Vector for small patches
2528     CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches
2529     CvMat* m_pca_hr_avg; // PCA average Vector for large patches
2530     CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches
2531     OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors
2532
2533     cv::flann::Index* m_pca_descriptors_tree;
2534     CvMat* m_pca_descriptors_matrix;
2535
2536     CvAffinePose* m_poses; // array of poses
2537     CvMat** m_transforms; // array of affine transformations corresponding to poses
2538
2539     int m_pca_dim_high;
2540     int m_pca_dim_low;
2541
2542     int m_pyr_levels;
2543     float scale_min;
2544     float scale_max;
2545     float scale_step;
2546
2547     // SavePCAall: saves PCA components and descriptors to a file storage
2548     // - fs: output file storage
2549     void SavePCAall (FileStorage &fs) const;
2550
2551     // LoadPCAall: loads PCA components and descriptors from a file node
2552     // - fn: input file node
2553     void LoadPCAall (const FileNode &fn);
2554 };
2555
2556 class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase
2557 {
2558 public:
2559     // creates an instance of OneWayDescriptorObject from a set of training files
2560     // - patch_size: size of the input (large) patch
2561     // - pose_count: the number of poses to generate for each descriptor
2562     // - train_path: path to training files
2563     // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
2564     // than patch_size each dimension
2565     // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
2566     // - pca_desc_config: the name of the file that contains descriptors of PCA components
2567     OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
2568                            const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
2569
2570     OneWayDescriptorObject(CvSize patch_size, int pose_count, const String &pca_filename,
2571                            const String &train_path = String (), const String &images_list = String (),
2572                            float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1);
2573
2574
2575     virtual ~OneWayDescriptorObject();
2576
2577     // Allocate: allocates memory for a given number of features
2578     // - train_feature_count: the total number of features
2579     // - object_feature_count: the number of features extracted from the object
2580     void Allocate(int train_feature_count, int object_feature_count);
2581
2582
2583     void SetLabeledFeatures(const std::vector<KeyPoint>& features) {m_train_features = features;};
2584     std::vector<KeyPoint>& GetLabeledFeatures() {return m_train_features;};
2585     const std::vector<KeyPoint>& GetLabeledFeatures() const {return m_train_features;};
2586     std::vector<KeyPoint> _GetLabeledFeatures() const;
2587
2588     // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0
2589     int IsDescriptorObject(int desc_idx) const;
2590
2591     // MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1
2592     int MatchPointToPart(CvPoint pt) const;
2593
2594     // GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor
2595     // - desc_idx: descriptor index
2596     int GetDescriptorPart(int desc_idx) const;
2597
2598
2599     void InitializeObjectDescriptors(IplImage* train_image, const std::vector<KeyPoint>& features,
2600                                      const char* feature_label, int desc_start_idx = 0, float scale = 1.0f,
2601                                      int is_background = 0);
2602
2603     // GetObjectFeatureCount: returns the number of object features
2604     int GetObjectFeatureCount() const {return m_object_feature_count;};
2605
2606 protected:
2607     int* m_part_id; // contains part id for each of object descriptors
2608     std::vector<KeyPoint> m_train_features; // train features
2609     int m_object_feature_count; // the number of the positive features
2610
2611 };
2612
2613
2614 /*
2615  *  OneWayDescriptorMatcher
2616  */
2617 class OneWayDescriptorMatcher;
2618 typedef OneWayDescriptorMatcher OneWayDescriptorMatch;
2619
2620 class CV_EXPORTS OneWayDescriptorMatcher : public GenericDescriptorMatcher
2621 {
2622 public:
2623     class CV_EXPORTS Params
2624     {
2625     public:
2626         static const int POSE_COUNT = 500;
2627         static const int PATCH_WIDTH = 24;
2628         static const int PATCH_HEIGHT = 24;
2629         static float GET_MIN_SCALE() { return 0.7f; }
2630         static float GET_MAX_SCALE() { return 1.5f; }
2631         static float GET_STEP_SCALE() { return 1.2f; }
2632
2633         Params( int poseCount = POSE_COUNT,
2634                Size patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
2635                String pcaFilename = String(),
2636                String trainPath = String(), String trainImagesList = String(),
2637                float minScale = GET_MIN_SCALE(), float maxScale = GET_MAX_SCALE(),
2638                float stepScale = GET_STEP_SCALE() );
2639
2640         int poseCount;
2641         Size patchSize;
2642         String pcaFilename;
2643         String trainPath;
2644         String trainImagesList;
2645
2646         float minScale, maxScale, stepScale;
2647     };
2648
2649     OneWayDescriptorMatcher( const Params& params=Params() );
2650     virtual ~OneWayDescriptorMatcher();
2651
2652     void initialize( const Params& params, const Ptr<OneWayDescriptorBase>& base=Ptr<OneWayDescriptorBase>() );
2653
2654     // Clears keypoints storing in collection and OneWayDescriptorBase
2655     virtual void clear();
2656
2657     virtual void train();
2658
2659     virtual bool isMaskSupported();
2660
2661     virtual void read( const FileNode &fn );
2662     virtual void write( FileStorage& fs ) const;
2663
2664     virtual bool empty() const;
2665
2666     virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
2667
2668 protected:
2669     // Matches a set of keypoints from a single image of the training set. A rectangle with a center in a keypoint
2670     // and size (patch_width/2*scale, patch_height/2*scale) is cropped from the source image for each
2671     // keypoint. scale is iterated from DescriptorOneWayParams::min_scale to DescriptorOneWayParams::max_scale.
2672     // The minimum distance to each training patch with all its affine poses is found over all scales.
2673     // The class ID of a match is returned for each keypoint. The distance is calculated over PCA components
2674     // loaded with DescriptorOneWay::Initialize, kd tree is used for finding minimum distances.
2675     virtual void knnMatchImpl( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
2676                               std::vector<std::vector<DMatch> >& matches, int k,
2677                               InputArrayOfArrays masks, bool compactResult );
2678     virtual void radiusMatchImpl( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
2679                                  std::vector<std::vector<DMatch> >& matches, float maxDistance,
2680                                  InputArrayOfArrays masks, bool compactResult );
2681
2682     Ptr<OneWayDescriptorBase> base;
2683     Params params;
2684     int prevTrainCount;
2685 };
2686
2687 /*
2688  *  FernDescriptorMatcher
2689  */
2690 class FernDescriptorMatcher;
2691 typedef FernDescriptorMatcher FernDescriptorMatch;
2692
2693 class CV_EXPORTS FernDescriptorMatcher : public GenericDescriptorMatcher
2694 {
2695 public:
2696     class CV_EXPORTS Params
2697     {
2698     public:
2699         Params( int nclasses=0,
2700                int patchSize=FernClassifier::PATCH_SIZE,
2701                int signatureSize=FernClassifier::DEFAULT_SIGNATURE_SIZE,
2702                int nstructs=FernClassifier::DEFAULT_STRUCTS,
2703                int structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
2704                int nviews=FernClassifier::DEFAULT_VIEWS,
2705                int compressionMethod=FernClassifier::COMPRESSION_NONE,
2706                const PatchGenerator& patchGenerator=PatchGenerator() );
2707
2708         Params( const String& filename );
2709
2710         int nclasses;
2711         int patchSize;
2712         int signatureSize;
2713         int nstructs;
2714         int structSize;
2715         int nviews;
2716         int compressionMethod;
2717         PatchGenerator patchGenerator;
2718
2719         String filename;
2720     };
2721
2722     FernDescriptorMatcher( const Params& params=Params() );
2723     virtual ~FernDescriptorMatcher();
2724
2725     virtual void clear();
2726
2727     virtual void train();
2728
2729     virtual bool isMaskSupported();
2730
2731     virtual void read( const FileNode &fn );
2732     virtual void write( FileStorage& fs ) const;
2733     virtual bool empty() const;
2734
2735     virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
2736
2737 protected:
2738     virtual void knnMatchImpl( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
2739                               std::vector<std::vector<DMatch> >& matches, int k,
2740                               InputArrayOfArrays masks, bool compactResult );
2741     virtual void radiusMatchImpl( InputArray queryImage, std::vector<KeyPoint>& queryKeypoints,
2742                                  std::vector<std::vector<DMatch> >& matches, float maxDistance,
2743                                  InputArrayOfArrays masks, bool compactResult );
2744
2745     void trainFernClassifier();
2746     void calcBestProbAndMatchIdx( const Mat& image, const Point2f& pt,
2747                                  float& bestProb, int& bestMatchIdx, std::vector<float>& signature );
2748     Ptr<FernClassifier> classifier;
2749     Params params;
2750     int prevTrainCount;
2751 };
2752
2753
2754 /*
2755  * CalonderDescriptorExtractor
2756  */
2757 template<typename T>
2758 class CV_EXPORTS CalonderDescriptorExtractor : public DescriptorExtractor
2759 {
2760 public:
2761     CalonderDescriptorExtractor( const String& classifierFile );
2762
2763     virtual void read( const FileNode &fn );
2764     virtual void write( FileStorage &fs ) const;
2765
2766     virtual int descriptorSize() const { return classifier_.classes(); }
2767     virtual int descriptorType() const { return DataType<T>::type; }
2768     virtual int defaultNorm() const { return NORM_L1; }
2769
2770     virtual bool empty() const;
2771
2772 protected:
2773     virtual void computeImpl( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray descriptors ) const;
2774
2775     RTreeClassifier classifier_;
2776     static const int BORDER_SIZE = 16;
2777 };
2778
2779 template<typename T>
2780 CalonderDescriptorExtractor<T>::CalonderDescriptorExtractor(const String& classifier_file)
2781 {
2782     classifier_.read( classifier_file.c_str() );
2783 }
2784
2785 template<typename T>
2786 void CalonderDescriptorExtractor<T>::computeImpl( InputArray _image,
2787                                                  std::vector<KeyPoint>& keypoints,
2788                                                  OutputArray _descriptors) const
2789 {
2790     Mat image = _image.getMat(), descriptors;
2791     // Cannot compute descriptors for keypoints on the image border.
2792     KeyPointsFilter::runByImageBorder(keypoints, image.size(), BORDER_SIZE);
2793
2794     /// @todo Check 16-byte aligned
2795     _descriptors.create((int)keypoints.size(), classifier_.classes(), cv::DataType<T>::type);
2796      descriptors = _descriptors.getMat();
2797
2798     int patchSize = RandomizedTree::PATCH_SIZE;
2799     int offset = patchSize / 2;
2800     for (size_t i = 0; i < keypoints.size(); ++i)
2801     {
2802         cv::Point2f pt = keypoints[i].pt;
2803         IplImage ipl = image( Rect((int)(pt.x - offset), (int)(pt.y - offset), patchSize, patchSize) );
2804         classifier_.getSignature( &ipl, descriptors.ptr<T>((int)i));
2805     }
2806 }
2807
2808 template<typename T>
2809 void CalonderDescriptorExtractor<T>::read( const FileNode& )
2810 {}
2811
2812 template<typename T>
2813 void CalonderDescriptorExtractor<T>::write( FileStorage& ) const
2814 {}
2815
2816 template<typename T>
2817 bool CalonderDescriptorExtractor<T>::empty() const
2818 {
2819     return classifier_.trees_.empty();
2820 }
2821
2822
2823 ////////////////////// Brute Force Matcher //////////////////////////
2824
2825 template<class Distance>
2826 class CV_EXPORTS BruteForceMatcher : public BFMatcher
2827 {
2828 public:
2829     BruteForceMatcher( Distance d = Distance() ) : BFMatcher(Distance::normType, false) {(void)d;}
2830     virtual ~BruteForceMatcher() {}
2831 };
2832
2833
2834 /****************************************************************************************\
2835 *                                Planar Object Detection                                 *
2836 \****************************************************************************************/
2837
2838 class CV_EXPORTS PlanarObjectDetector
2839 {
2840 public:
2841     PlanarObjectDetector();
2842     PlanarObjectDetector(const FileNode& node);
2843     PlanarObjectDetector(const std::vector<Mat>& pyr, int _npoints=300,
2844                          int _patchSize=FernClassifier::PATCH_SIZE,
2845                          int _nstructs=FernClassifier::DEFAULT_STRUCTS,
2846                          int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
2847                          int _nviews=FernClassifier::DEFAULT_VIEWS,
2848                          const LDetector& detector=LDetector(),
2849                          const PatchGenerator& patchGenerator=PatchGenerator());
2850     virtual ~PlanarObjectDetector();
2851     virtual void train(const std::vector<Mat>& pyr, int _npoints=300,
2852                        int _patchSize=FernClassifier::PATCH_SIZE,
2853                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
2854                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
2855                        int _nviews=FernClassifier::DEFAULT_VIEWS,
2856                        const LDetector& detector=LDetector(),
2857                        const PatchGenerator& patchGenerator=PatchGenerator());
2858     virtual void train(const std::vector<Mat>& pyr, const std::vector<KeyPoint>& keypoints,
2859                        int _patchSize=FernClassifier::PATCH_SIZE,
2860                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
2861                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
2862                        int _nviews=FernClassifier::DEFAULT_VIEWS,
2863                        const LDetector& detector=LDetector(),
2864                        const PatchGenerator& patchGenerator=PatchGenerator());
2865     Rect getModelROI() const;
2866     std::vector<KeyPoint> getModelPoints() const;
2867     const LDetector& getDetector() const;
2868     const FernClassifier& getClassifier() const;
2869     void setVerbose(bool verbose);
2870
2871     void read(const FileNode& node);
2872     void write(FileStorage& fs, const String& name=String()) const;
2873     bool operator()(const Mat& image, CV_OUT Mat& H, CV_OUT std::vector<Point2f>& corners) const;
2874     bool operator()(const std::vector<Mat>& pyr, const std::vector<KeyPoint>& keypoints,
2875                     CV_OUT Mat& H, CV_OUT std::vector<Point2f>& corners,
2876                     CV_OUT std::vector<int>* pairs=0) const;
2877
2878 protected:
2879     bool verbose;
2880     Rect modelROI;
2881     std::vector<KeyPoint> modelPoints;
2882     LDetector ldetector;
2883     FernClassifier fernClassifier;
2884 };
2885
2886 }
2887
2888 // 2009-01-12, Xavier Delacour <xavier.delacour@gmail.com>
2889
2890 struct lsh_hash {
2891     int h1, h2;
2892 };
2893
2894 struct CvLSHOperations
2895 {
2896     virtual ~CvLSHOperations() {}
2897
2898     virtual int vector_add(const void* data) = 0;
2899     virtual void vector_remove(int i) = 0;
2900     virtual const void* vector_lookup(int i) = 0;
2901     virtual void vector_reserve(int n) = 0;
2902     virtual unsigned int vector_count() = 0;
2903
2904     virtual void hash_insert(lsh_hash h, int l, int i) = 0;
2905     virtual void hash_remove(lsh_hash h, int l, int i) = 0;
2906     virtual int hash_lookup(lsh_hash h, int l, int* ret_i, int ret_i_max) = 0;
2907 };
2908
2909 #endif
2910
2911 #ifdef __cplusplus
2912 extern "C" {
2913 #endif
2914
2915 /* Splits color or grayscale image into multiple connected components
2916  of nearly the same color/brightness using modification of Burt algorithm.
2917  comp with contain a pointer to sequence (CvSeq)
2918  of connected components (CvConnectedComp) */
2919 CVAPI(void) cvPyrSegmentation( IplImage* src, IplImage* dst,
2920                               CvMemStorage* storage, CvSeq** comp,
2921                               int level, double threshold1,
2922                               double threshold2 );
2923
2924 /****************************************************************************************\
2925 *                              Planar subdivisions                                       *
2926 \****************************************************************************************/
2927
2928 typedef size_t CvSubdiv2DEdge;
2929
2930 #define CV_QUADEDGE2D_FIELDS()     \
2931     int flags;                     \
2932     struct CvSubdiv2DPoint* pt[4]; \
2933     CvSubdiv2DEdge  next[4];
2934
2935 #define CV_SUBDIV2D_POINT_FIELDS()\
2936     int            flags;      \
2937     CvSubdiv2DEdge first;      \
2938     CvPoint2D32f   pt;         \
2939     int id;
2940
2941 #define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30)
2942
2943 typedef struct CvQuadEdge2D
2944 {
2945     CV_QUADEDGE2D_FIELDS()
2946 }
2947 CvQuadEdge2D;
2948
2949 typedef struct CvSubdiv2DPoint
2950 {
2951     CV_SUBDIV2D_POINT_FIELDS()
2952 }
2953 CvSubdiv2DPoint;
2954
2955 #define CV_SUBDIV2D_FIELDS()    \
2956     CV_GRAPH_FIELDS()           \
2957     int  quad_edges;            \
2958     int  is_geometry_valid;     \
2959     CvSubdiv2DEdge recent_edge; \
2960     CvPoint2D32f  topleft;      \
2961     CvPoint2D32f  bottomright;
2962
2963 typedef struct CvSubdiv2D
2964 {
2965     CV_SUBDIV2D_FIELDS()
2966 }
2967 CvSubdiv2D;
2968
2969 typedef enum CvSubdiv2DPointLocation
2970 {
2971     CV_PTLOC_ERROR = -2,
2972     CV_PTLOC_OUTSIDE_RECT = -1,
2973     CV_PTLOC_INSIDE = 0,
2974     CV_PTLOC_VERTEX = 1,
2975     CV_PTLOC_ON_EDGE = 2
2976 }
2977 CvSubdiv2DPointLocation;
2978
2979 typedef enum CvNextEdgeType
2980 {
2981     CV_NEXT_AROUND_ORG   = 0x00,
2982     CV_NEXT_AROUND_DST   = 0x22,
2983     CV_PREV_AROUND_ORG   = 0x11,
2984     CV_PREV_AROUND_DST   = 0x33,
2985     CV_NEXT_AROUND_LEFT  = 0x13,
2986     CV_NEXT_AROUND_RIGHT = 0x31,
2987     CV_PREV_AROUND_LEFT  = 0x20,
2988     CV_PREV_AROUND_RIGHT = 0x02
2989 }
2990 CvNextEdgeType;
2991
2992 /* get the next edge with the same origin point (counterwise) */
2993 #define  CV_SUBDIV2D_NEXT_EDGE( edge )  (((CvQuadEdge2D*)((edge) & ~3))->next[(edge)&3])
2994
2995
2996 /* Initializes Delaunay triangulation */
2997 CVAPI(void)  cvInitSubdivDelaunay2D( CvSubdiv2D* subdiv, CvRect rect );
2998
2999 /* Creates new subdivision */
3000 CVAPI(CvSubdiv2D*)  cvCreateSubdiv2D( int subdiv_type, int header_size,
3001                                      int vtx_size, int quadedge_size,
3002                                      CvMemStorage* storage );
3003
3004 /************************* high-level subdivision functions ***************************/
3005
3006 /* Simplified Delaunay diagram creation */
3007 CV_INLINE  CvSubdiv2D* cvCreateSubdivDelaunay2D( CvRect rect, CvMemStorage* storage )
3008 {
3009     CvSubdiv2D* subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*subdiv),
3010                                           sizeof(CvSubdiv2DPoint), sizeof(CvQuadEdge2D), storage );
3011
3012     cvInitSubdivDelaunay2D( subdiv, rect );
3013     return subdiv;
3014 }
3015
3016
3017 /* Inserts new point to the Delaunay triangulation */
3018 CVAPI(CvSubdiv2DPoint*)  cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt);
3019
3020 /* Locates a point within the Delaunay triangulation (finds the edge
3021  the point is left to or belongs to, or the triangulation point the given
3022  point coinsides with */
3023 CVAPI(CvSubdiv2DPointLocation)  cvSubdiv2DLocate(
3024                                                  CvSubdiv2D* subdiv, CvPoint2D32f pt,
3025                                                  CvSubdiv2DEdge* edge,
3026                                                  CvSubdiv2DPoint** vertex CV_DEFAULT(NULL) );
3027
3028 /* Calculates Voronoi tesselation (i.e. coordinates of Voronoi points) */
3029 CVAPI(void)  cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv );
3030
3031
3032 /* Removes all Voronoi points from the tesselation */
3033 CVAPI(void)  cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv );
3034
3035
3036 /* Finds the nearest to the given point vertex in subdivision. */
3037 CVAPI(CvSubdiv2DPoint*) cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt );
3038
3039
3040 /************ Basic quad-edge navigation and operations ************/
3041
3042 CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DNextEdge( CvSubdiv2DEdge edge )
3043 {
3044     return  CV_SUBDIV2D_NEXT_EDGE(edge);
3045 }
3046
3047
3048 CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate )
3049 {
3050     return  (edge & ~3) + ((edge + rotate) & 3);
3051 }
3052
3053 CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DSymEdge( CvSubdiv2DEdge edge )
3054 {
3055     return edge ^ 2;
3056 }
3057
3058 CV_INLINE  CvSubdiv2DEdge  cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type )
3059 {
3060     CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3);
3061     edge = e->next[(edge + (int)type) & 3];
3062     return  (edge & ~3) + ((edge + ((int)type >> 4)) & 3);
3063 }
3064
3065
3066 CV_INLINE  CvSubdiv2DPoint*  cvSubdiv2DEdgeOrg( CvSubdiv2DEdge edge )
3067 {
3068     CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3);
3069     return (CvSubdiv2DPoint*)e->pt[edge & 3];
3070 }
3071
3072
3073 CV_INLINE  CvSubdiv2DPoint*  cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge )
3074 {
3075     CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3);
3076     return (CvSubdiv2DPoint*)e->pt[(edge + 2) & 3];
3077 }
3078
3079 /****************************************************************************************\
3080 *                           Additional operations on Subdivisions                        *
3081 \****************************************************************************************/
3082
3083 // paints voronoi diagram: just demo function
3084 CVAPI(void)  icvDrawMosaic( CvSubdiv2D* subdiv, IplImage* src, IplImage* dst );
3085
3086 // checks planar subdivision for correctness. It is not an absolute check,
3087 // but it verifies some relations between quad-edges
3088 CVAPI(int)   icvSubdiv2DCheck( CvSubdiv2D* subdiv );
3089
3090 // returns squared distance between two 2D points with floating-point coordinates.
3091 CV_INLINE double icvSqDist2D32f( CvPoint2D32f pt1, CvPoint2D32f pt2 )
3092 {
3093     double dx = pt1.x - pt2.x;
3094     double dy = pt1.y - pt2.y;
3095
3096     return dx*dx + dy*dy;
3097 }
3098
3099
3100
3101
3102 CV_INLINE  double  cvTriangleArea( CvPoint2D32f a, CvPoint2D32f b, CvPoint2D32f c )
3103 {
3104     return ((double)b.x - a.x) * ((double)c.y - a.y) - ((double)b.y - a.y) * ((double)c.x - a.x);
3105 }
3106
3107
3108 /* Constructs kd-tree from set of feature descriptors */
3109 CVAPI(struct CvFeatureTree*) cvCreateKDTree(CvMat* desc);
3110
3111 /* Constructs spill-tree from set of feature descriptors */
3112 CVAPI(struct CvFeatureTree*) cvCreateSpillTree( const CvMat* raw_data,
3113                                                const int naive CV_DEFAULT(50),
3114                                                const double rho CV_DEFAULT(.7),
3115                                                const double tau CV_DEFAULT(.1) );
3116
3117 /* Release feature tree */
3118 CVAPI(void) cvReleaseFeatureTree(struct CvFeatureTree* tr);
3119
3120 /* Searches feature tree for k nearest neighbors of given reference points,
3121  searching (in case of kd-tree/bbf) at most emax leaves. */
3122 CVAPI(void) cvFindFeatures(struct CvFeatureTree* tr, const CvMat* query_points,
3123                            CvMat* indices, CvMat* dist, int k, int emax CV_DEFAULT(20));
3124
3125 /* Search feature tree for all points that are inlier to given rect region.
3126  Only implemented for kd trees */
3127 CVAPI(int) cvFindFeaturesBoxed(struct CvFeatureTree* tr,
3128                                CvMat* bounds_min, CvMat* bounds_max,
3129                                CvMat* out_indices);
3130
3131
3132 /* Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
3133  given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions. */
3134 CVAPI(struct CvLSH*) cvCreateLSH(struct CvLSHOperations* ops, int d,
3135                                  int L CV_DEFAULT(10), int k CV_DEFAULT(10),
3136                                  int type CV_DEFAULT(CV_64FC1), double r CV_DEFAULT(4),
3137                                  int64 seed CV_DEFAULT(-1));
3138
3139 /* Construct in-memory LSH table, with n bins. */
3140 CVAPI(struct CvLSH*) cvCreateMemoryLSH(int d, int n, int L CV_DEFAULT(10), int k CV_DEFAULT(10),
3141                                        int type CV_DEFAULT(CV_64FC1), double r CV_DEFAULT(4),
3142                                        int64 seed CV_DEFAULT(-1));
3143
3144 /* Free the given LSH structure. */
3145 CVAPI(void) cvReleaseLSH(struct CvLSH** lsh);
3146
3147 /* Return the number of vectors in the LSH. */
3148 CVAPI(unsigned int) LSHSize(struct CvLSH* lsh);
3149
3150 /* Add vectors to the LSH structure, optionally returning indices. */
3151 CVAPI(void) cvLSHAdd(struct CvLSH* lsh, const CvMat* data, CvMat* indices CV_DEFAULT(0));
3152
3153 /* Remove vectors from LSH, as addressed by given indices. */
3154 CVAPI(void) cvLSHRemove(struct CvLSH* lsh, const CvMat* indices);
3155
3156 /* Query the LSH n times for at most k nearest points; data is n x d,
3157  indices and dist are n x k. At most emax stored points will be accessed. */
3158 CVAPI(void) cvLSHQuery(struct CvLSH* lsh, const CvMat* query_points,
3159                        CvMat* indices, CvMat* dist, int k, int emax);
3160
3161 /* Kolmogorov-Zabin stereo-correspondence algorithm (a.k.a. KZ1) */
3162 #define CV_STEREO_GC_OCCLUDED  SHRT_MAX
3163
3164 typedef struct CvStereoGCState
3165 {
3166     int Ithreshold;
3167     int interactionRadius;
3168     float K, lambda, lambda1, lambda2;
3169     int occlusionCost;
3170     int minDisparity;
3171     int numberOfDisparities;
3172     int maxIters;
3173
3174     CvMat* left;
3175     CvMat* right;
3176     CvMat* dispLeft;
3177     CvMat* dispRight;
3178     CvMat* ptrLeft;
3179     CvMat* ptrRight;
3180     CvMat* vtxBuf;
3181     CvMat* edgeBuf;
3182 } CvStereoGCState;
3183
3184 CVAPI(CvStereoGCState*) cvCreateStereoGCState( int numberOfDisparities, int maxIters );
3185 CVAPI(void) cvReleaseStereoGCState( CvStereoGCState** state );
3186
3187 CVAPI(void) cvFindStereoCorrespondenceGC( const CvArr* left, const CvArr* right,
3188                                          CvArr* disparityLeft, CvArr* disparityRight,
3189                                          CvStereoGCState* state,
3190                                          int useDisparityGuess CV_DEFAULT(0) );
3191
3192 /* Calculates optical flow for 2 images using classical Lucas & Kanade algorithm */
3193 CVAPI(void)  cvCalcOpticalFlowLK( const CvArr* prev, const CvArr* curr,
3194                                  CvSize win_size, CvArr* velx, CvArr* vely );
3195
3196 /* Calculates optical flow for 2 images using block matching algorithm */
3197 CVAPI(void)  cvCalcOpticalFlowBM( const CvArr* prev, const CvArr* curr,
3198                                  CvSize block_size, CvSize shift_size,
3199                                  CvSize max_range, int use_previous,
3200                                  CvArr* velx, CvArr* vely );
3201
3202 /* Calculates Optical flow for 2 images using Horn & Schunck algorithm */
3203 CVAPI(void)  cvCalcOpticalFlowHS( const CvArr* prev, const CvArr* curr,
3204                                  int use_previous, CvArr* velx, CvArr* vely,
3205                                  double lambda, CvTermCriteria criteria );
3206
3207
3208 /****************************************************************************************\
3209 *                           Background/foreground segmentation                           *
3210 \****************************************************************************************/
3211
3212 /* We discriminate between foreground and background pixels
3213  * by building and maintaining a model of the background.
3214  * Any pixel which does not fit this model is then deemed
3215  * to be foreground.
3216  *
3217  * At present we support two core background models,
3218  * one of which has two variations:
3219  *
3220  *  o CV_BG_MODEL_FGD: latest and greatest algorithm, described in
3221  *
3222  *       Foreground Object Detection from Videos Containing Complex Background.
3223  *       Liyuan Li, Weimin Huang, Irene Y.H. Gu, and Qi Tian.
3224  *       ACM MM2003 9p
3225  *
3226  *  o CV_BG_MODEL_FGD_SIMPLE:
3227  *       A code comment describes this as a simplified version of the above,
3228  *       but the code is in fact currently identical
3229  *
3230  *  o CV_BG_MODEL_MOG: "Mixture of Gaussians", older algorithm, described in
3231  *
3232  *       Moving target classification and tracking from real-time video.
3233  *       A Lipton, H Fujijoshi, R Patil
3234  *       Proceedings IEEE Workshop on Application of Computer Vision pp 8-14 1998
3235  *
3236  *       Learning patterns of activity using real-time tracking
3237  *       C Stauffer and W Grimson  August 2000
3238  *       IEEE Transactions on Pattern Analysis and Machine Intelligence 22(8):747-757
3239  */
3240
3241
3242 #define CV_BG_MODEL_FGD         0
3243 #define CV_BG_MODEL_MOG         1                       /* "Mixture of Gaussians".      */
3244 #define CV_BG_MODEL_FGD_SIMPLE  2
3245
3246 struct CvBGStatModel;
3247
3248 typedef void (CV_CDECL * CvReleaseBGStatModel)( struct CvBGStatModel** bg_model );
3249 typedef int (CV_CDECL * CvUpdateBGStatModel)( IplImage* curr_frame, struct CvBGStatModel* bg_model,
3250                                              double learningRate );
3251
3252 #define CV_BG_STAT_MODEL_FIELDS()                                               \
3253 int             type; /*type of BG model*/                                      \
3254 CvReleaseBGStatModel release;                                                   \
3255 CvUpdateBGStatModel update;                                                     \
3256 IplImage*       background;   /*8UC3 reference background image*/               \
3257 IplImage*       foreground;   /*8UC1 foreground image*/                         \
3258 IplImage**      layers;       /*8UC3 reference background image, can be null */ \
3259 int             layer_count;  /* can be zero */                                 \
3260 CvMemStorage*   storage;      /*storage for foreground_regions*/                \
3261 CvSeq*          foreground_regions /*foreground object contours*/
3262
3263 typedef struct CvBGStatModel
3264 {
3265     CV_BG_STAT_MODEL_FIELDS();
3266 } CvBGStatModel;
3267
3268 //
3269
3270 // Releases memory used by BGStatModel
3271 CVAPI(void) cvReleaseBGStatModel( CvBGStatModel** bg_model );
3272
3273 // Updates statistical model and returns number of found foreground regions
3274 CVAPI(int) cvUpdateBGStatModel( IplImage* current_frame, CvBGStatModel*  bg_model,
3275                                double learningRate CV_DEFAULT(-1));
3276
3277 // Performs FG post-processing using segmentation
3278 // (all pixels of a region will be classified as foreground if majority of pixels of the region are FG).
3279 // parameters:
3280 //      segments - pointer to result of segmentation (for example MeanShiftSegmentation)
3281 //      bg_model - pointer to CvBGStatModel structure
3282 CVAPI(void) cvRefineForegroundMaskBySegm( CvSeq* segments, CvBGStatModel*  bg_model );
3283
3284 /* Common use change detection function */
3285 CVAPI(int)  cvChangeDetection( IplImage*  prev_frame,
3286                               IplImage*  curr_frame,
3287                               IplImage*  change_mask );
3288
3289 /*
3290  Interface of ACM MM2003 algorithm
3291  */
3292
3293 /* Default parameters of foreground detection algorithm: */
3294 #define  CV_BGFG_FGD_LC              128
3295 #define  CV_BGFG_FGD_N1C             15
3296 #define  CV_BGFG_FGD_N2C             25
3297
3298 #define  CV_BGFG_FGD_LCC             64
3299 #define  CV_BGFG_FGD_N1CC            25
3300 #define  CV_BGFG_FGD_N2CC            40
3301
3302 /* Background reference image update parameter: */
3303 #define  CV_BGFG_FGD_ALPHA_1         0.1f
3304
3305 /* stat model update parameter
3306  * 0.002f ~ 1K frame(~45sec), 0.005 ~ 18sec (if 25fps and absolutely static BG)
3307  */
3308 #define  CV_BGFG_FGD_ALPHA_2         0.005f
3309
3310 /* start value for alpha parameter (to fast initiate statistic model) */
3311 #define  CV_BGFG_FGD_ALPHA_3         0.1f
3312
3313 #define  CV_BGFG_FGD_DELTA           2
3314
3315 #define  CV_BGFG_FGD_T               0.9f
3316
3317 #define  CV_BGFG_FGD_MINAREA         15.f
3318
3319 #define  CV_BGFG_FGD_BG_UPDATE_TRESH 0.5f
3320
3321 /* See the above-referenced Li/Huang/Gu/Tian paper
3322  * for a full description of these background-model
3323  * tuning parameters.
3324  *
3325  * Nomenclature:  'c'  == "color", a three-component red/green/blue vector.
3326  *                         We use histograms of these to model the range of
3327  *                         colors we've seen at a given background pixel.
3328  *
3329  *                'cc' == "color co-occurrence", a six-component vector giving
3330  *                         RGB color for both this frame and preceding frame.
3331  *                             We use histograms of these to model the range of
3332  *                         color CHANGES we've seen at a given background pixel.
3333  */
3334 typedef struct CvFGDStatModelParams
3335 {
3336     int    Lc;                  /* Quantized levels per 'color' component. Power of two, typically 32, 64 or 128.                               */
3337     int    N1c;                 /* Number of color vectors used to model normal background color variation at a given pixel.                    */
3338     int    N2c;                 /* Number of color vectors retained at given pixel.  Must be > N1c, typically ~ 5/3 of N1c.                     */
3339     /* Used to allow the first N1c vectors to adapt over time to changing background.                           */
3340
3341     int    Lcc;                 /* Quantized levels per 'color co-occurrence' component.  Power of two, typically 16, 32 or 64.                 */
3342     int    N1cc;                /* Number of color co-occurrence vectors used to model normal background color variation at a given pixel.      */
3343     int    N2cc;                /* Number of color co-occurrence vectors retained at given pixel.  Must be > N1cc, typically ~ 5/3 of N1cc.     */
3344     /* Used to allow the first N1cc vectors to adapt over time to changing background.                          */
3345
3346     int    is_obj_without_holes;/* If TRUE we ignore holes within foreground blobs. Defaults to TRUE.                                           */
3347     int    perform_morphing;    /* Number of erode-dilate-erode foreground-blob cleanup iterations.                                             */
3348     /* These erase one-pixel junk blobs and merge almost-touching blobs. Default value is 1.                    */
3349
3350     float  alpha1;              /* How quickly we forget old background pixel values seen.  Typically set to 0.1                                */
3351     float  alpha2;              /* "Controls speed of feature learning". Depends on T. Typical value circa 0.005.                               */
3352     float  alpha3;              /* Alternate to alpha2, used (e.g.) for quicker initial convergence. Typical value 0.1.                         */
3353
3354     float  delta;               /* Affects color and color co-occurrence quantization, typically set to 2.                                      */
3355     float  T;                   /* "A percentage value which determines when new features can be recognized as new background." (Typically 0.9).*/
3356     float  minArea;             /* Discard foreground blobs whose bounding box is smaller than this threshold.                                  */
3357 } CvFGDStatModelParams;
3358
3359 typedef struct CvBGPixelCStatTable
3360 {
3361     float          Pv, Pvb;
3362     uchar          v[3];
3363 } CvBGPixelCStatTable;
3364
3365 typedef struct CvBGPixelCCStatTable
3366 {
3367     float          Pv, Pvb;
3368     uchar          v[6];
3369 } CvBGPixelCCStatTable;
3370
3371 typedef struct CvBGPixelStat
3372 {
3373     float                 Pbc;
3374     float                 Pbcc;
3375     CvBGPixelCStatTable*  ctable;
3376     CvBGPixelCCStatTable* cctable;
3377     uchar                 is_trained_st_model;
3378     uchar                 is_trained_dyn_model;
3379 } CvBGPixelStat;
3380
3381
3382 typedef struct CvFGDStatModel
3383 {
3384     CV_BG_STAT_MODEL_FIELDS();
3385     CvBGPixelStat*         pixel_stat;
3386     IplImage*              Ftd;
3387     IplImage*              Fbd;
3388     IplImage*              prev_frame;
3389     CvFGDStatModelParams   params;
3390 } CvFGDStatModel;
3391
3392 /* Creates FGD model */
3393 CVAPI(CvBGStatModel*) cvCreateFGDStatModel( IplImage* first_frame,
3394                                            CvFGDStatModelParams* parameters CV_DEFAULT(NULL));
3395
3396 /*
3397  Interface of Gaussian mixture algorithm
3398
3399  "An improved adaptive background mixture model for real-time tracking with shadow detection"
3400  P. KadewTraKuPong and R. Bowden,
3401  Proc. 2nd European Workshp on Advanced Video-Based Surveillance Systems, 2001."
3402  http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdf
3403  */
3404
3405 /* Note:  "MOG" == "Mixture Of Gaussians": */
3406
3407 #define CV_BGFG_MOG_MAX_NGAUSSIANS 500
3408
3409 /* default parameters of gaussian background detection algorithm */
3410 #define CV_BGFG_MOG_BACKGROUND_THRESHOLD     0.7     /* threshold sum of weights for background test */
3411 #define CV_BGFG_MOG_STD_THRESHOLD            2.5     /* lambda=2.5 is 99% */
3412 #define CV_BGFG_MOG_WINDOW_SIZE              200     /* Learning rate; alpha = 1/CV_GBG_WINDOW_SIZE */
3413 #define CV_BGFG_MOG_NGAUSSIANS               5       /* = K = number of Gaussians in mixture */
3414 #define CV_BGFG_MOG_WEIGHT_INIT              0.05
3415 #define CV_BGFG_MOG_SIGMA_INIT               30
3416 #define CV_BGFG_MOG_MINAREA                  15.f
3417
3418
3419 #define CV_BGFG_MOG_NCOLORS                  3
3420
3421 typedef struct CvGaussBGStatModelParams
3422 {
3423     int     win_size;               /* = 1/alpha */
3424     int     n_gauss;
3425     double  bg_threshold, std_threshold, minArea;
3426     double  weight_init, variance_init;
3427 }CvGaussBGStatModelParams;
3428
3429 typedef struct CvGaussBGValues
3430 {
3431     int         match_sum;
3432     double      weight;
3433     double      variance[CV_BGFG_MOG_NCOLORS];
3434     double      mean[CV_BGFG_MOG_NCOLORS];
3435 } CvGaussBGValues;
3436
3437 typedef struct CvGaussBGPoint
3438 {
3439     CvGaussBGValues* g_values;
3440 } CvGaussBGPoint;
3441
3442
3443 typedef struct CvGaussBGModel
3444 {
3445     CV_BG_STAT_MODEL_FIELDS();
3446     CvGaussBGStatModelParams   params;
3447     CvGaussBGPoint*            g_point;
3448     int                        countFrames;
3449     void*                      mog;
3450 } CvGaussBGModel;
3451
3452
3453 /* Creates Gaussian mixture background model */
3454 CVAPI(CvBGStatModel*) cvCreateGaussianBGModel( IplImage* first_frame,
3455                                               CvGaussBGStatModelParams* parameters CV_DEFAULT(NULL));
3456
3457
3458 typedef struct CvBGCodeBookElem
3459 {
3460     struct CvBGCodeBookElem* next;
3461     int tLastUpdate;
3462     int stale;
3463     uchar boxMin[3];
3464     uchar boxMax[3];
3465     uchar learnMin[3];
3466     uchar learnMax[3];
3467 } CvBGCodeBookElem;
3468
3469 typedef struct CvBGCodeBookModel
3470 {
3471     CvSize size;
3472     int t;
3473     uchar cbBounds[3];
3474     uchar modMin[3];
3475     uchar modMax[3];
3476     CvBGCodeBookElem** cbmap;
3477     CvMemStorage* storage;
3478     CvBGCodeBookElem* freeList;
3479 } CvBGCodeBookModel;
3480
3481 CVAPI(CvBGCodeBookModel*) cvCreateBGCodeBookModel( void );
3482 CVAPI(void) cvReleaseBGCodeBookModel( CvBGCodeBookModel** model );
3483
3484 CVAPI(void) cvBGCodeBookUpdate( CvBGCodeBookModel* model, const CvArr* image,
3485                                CvRect roi CV_DEFAULT(cvRect(0,0,0,0)),
3486                                const CvArr* mask CV_DEFAULT(0) );
3487
3488 CVAPI(int) cvBGCodeBookDiff( const CvBGCodeBookModel* model, const CvArr* image,
3489                             CvArr* fgmask, CvRect roi CV_DEFAULT(cvRect(0,0,0,0)) );
3490
3491 CVAPI(void) cvBGCodeBookClearStale( CvBGCodeBookModel* model, int staleThresh,
3492                                    CvRect roi CV_DEFAULT(cvRect(0,0,0,0)),
3493                                    const CvArr* mask CV_DEFAULT(0) );
3494
3495 CVAPI(CvSeq*) cvSegmentFGMask( CvArr *fgmask, int poly1Hull0 CV_DEFAULT(1),
3496                               float perimScale CV_DEFAULT(4.f),
3497                               CvMemStorage* storage CV_DEFAULT(0),
3498                               CvPoint offset CV_DEFAULT(cvPoint(0,0)));
3499
3500 #ifdef __cplusplus
3501 }
3502 #endif
3503
3504 #endif
3505
3506 /* End of file. */