]> rtime.felk.cvut.cz Git - opencv.git/blob - opencv/include/opencv/cv.hpp
added grabcut demo; fixed grabCut()
[opencv.git] / opencv / include / opencv / cv.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 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #ifndef _CV_HPP_
44 #define _CV_HPP_
45
46 #ifdef __cplusplus
47
48 namespace cv
49 {
50
51 enum { BORDER_REPLICATE=IPL_BORDER_REPLICATE, BORDER_CONSTANT=IPL_BORDER_CONSTANT,
52        BORDER_REFLECT=IPL_BORDER_REFLECT, BORDER_REFLECT_101=IPL_BORDER_REFLECT_101,
53        BORDER_REFLECT101=BORDER_REFLECT_101, BORDER_WRAP=IPL_BORDER_WRAP,
54        BORDER_TRANSPARENT, BORDER_DEFAULT=BORDER_REFLECT_101, BORDER_ISOLATED=16 };
55
56 CV_EXPORTS int borderInterpolate( int p, int len, int borderType );
57
58 class CV_EXPORTS BaseRowFilter
59 {
60 public:
61     BaseRowFilter();
62     virtual ~BaseRowFilter();
63     virtual void operator()(const uchar* src, uchar* dst,
64                             int width, int cn) = 0;
65     int ksize, anchor;
66 };
67
68
69 class CV_EXPORTS BaseColumnFilter
70 {
71 public:
72     BaseColumnFilter();
73     virtual ~BaseColumnFilter();
74     virtual void operator()(const uchar** src, uchar* dst, int dststep,
75                             int dstcount, int width) = 0;
76     virtual void reset();
77     int ksize, anchor;
78 };
79
80
81 class CV_EXPORTS BaseFilter
82 {
83 public:
84     BaseFilter();
85     virtual ~BaseFilter();
86     virtual void operator()(const uchar** src, uchar* dst, int dststep,
87                             int dstcount, int width, int cn) = 0;
88     virtual void reset();
89     Size ksize;
90     Point anchor;
91 };
92
93
94 class CV_EXPORTS FilterEngine
95 {
96 public:
97     FilterEngine();
98     FilterEngine(const Ptr<BaseFilter>& _filter2D,
99                  const Ptr<BaseRowFilter>& _rowFilter,
100                  const Ptr<BaseColumnFilter>& _columnFilter,
101                  int srcType, int dstType, int bufType,
102                  int _rowBorderType=BORDER_REPLICATE,
103                  int _columnBorderType=-1,
104                  const Scalar& _borderValue=Scalar());
105     virtual ~FilterEngine();
106     void init(const Ptr<BaseFilter>& _filter2D,
107               const Ptr<BaseRowFilter>& _rowFilter,
108               const Ptr<BaseColumnFilter>& _columnFilter,
109               int srcType, int dstType, int bufType,
110               int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1,
111               const Scalar& _borderValue=Scalar());
112     virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1);
113     virtual int start(const Mat& src, const Rect& srcRoi=Rect(0,0,-1,-1),
114                       bool isolated=false, int maxBufRows=-1);
115     virtual int proceed(const uchar* src, int srcStep, int srcCount,
116                         uchar* dst, int dstStep);
117     virtual void apply( const Mat& src, Mat& dst,
118                         const Rect& srcRoi=Rect(0,0,-1,-1),
119                         Point dstOfs=Point(0,0),
120                         bool isolated=false);
121     bool isSeparable() const { return (const BaseFilter*)filter2D == 0; }
122     int remainingInputRows() const;
123     int remainingOutputRows() const;
124     
125     int srcType, dstType, bufType;
126     Size ksize;
127     Point anchor;
128     int maxWidth;
129     Size wholeSize;
130     Rect roi;
131     int dx1, dx2;
132     int rowBorderType, columnBorderType;
133     vector<int> borderTab;
134     int borderElemSize;
135     vector<uchar> ringBuf;
136     vector<uchar> srcRow;
137     vector<uchar> constBorderValue;
138     vector<uchar> constBorderRow;
139     int bufStep, startY, startY0, endY, rowCount, dstY;
140     vector<uchar*> rows;
141     
142     Ptr<BaseFilter> filter2D;
143     Ptr<BaseRowFilter> rowFilter;
144     Ptr<BaseColumnFilter> columnFilter;
145 };
146
147 enum { KERNEL_GENERAL=0, KERNEL_SYMMETRICAL=1, KERNEL_ASYMMETRICAL=2,
148        KERNEL_SMOOTH=4, KERNEL_INTEGER=8 };
149
150 CV_EXPORTS int getKernelType(const Mat& kernel, Point anchor);
151
152 CV_EXPORTS Ptr<BaseRowFilter> getLinearRowFilter(int srcType, int bufType,
153                                             const Mat& kernel, int anchor,
154                                             int symmetryType);
155
156 CV_EXPORTS Ptr<BaseColumnFilter> getLinearColumnFilter(int bufType, int dstType,
157                                             const Mat& kernel, int anchor,
158                                             int symmetryType, double delta=0,
159                                             int bits=0);
160
161 CV_EXPORTS Ptr<BaseFilter> getLinearFilter(int srcType, int dstType,
162                                            const Mat& kernel,
163                                            Point anchor=Point(-1,-1),
164                                            double delta=0, int bits=0);
165
166 CV_EXPORTS Ptr<FilterEngine> createSeparableLinearFilter(int srcType, int dstType,
167                           const Mat& rowKernel, const Mat& columnKernel,
168                           Point _anchor=Point(-1,-1), double delta=0,
169                           int _rowBorderType=BORDER_DEFAULT,
170                           int _columnBorderType=-1,
171                           const Scalar& _borderValue=Scalar());
172
173 CV_EXPORTS Ptr<FilterEngine> createLinearFilter(int srcType, int dstType,
174                  const Mat& kernel, Point _anchor=Point(-1,-1),
175                  double delta=0, int _rowBorderType=BORDER_DEFAULT,
176                  int _columnBorderType=-1, const Scalar& _borderValue=Scalar());
177
178 CV_EXPORTS Mat getGaussianKernel( int ksize, double sigma, int ktype=CV_64F );
179
180 CV_EXPORTS Ptr<FilterEngine> createGaussianFilter( int type, Size ksize,
181                                     double sigma1, double sigma2=0,
182                                     int borderType=BORDER_DEFAULT);
183
184 CV_EXPORTS void getDerivKernels( Mat& kx, Mat& ky, int dx, int dy, int ksize,
185                                  bool normalize=false, int ktype=CV_32F );
186
187 CV_EXPORTS Ptr<FilterEngine> createDerivFilter( int srcType, int dstType,
188                                         int dx, int dy, int ksize,
189                                         int borderType=BORDER_DEFAULT );
190
191 CV_EXPORTS Ptr<BaseRowFilter> getRowSumFilter(int srcType, int sumType,
192                                                  int ksize, int anchor=-1);
193 CV_EXPORTS Ptr<BaseColumnFilter> getColumnSumFilter(int sumType, int dstType,
194                                                        int ksize, int anchor=-1,
195                                                        double scale=1);
196 CV_EXPORTS Ptr<FilterEngine> createBoxFilter( int srcType, int dstType, Size ksize,
197                                                  Point anchor=Point(-1,-1),
198                                                  bool normalize=true,
199                                                  int borderType=BORDER_DEFAULT);
200
201 enum { MORPH_ERODE=0, MORPH_DILATE=1, MORPH_OPEN=2, MORPH_CLOSE=3,
202        MORPH_GRADIENT=4, MORPH_TOPHAT=5, MORPH_BLACKHAT=6 };
203
204 CV_EXPORTS Ptr<BaseRowFilter> getMorphologyRowFilter(int op, int type, int ksize, int anchor=-1);
205 CV_EXPORTS Ptr<BaseColumnFilter> getMorphologyColumnFilter(int op, int type, int ksize, int anchor=-1);
206 CV_EXPORTS Ptr<BaseFilter> getMorphologyFilter(int op, int type, const Mat& kernel,
207                                                Point anchor=Point(-1,-1));
208
209 static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); }
210
211 CV_EXPORTS Ptr<FilterEngine> createMorphologyFilter(int op, int type, const Mat& kernel,
212                     Point anchor=Point(-1,-1), int _rowBorderType=BORDER_CONSTANT,
213                     int _columnBorderType=-1,
214                     const Scalar& _borderValue=morphologyDefaultBorderValue());
215
216 enum { MORPH_RECT=0, MORPH_CROSS=1, MORPH_ELLIPSE=2 };
217 CV_EXPORTS Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
218
219 CV_EXPORTS void copyMakeBorder( const Mat& src, Mat& dst,
220                                 int top, int bottom, int left, int right,
221                                 int borderType, const Scalar& value=Scalar() );
222
223 CV_EXPORTS void medianBlur( const Mat& src, Mat& dst, int ksize );
224 CV_EXPORTS void GaussianBlur( const Mat& src, Mat& dst, Size ksize,
225                               double sigma1, double sigma2=0,
226                               int borderType=BORDER_DEFAULT );
227 CV_EXPORTS void bilateralFilter( const Mat& src, Mat& dst, int d,
228                                  double sigmaColor, double sigmaSpace,
229                                  int borderType=BORDER_DEFAULT );
230 CV_EXPORTS void boxFilter( const Mat& src, Mat& dst, int ddepth,
231                            Size ksize, Point anchor=Point(-1,-1),
232                            bool normalize=true,
233                            int borderType=BORDER_DEFAULT );
234 static inline void blur( const Mat& src, Mat& dst,
235                          Size ksize, Point anchor=Point(-1,-1),
236                          int borderType=BORDER_DEFAULT )
237 {
238     boxFilter( src, dst, -1, ksize, anchor, true, borderType );
239 }
240
241 CV_EXPORTS void filter2D( const Mat& src, Mat& dst, int ddepth,
242                           const Mat& kernel, Point anchor=Point(-1,-1),
243                           double delta=0, int borderType=BORDER_DEFAULT );
244
245 CV_EXPORTS void sepFilter2D( const Mat& src, Mat& dst, int ddepth,
246                              const Mat& kernelX, const Mat& kernelY,
247                              Point anchor=Point(-1,-1),
248                              double delta=0, int borderType=BORDER_DEFAULT );
249
250 CV_EXPORTS void Sobel( const Mat& src, Mat& dst, int ddepth,
251                        int dx, int dy, int ksize=3,
252                        double scale=1, double delta=0,
253                        int borderType=BORDER_DEFAULT );
254
255 CV_EXPORTS void Scharr( const Mat& src, Mat& dst, int ddepth,
256                         int dx, int dy, double scale=1, double delta=0,
257                         int borderType=BORDER_DEFAULT );
258
259 CV_EXPORTS void Laplacian( const Mat& src, Mat& dst, int ddepth,
260                            int ksize=1, double scale=1, double delta=0,
261                            int borderType=BORDER_DEFAULT );
262
263 CV_EXPORTS void Canny( const Mat& image, Mat& edges,
264                        double threshold1, double threshold2,
265                        int apertureSize=3, bool L2gradient=false );
266
267 CV_EXPORTS void cornerMinEigenVal( const Mat& src, Mat& dst,
268                                    int blockSize, int ksize=3,
269                                    int borderType=BORDER_DEFAULT );
270
271 CV_EXPORTS void cornerHarris( const Mat& src, Mat& dst, int blockSize,
272                               int ksize, double k,
273                               int borderType=BORDER_DEFAULT );
274
275 CV_EXPORTS void cornerEigenValsAndVecs( const Mat& src, Mat& dst,
276                                         int blockSize, int ksize,
277                                         int borderType=BORDER_DEFAULT );
278
279 CV_EXPORTS void preCornerDetect( const Mat& src, Mat& dst, int ksize,
280                                  int borderType=BORDER_DEFAULT );
281
282 CV_EXPORTS void cornerSubPix( const Mat& image, vector<Point2f>& corners,
283                               Size winSize, Size zeroZone,
284                               TermCriteria criteria );
285
286 CV_EXPORTS void goodFeaturesToTrack( const Mat& image, vector<Point2f>& corners,
287                                      int maxCorners, double qualityLevel, double minDistance,
288                                      const Mat& mask=Mat(), int blockSize=3,
289                                      bool useHarrisDetector=false, double k=0.04 );
290
291 CV_EXPORTS void HoughLines( const Mat& image, vector<Vec2f>& lines,
292                             double rho, double theta, int threshold,
293                             double srn=0, double stn=0 );
294
295 CV_EXPORTS void HoughLinesP( Mat& image, vector<Vec4i>& lines,
296                              double rho, double theta, int threshold,
297                              double minLineLength=0, double maxLineGap=0 );
298
299 CV_EXPORTS void HoughCircles( const Mat& image, vector<Vec3f>& circles,
300                               int method, double dp, double minDist,
301                               double param1=100, double param2=100,
302                               int minRadius=0, int maxRadius=0 );
303
304 CV_EXPORTS void erode( const Mat& src, Mat& dst, const Mat& kernel,
305                        Point anchor=Point(-1,-1), int iterations=1,
306                        int borderType=BORDER_CONSTANT,
307                        const Scalar& borderValue=morphologyDefaultBorderValue() );
308 CV_EXPORTS void dilate( const Mat& src, Mat& dst, const Mat& kernel,
309                         Point anchor=Point(-1,-1), int iterations=1,
310                         int borderType=BORDER_CONSTANT,
311                         const Scalar& borderValue=morphologyDefaultBorderValue() );
312 CV_EXPORTS void morphologyEx( const Mat& src, Mat& dst, int op, const Mat& kernel,
313                               Point anchor=Point(-1,-1), int iterations=1,
314                               int borderType=BORDER_CONSTANT,
315                               const Scalar& borderValue=morphologyDefaultBorderValue() );
316
317 enum { INTER_NEAREST=0, INTER_LINEAR=1, INTER_CUBIC=2, INTER_AREA=3,
318        INTER_LANCZOS4=4, INTER_MAX=7, WARP_INVERSE_MAP=16 };
319
320 CV_EXPORTS void resize( const Mat& src, Mat& dst,
321                         Size dsize=Size(), double fx=0, double fy=0,
322                         int interpolation=INTER_LINEAR );
323
324 CV_EXPORTS void warpAffine( const Mat& src, Mat& dst,
325                             const Mat& M, Size dsize,
326                             int flags=INTER_LINEAR,
327                             int borderMode=BORDER_CONSTANT,
328                             const Scalar& borderValue=Scalar());
329 CV_EXPORTS void warpPerspective( const Mat& src, Mat& dst,
330                                  const Mat& M, Size dsize,
331                                  int flags=INTER_LINEAR,
332                                  int borderMode=BORDER_CONSTANT,
333                                  const Scalar& borderValue=Scalar());
334
335 CV_EXPORTS void remap( const Mat& src, Mat& dst, const Mat& map1, const Mat& map2,
336                        int interpolation, int borderMode=BORDER_CONSTANT,
337                        const Scalar& borderValue=Scalar());
338
339 CV_EXPORTS void convertMaps( const Mat& map1, const Mat& map2, Mat& dstmap1, Mat& dstmap2,
340                              int dstmap1type, bool nninterpolation=false );
341
342 CV_EXPORTS Mat getRotationMatrix2D( Point2f center, double angle, double scale );
343 CV_EXPORTS Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] );
344 CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
345 CV_EXPORTS void invertAffineTransform(const Mat& M, Mat& iM);
346
347 CV_EXPORTS void getRectSubPix( const Mat& image, Size patchSize,
348                                Point2f center, Mat& patch, int patchType=-1 );
349
350 CV_EXPORTS void integral( const Mat& src, Mat& sum, int sdepth=-1 );
351 CV_EXPORTS void integral( const Mat& src, Mat& sum, Mat& sqsum, int sdepth=-1 );
352 CV_EXPORTS void integral( const Mat& src, Mat& sum, Mat& sqsum, Mat& tilted, int sdepth=-1 );
353
354 CV_EXPORTS void accumulate( const Mat& src, Mat& dst, const Mat& mask=Mat() );
355 CV_EXPORTS void accumulateSquare( const Mat& src, Mat& dst, const Mat& mask=Mat() );
356 CV_EXPORTS void accumulateProduct( const Mat& src1, const Mat& src2,
357                                    Mat& dst, const Mat& mask=Mat() );
358 CV_EXPORTS void accumulateWeighted( const Mat& src, Mat& dst,
359                                     double alpha, const Mat& mask=Mat() );
360
361 enum { THRESH_BINARY=0, THRESH_BINARY_INV=1, THRESH_TRUNC=2, THRESH_TOZERO=3,
362        THRESH_TOZERO_INV=4, THRESH_MASK=7, THRESH_OTSU=8 };
363
364 CV_EXPORTS double threshold( const Mat& src, Mat& dst, double thresh, double maxval, int type );
365
366 enum { ADAPTIVE_THRESH_MEAN_C=0, ADAPTIVE_THRESH_GAUSSIAN_C=1 };
367
368 CV_EXPORTS void adaptiveThreshold( const Mat& src, Mat& dst, double maxValue,
369                                    int adaptiveMethod, int thresholdType,
370                                    int blockSize, double C );
371
372 CV_EXPORTS void pyrDown( const Mat& src, Mat& dst, const Size& dstsize=Size());
373 CV_EXPORTS void pyrUp( const Mat& src, Mat& dst, const Size& dstsize=Size());
374 CV_EXPORTS void buildPyramid( const Mat& src, vector<Mat>& dst, int maxlevel );
375
376
377 CV_EXPORTS void undistort( const Mat& src, Mat& dst, const Mat& cameraMatrix,
378                            const Mat& distCoeffs, const Mat& newCameraMatrix=Mat() );
379 CV_EXPORTS void initUndistortRectifyMap( const Mat& cameraMatrix, const Mat& distCoeffs,
380                            const Mat& R, const Mat& newCameraMatrix,
381                            Size size, int m1type, Mat& map1, Mat& map2 );
382 CV_EXPORTS Mat getDefaultNewCameraMatrix( const Mat& cameraMatrix, Size imgsize=Size(),
383                                           bool centerPrincipalPoint=false );
384
385 enum { OPTFLOW_USE_INITIAL_FLOW=4, OPTFLOW_FARNEBACK_GAUSSIAN=256 };
386
387 CV_EXPORTS void calcOpticalFlowPyrLK( const Mat& prevImg, const Mat& nextImg,
388                            const vector<Point2f>& prevPts, vector<Point2f>& nextPts,
389                            vector<uchar>& status, vector<float>& err,
390                            Size winSize=Size(15,15), int maxLevel=3,
391                            TermCriteria criteria=TermCriteria(
392                             TermCriteria::COUNT+TermCriteria::EPS,
393                             30, 0.01),
394                            double derivLambda=0.5,
395                            int flags=0 );
396
397 CV_EXPORTS void calcOpticalFlowFarneback( const Mat& prev0, const Mat& next0,
398                                Mat& flow0, double pyr_scale, int levels, int winsize,
399                                int iterations, int poly_n, double poly_sigma, int flags );
400     
401
402 template<> inline void Ptr<CvHistogram>::delete_obj()
403 { cvReleaseHist(&obj); }
404     
405 CV_EXPORTS void calcHist( const Mat* images, int nimages,
406                           const int* channels, const Mat& mask,
407                           MatND& hist, int dims, const int* histSize,
408                           const float** ranges, bool uniform=true,
409                           bool accumulate=false );
410
411 CV_EXPORTS void calcHist( const Mat* images, int nimages,
412                           const int* channels, const Mat& mask,
413                           SparseMat& hist, int dims, const int* histSize,
414                           const float** ranges, bool uniform=true,
415                           bool accumulate=false );
416     
417 CV_EXPORTS void calcBackProject( const Mat* images, int nimages,
418                                  const int* channels, const MatND& hist,
419                                  Mat& backProject, const float** ranges,
420                                  double scale=1, bool uniform=true );
421     
422 CV_EXPORTS void calcBackProject( const Mat* images, int nimages,
423                                  const int* channels, const SparseMat& hist,
424                                  Mat& backProject, const float** ranges,
425                                  double scale=1, bool uniform=true );
426
427 CV_EXPORTS double compareHist( const MatND& H1, const MatND& H2, int method );
428
429 CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method );
430
431 CV_EXPORTS void equalizeHist( const Mat& src, Mat& dst );
432
433 CV_EXPORTS void watershed( const Mat& image, Mat& markers );
434
435 enum { GC_BGD    = 0,  // background
436        GC_FGD    = 1,  // foreground
437        GC_PR_BGD = 2,  // most probably background
438        GC_PR_FGD = 3   // most probably foreground 
439      };
440
441 enum { GC_INIT_WITH_RECT  = 0,
442        GC_INIT_WITH_MASK  = 1,
443        GC_EVAL            = 2
444      };
445
446 CV_EXPORTS void grabCut( const Mat& img, Mat& mask, Rect rect, 
447                          Mat& bgdModel, Mat& fgdModel,
448                          int iterCount, int flag = GC_EVAL );
449
450 enum { INPAINT_NS=CV_INPAINT_NS, INPAINT_TELEA=CV_INPAINT_TELEA };
451
452 CV_EXPORTS void inpaint( const Mat& src, const Mat& inpaintMask,
453                          Mat& dst, double inpaintRange, int flags );
454
455 CV_EXPORTS void distanceTransform( const Mat& src, Mat& dst, Mat& labels,
456                                    int distanceType, int maskSize );
457
458 CV_EXPORTS void distanceTransform( const Mat& src, Mat& dst,
459                                    int distanceType, int maskSize );
460
461 enum { FLOODFILL_FIXED_RANGE = 1 << 16,
462        FLOODFILL_MASK_ONLY = 1 << 17 };
463
464 CV_EXPORTS int floodFill( Mat& image,
465                           Point seedPoint, Scalar newVal, Rect* rect=0,
466                           Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),
467                           int flags=4 );
468
469 CV_EXPORTS int floodFill( Mat& image, Mat& mask,
470                           Point seedPoint, Scalar newVal, Rect* rect=0,
471                           Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),
472                           int flags=4 );
473
474 CV_EXPORTS void cvtColor( const Mat& src, Mat& dst, int code, int dstCn=0 );
475
476 class CV_EXPORTS Moments
477 {
478 public:
479     Moments();
480     Moments(double m00, double m10, double m01, double m20, double m11,
481             double m02, double m30, double m21, double m12, double m03 );
482     Moments( const CvMoments& moments );
483     operator CvMoments() const;
484     
485     double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; // spatial moments
486     double  mu20, mu11, mu02, mu30, mu21, mu12, mu03; // central moments
487     double  nu20, nu11, nu02, nu30, nu21, nu12, nu03; // central normalized moments
488 };
489
490 CV_EXPORTS Moments moments( const Mat& array, bool binaryImage=false );
491
492 CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
493
494 enum { TM_SQDIFF=CV_TM_SQDIFF, TM_SQDIFF_NORMED=CV_TM_SQDIFF_NORMED,
495        TM_CCORR=CV_TM_CCORR, TM_CCORR_NORMED=CV_TM_CCORR_NORMED,
496        TM_CCOEFF=CV_TM_CCOEFF, TM_CCOEFF_NORMED=CV_TM_CCOEFF_NORMED };
497
498 CV_EXPORTS void matchTemplate( const Mat& image, const Mat& templ, Mat& result, int method );
499
500 enum { RETR_EXTERNAL=CV_RETR_EXTERNAL, RETR_LIST=CV_RETR_LIST,
501        RETR_CCOMP=CV_RETR_CCOMP, RETR_TREE=CV_RETR_TREE };
502
503 enum { CHAIN_APPROX_NONE=CV_CHAIN_APPROX_NONE,
504        CHAIN_APPROX_SIMPLE=CV_CHAIN_APPROX_SIMPLE,
505        CHAIN_APPROX_TC89_L1=CV_CHAIN_APPROX_TC89_L1,
506        CHAIN_APPROX_TC89_KCOS=CV_CHAIN_APPROX_TC89_KCOS };
507
508 CV_EXPORTS void findContours( const Mat& image, vector<vector<Point> >& contours,
509                               vector<Vec4i>& hierarchy, int mode,
510                               int method, Point offset=Point());
511
512 CV_EXPORTS void findContours( const Mat& image, vector<vector<Point> >& contours,
513                               int mode, int method, Point offset=Point());
514
515 CV_EXPORTS void drawContours( Mat& image, const vector<vector<Point> >& contours,
516                               int contourIdx, const Scalar& color,
517                               int thickness=1, int lineType=8,
518                               const vector<Vec4i>& hierarchy=vector<Vec4i>(),
519                               int maxLevel=INT_MAX, Point offset=Point() );
520
521 CV_EXPORTS void approxPolyDP( const Mat& curve,
522                               vector<Point>& approxCurve,
523                               double epsilon, bool closed );
524 CV_EXPORTS void approxPolyDP( const Mat& curve,
525                               vector<Point2f>& approxCurve,
526                               double epsilon, bool closed );
527     
528 CV_EXPORTS double arcLength( const Mat& curve, bool closed );
529 CV_EXPORTS Rect boundingRect( const Mat& points );
530 CV_EXPORTS double contourArea( const Mat& contour );    
531 CV_EXPORTS RotatedRect minAreaRect( const Mat& points );
532 CV_EXPORTS void minEnclosingCircle( const Mat& points,
533                                     Point2f& center, float& radius );    
534 CV_EXPORTS double matchShapes( const Mat& contour1,
535                                const Mat& contour2,
536                                int method, double parameter );
537     
538 CV_EXPORTS void convexHull( const Mat& points, vector<int>& hull, bool clockwise=false );
539 CV_EXPORTS void convexHull( const Mat& points, vector<Point>& hull, bool clockwise=false );
540 CV_EXPORTS void convexHull( const Mat& points, vector<Point2f>& hull, bool clockwise=false );
541
542 CV_EXPORTS bool isContourConvex( const Mat& contour );
543
544 CV_EXPORTS RotatedRect fitEllipse( const Mat& points );
545
546 CV_EXPORTS void fitLine( const Mat& points, Vec4f& line, int distType,
547                          double param, double reps, double aeps );
548 CV_EXPORTS void fitLine( const Mat& points, Vec6f& line, int distType,
549                          double param, double reps, double aeps );
550
551 CV_EXPORTS double pointPolygonTest( const Mat& contour,
552                                     Point2f pt, bool measureDist );
553
554 CV_EXPORTS Mat estimateRigidTransform( const Mat& A, const Mat& B,
555                                        bool fullAffine );
556
557 CV_EXPORTS void updateMotionHistory( const Mat& silhouette, Mat& mhi,
558                                      double timestamp, double duration );
559
560 CV_EXPORTS void calcMotionGradient( const Mat& mhi, Mat& mask,
561                                     Mat& orientation,
562                                     double delta1, double delta2,
563                                     int apertureSize=3 );
564
565 CV_EXPORTS double calcGlobalOrientation( const Mat& orientation, const Mat& mask,
566                                          const Mat& mhi, double timestamp,
567                                          double duration );
568 // TODO: need good API for cvSegmentMotion
569
570 CV_EXPORTS RotatedRect CamShift( const Mat& probImage, Rect& window,
571                                  TermCriteria criteria );
572
573 CV_EXPORTS int meanShift( const Mat& probImage, Rect& window,
574                           TermCriteria criteria );
575
576 CV_EXPORTS int estimateAffine3D(const Mat& from, const Mat& to, Mat& out,
577                                 vector<uchar>& outliers,
578                                 double param1 = 3.0, double param2 = 0.99);
579
580 class CV_EXPORTS KalmanFilter
581 {
582 public:
583     KalmanFilter();
584     KalmanFilter(int dynamParams, int measureParams, int controlParams=0);
585     void init(int dynamParams, int measureParams, int controlParams=0);
586
587     const Mat& predict(const Mat& control=Mat());
588     const Mat& correct(const Mat& measurement);
589
590     Mat statePre;           // predicted state (x'(k)):
591                             //    x(k)=A*x(k-1)+B*u(k)
592     Mat statePost;          // corrected state (x(k)):
593                             //    x(k)=x'(k)+K(k)*(z(k)-H*x'(k))
594     Mat transitionMatrix;   // state transition matrix (A)
595     Mat controlMatrix;      // control matrix (B)
596                             //   (it is not used if there is no control)
597     Mat measurementMatrix;  // measurement matrix (H)
598     Mat processNoiseCov;    // process noise covariance matrix (Q)
599     Mat measurementNoiseCov;// measurement noise covariance matrix (R)
600     Mat errorCovPre;        // priori error estimate covariance matrix (P'(k)):
601                             //    P'(k)=A*P(k-1)*At + Q)*/
602     Mat gain;               // Kalman gain matrix (K(k)):
603                             //    K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)
604     Mat errorCovPost;       // posteriori error estimate covariance matrix (P(k)):
605                             //    P(k)=(I-K(k)*H)*P'(k)
606     Mat temp1;              // temporary matrices
607     Mat temp2;
608     Mat temp3;
609     Mat temp4;
610     Mat temp5;
611 };
612
613
614 ///////////////////////////// Object Detection ////////////////////////////
615
616 CV_EXPORTS void groupRectangles(vector<Rect>& rectList, int groupThreshold, double eps=0.2);
617         
618 class CV_EXPORTS FeatureEvaluator
619 {
620 public:    
621     enum { HAAR = 0, LBP = 1 };
622     virtual ~FeatureEvaluator();
623     virtual bool read(const FileNode& node);
624     virtual Ptr<FeatureEvaluator> clone() const;
625     virtual int getFeatureType() const;
626     
627     virtual bool setImage(const Mat&, Size origWinSize);
628     virtual bool setWindow(Point p);
629
630     virtual double calcOrd(int featureIdx) const;
631     virtual int calcCat(int featureIdx) const;
632
633     static Ptr<FeatureEvaluator> create(int type);
634 };
635     
636 template<> inline void Ptr<CvHaarClassifierCascade>::delete_obj()
637 { cvReleaseHaarClassifierCascade(&obj); }    
638    
639 class CV_EXPORTS CascadeClassifier
640 {
641 public:
642     struct CV_EXPORTS DTreeNode
643     {
644         int featureIdx;
645         float threshold; // for ordered features only
646         int left;
647         int right;
648     };
649     
650     struct CV_EXPORTS DTree
651     {
652         int nodeCount;
653     };
654     
655     struct CV_EXPORTS Stage
656     {
657         int first;
658         int ntrees;
659         float threshold;
660     };
661     
662     enum { BOOST = 0 };
663     enum { DO_CANNY_PRUNING = CV_HAAR_DO_CANNY_PRUNING,
664            SCALE_IMAGE = CV_HAAR_SCALE_IMAGE,
665            FIND_BIGGEST_OBJECT = CV_HAAR_FIND_BIGGEST_OBJECT,
666            DO_ROUGH_SEARCH = CV_HAAR_DO_ROUGH_SEARCH };
667
668     CascadeClassifier();
669     CascadeClassifier(const string& filename);
670     ~CascadeClassifier();
671     
672     bool empty() const;
673     bool load(const string& filename);
674     bool read(const FileNode& node);
675     void detectMultiScale( const Mat& image,
676                            vector<Rect>& objects,
677                            double scaleFactor=1.1,
678                            int minNeighbors=3, int flags=0,
679                            Size minSize=Size());
680  
681     bool setImage( Ptr<FeatureEvaluator>&, const Mat& );
682     int runAt( Ptr<FeatureEvaluator>&, Point );
683
684     bool is_stump_based;
685
686     int stageType;
687     int featureType;
688     int ncategories;
689     Size origWinSize;
690     
691     vector<Stage> stages;
692     vector<DTree> classifiers;
693     vector<DTreeNode> nodes;
694     vector<float> leaves;
695     vector<int> subsets;
696
697     Ptr<FeatureEvaluator> feval;
698     Ptr<CvHaarClassifierCascade> oldCascade;
699 };
700
701     
702 CV_EXPORTS void undistortPoints( const Mat& src, vector<Point2f>& dst,
703                                  const Mat& cameraMatrix, const Mat& distCoeffs,
704                                  const Mat& R=Mat(), const Mat& P=Mat());
705 CV_EXPORTS void undistortPoints( const Mat& src, Mat& dst,
706                                  const Mat& cameraMatrix, const Mat& distCoeffs,
707                                  const Mat& R=Mat(), const Mat& P=Mat());
708
709 CV_EXPORTS void Rodrigues(const Mat& src, Mat& dst);
710 CV_EXPORTS void Rodrigues(const Mat& src, Mat& dst, Mat& jacobian);
711
712 enum { LMEDS=4, RANSAC=8 };
713
714 CV_EXPORTS Mat findHomography( const Mat& srcPoints,
715                                const Mat& dstPoints,
716                                Mat& mask, int method=0,
717                                double ransacReprojThreshold=0 );
718     
719 CV_EXPORTS Mat findHomography( const Mat& srcPoints,
720                                const Mat& dstPoints,
721                                vector<uchar>& mask, int method=0,
722                                double ransacReprojThreshold=0 );
723
724 CV_EXPORTS Mat findHomography( const Mat& srcPoints,
725                                const Mat& dstPoints,
726                                int method=0, double ransacReprojThreshold=0 );
727
728 /* Computes RQ decomposition for 3x3 matrices */
729 CV_EXPORTS void RQDecomp3x3( const Mat& M, Mat& R, Mat& Q );
730 CV_EXPORTS Vec3d RQDecomp3x3( const Mat& M, Mat& R, Mat& Q,
731                               Mat& Qx, Mat& Qy, Mat& Qz );
732
733 CV_EXPORTS void decomposeProjectionMatrix( const Mat& projMatrix, Mat& cameraMatrix,
734                                            Mat& rotMatrix, Mat& transVect );
735 CV_EXPORTS void decomposeProjectionMatrix( const Mat& projMatrix, Mat& cameraMatrix,
736                                            Mat& rotMatrix, Mat& transVect,
737                                            Mat& rotMatrixX, Mat& rotMatrixY,
738                                            Mat& rotMatrixZ, Vec3d& eulerAngles );
739
740 CV_EXPORTS void matMulDeriv( const Mat& A, const Mat& B, Mat& dABdA, Mat& dABdB );
741
742 CV_EXPORTS void composeRT( const Mat& rvec1, const Mat& tvec1,
743                            const Mat& rvec2, const Mat& tvec2,
744                            Mat& rvec3, Mat& tvec3 );
745
746 CV_EXPORTS void composeRT( const Mat& rvec1, const Mat& tvec1,
747                            const Mat& rvec2, const Mat& tvec2,
748                            Mat& rvec3, Mat& tvec3,
749                            Mat& dr3dr1, Mat& dr3dt1,
750                            Mat& dr3dr2, Mat& dr3dt2,
751                            Mat& dt3dr1, Mat& dt3dt1,
752                            Mat& dt3dr2, Mat& dt3dt2 );
753
754 CV_EXPORTS void projectPoints( const Mat& objectPoints,
755                                const Mat& rvec, const Mat& tvec,
756                                const Mat& cameraMatrix,
757                                const Mat& distCoeffs,
758                                vector<Point2f>& imagePoints );
759
760 CV_EXPORTS void projectPoints( const Mat& objectPoints,
761                                const Mat& rvec, const Mat& tvec,
762                                const Mat& cameraMatrix,
763                                const Mat& distCoeffs,
764                                vector<Point2f>& imagePoints,
765                                Mat& dpdrot, Mat& dpdt, Mat& dpdf,
766                                Mat& dpdc, Mat& dpddist,
767                                double aspectRatio=0 );
768
769 CV_EXPORTS void solvePnP( const Mat& objectPoints,
770                           const Mat& imagePoints,
771                           const Mat& cameraMatrix,
772                           const Mat& distCoeffs,
773                           Mat& rvec, Mat& tvec,
774                           bool useExtrinsicGuess=false );
775
776 CV_EXPORTS Mat initCameraMatrix2D( const vector<vector<Point3f> >& objectPoints,
777                                    const vector<vector<Point2f> >& imagePoints,
778                                    Size imageSize, double aspectRatio=1. );
779
780 enum { CALIB_CB_ADAPTIVE_THRESH = CV_CALIB_CB_ADAPTIVE_THRESH,
781        CALIB_CB_NORMALIZE_IMAGE = CV_CALIB_CB_NORMALIZE_IMAGE,
782        CALIB_CB_FILTER_QUADS = CV_CALIB_CB_FILTER_QUADS };
783
784 CV_EXPORTS bool findChessboardCorners( const Mat& image, Size patternSize,
785                                        vector<Point2f>& corners,
786                                        int flags=CV_CALIB_CB_ADAPTIVE_THRESH+
787                                             CV_CALIB_CB_NORMALIZE_IMAGE );
788
789 CV_EXPORTS void drawChessboardCorners( Mat& image, Size patternSize,
790                                        const Mat& corners,
791                                        bool patternWasFound );
792
793 enum
794 {
795     CALIB_USE_INTRINSIC_GUESS = CV_CALIB_USE_INTRINSIC_GUESS,
796     CALIB_FIX_ASPECT_RATIO = CV_CALIB_FIX_ASPECT_RATIO,
797     CALIB_FIX_PRINCIPAL_POINT = CV_CALIB_FIX_PRINCIPAL_POINT,
798     CALIB_ZERO_TANGENT_DIST = CV_CALIB_ZERO_TANGENT_DIST,
799     CALIB_FIX_FOCAL_LENGTH = CV_CALIB_FIX_FOCAL_LENGTH,
800     CALIB_FIX_K1 = CV_CALIB_FIX_K1,
801     CALIB_FIX_K2 = CV_CALIB_FIX_K2,
802     CALIB_FIX_K3 = CV_CALIB_FIX_K3,
803     // only for stereo
804     CALIB_FIX_INTRINSIC = CV_CALIB_FIX_INTRINSIC,
805     CALIB_SAME_FOCAL_LENGTH = CV_CALIB_SAME_FOCAL_LENGTH,
806     // for stereo rectification
807     CALIB_ZERO_DISPARITY = CV_CALIB_ZERO_DISPARITY
808 };
809
810 CV_EXPORTS void calibrateCamera( const vector<vector<Point3f> >& objectPoints,
811                                  const vector<vector<Point2f> >& imagePoints,
812                                  Size imageSize,
813                                  Mat& cameraMatrix, Mat& distCoeffs,
814                                  vector<Mat>& rvecs, vector<Mat>& tvecs,
815                                  int flags=0 );
816
817 CV_EXPORTS void calibrationMatrixValues( const Mat& cameraMatrix,
818                                 Size imageSize,
819                                 double apertureWidth,
820                                 double apertureHeight,
821                                 double& fovx,
822                                 double& fovy,
823                                 double& focalLength,
824                                 Point2d& principalPoint,
825                                 double& aspectRatio );
826
827 CV_EXPORTS void stereoCalibrate( const vector<vector<Point3f> >& objectPoints,
828                                  const vector<vector<Point2f> >& imagePoints1,
829                                  const vector<vector<Point2f> >& imagePoints2,
830                                  Mat& cameraMatrix1, Mat& distCoeffs1,
831                                  Mat& cameraMatrix2, Mat& distCoeffs2,
832                                  Size imageSize, Mat& R, Mat& T,
833                                  Mat& E, Mat& F,
834                                  TermCriteria criteria = TermCriteria(TermCriteria::COUNT+
835                                     TermCriteria::EPS, 30, 1e-6),
836                                  int flags=CALIB_FIX_INTRINSIC );
837
838 CV_EXPORTS void stereoRectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
839                                const Mat& cameraMatrix2, const Mat& distCoeffs2,
840                                Size imageSize, const Mat& R, const Mat& T,
841                                Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
842                                int flags=CALIB_ZERO_DISPARITY );
843
844 CV_EXPORTS bool stereoRectifyUncalibrated( const Mat& points1,
845                                            const Mat& points2,
846                                            const Mat& F, Size imgSize,
847                                            Mat& H1, Mat& H2,
848                                            double threshold=5 );
849
850 CV_EXPORTS void convertPointsHomogeneous( const Mat& src, vector<Point3f>& dst );
851 CV_EXPORTS void convertPointsHomogeneous( const Mat& src, vector<Point2f>& dst );
852
853 enum
854
855     FM_7POINT = CV_FM_7POINT,
856     FM_8POINT = CV_FM_8POINT,
857     FM_LMEDS = CV_FM_LMEDS,
858     FM_RANSAC = CV_FM_RANSAC
859 };
860
861 CV_EXPORTS Mat findFundamentalMat( const Mat& points1, const Mat& points2,
862                                    vector<uchar>& mask, int method=FM_RANSAC,
863                                    double param1=3., double param2=0.99 );
864
865 CV_EXPORTS Mat findFundamentalMat( const Mat& points1, const Mat& points2,
866                                    int method=FM_RANSAC,
867                                    double param1=3., double param2=0.99 );
868
869 CV_EXPORTS void computeCorrespondEpilines( const Mat& points1,
870                                            int whichImage, const Mat& F,
871                                            vector<Vec3f>& lines );
872
873 template<> inline void Ptr<CvStereoBMState>::delete_obj()
874 { cvReleaseStereoBMState(&obj); }
875
876 // Block matching stereo correspondence algorithm
877 class CV_EXPORTS StereoBM
878 {
879 public:
880     enum { NORMALIZED_RESPONSE = CV_STEREO_BM_NORMALIZED_RESPONSE,
881         BASIC_PRESET=CV_STEREO_BM_BASIC,
882         FISH_EYE_PRESET=CV_STEREO_BM_FISH_EYE,
883         NARROW_PRESET=CV_STEREO_BM_NARROW };
884     
885     StereoBM();
886     StereoBM(int preset, int ndisparities=0, int SADWindowSize=21);
887     void init(int preset, int ndisparities=0, int SADWindowSize=21);
888     void operator()( const Mat& left, const Mat& right, Mat& disparity );
889
890     Ptr<CvStereoBMState> state;
891 };
892
893 CV_EXPORTS void reprojectImageTo3D( const Mat& disparity,
894                                     Mat& _3dImage, const Mat& Q,
895                                     bool handleMissingValues=false );
896
897 class CV_EXPORTS KeyPoint
898 {
899 public:    
900     KeyPoint() : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {}
901     KeyPoint(Point2f _pt, float _size, float _angle=-1,
902             float _response=0, int _octave=0, int _class_id=-1)
903             : pt(_pt), size(_size), angle(_angle),
904             response(_response), octave(_octave), class_id(_class_id) {}
905     KeyPoint(float x, float y, float _size, float _angle=-1,
906             float _response=0, int _octave=0, int _class_id=-1)
907             : pt(x, y), size(_size), angle(_angle),
908             response(_response), octave(_octave), class_id(_class_id) {}
909     
910     Point2f pt;
911     float size;
912     float angle;
913     float response;
914     int octave;
915     int class_id;
916 };
917
918 CV_EXPORTS void write(FileStorage& fs, const string& name, const vector<KeyPoint>& keypoints);
919 CV_EXPORTS void read(const FileNode& node, vector<KeyPoint>& keypoints);    
920
921 class CV_EXPORTS SURF : public CvSURFParams
922 {
923 public:
924     SURF();
925     SURF(double _hessianThreshold, int _nOctaves=4,
926          int _nOctaveLayers=2, bool _extended=false);
927
928     int descriptorSize() const;
929     void operator()(const Mat& img, const Mat& mask,
930                     vector<KeyPoint>& keypoints) const;
931     void operator()(const Mat& img, const Mat& mask,
932                     vector<KeyPoint>& keypoints,
933                     vector<float>& descriptors,
934                     bool useProvidedKeypoints=false) const;
935 };
936
937
938 class CV_EXPORTS MSER : public CvMSERParams
939 {
940 public:
941     MSER();
942     MSER( int _delta, int _min_area, int _max_area,
943           float _max_variation, float _min_diversity,
944           int _max_evolution, double _area_threshold,
945           double _min_margin, int _edge_blur_size );
946     void operator()(Mat& image, vector<vector<Point> >& msers, const Mat& mask) const;
947 };
948
949
950 class CV_EXPORTS StarDetector : CvStarDetectorParams
951 {
952 public:
953     StarDetector();
954     StarDetector(int _maxSize, int _responseThreshold,
955                  int _lineThresholdProjected,
956                  int _lineThresholdBinarized,
957                  int _suppressNonmaxSize);
958
959     void operator()(const Mat& image, vector<KeyPoint>& keypoints) const;
960 };
961     
962 }
963
964 //////////////////////////////////////////////////////////////////////////////////////////
965
966 class CV_EXPORTS CvLevMarq
967 {
968 public:
969     CvLevMarq();
970     CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria=
971         cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
972         bool completeSymmFlag=false );
973     ~CvLevMarq();
974     void init( int nparams, int nerrs, CvTermCriteria criteria=
975         cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
976         bool completeSymmFlag=false );
977     bool update( const CvMat*& param, CvMat*& J, CvMat*& err );
978     bool updateAlt( const CvMat*& param, CvMat*& JtJ, CvMat*& JtErr, double*& errNorm );
979
980     void clear();
981     void step();
982     enum { DONE=0, STARTED=1, CALC_J=2, CHECK_ERR=3 };
983
984     CvMat* mask;
985     CvMat* prevParam;
986     CvMat* param;
987     CvMat* J;
988     CvMat* err;
989     CvMat* JtJ;
990     CvMat* JtJN;
991     CvMat* JtErr;
992     CvMat* JtJV;
993     CvMat* JtJW;
994     double prevErrNorm, errNorm;
995     int lambdaLg10;
996     CvTermCriteria criteria;
997     int state;
998     int iters;
999     bool completeSymmFlag;
1000 };
1001
1002
1003 // 2009-01-12, Xavier Delacour <xavier.delacour@gmail.com>
1004
1005 struct lsh_hash {
1006   int h1, h2;
1007 };
1008
1009 struct CvLSHOperations
1010 {
1011   virtual ~CvLSHOperations() {}
1012
1013   virtual int vector_add(const void* data) = 0;
1014   virtual void vector_remove(int i) = 0;
1015   virtual const void* vector_lookup(int i) = 0;
1016   virtual void vector_reserve(int n) = 0;
1017   virtual unsigned int vector_count() = 0;
1018
1019   virtual void hash_insert(lsh_hash h, int l, int i) = 0;
1020   virtual void hash_remove(lsh_hash h, int l, int i) = 0;
1021   virtual int hash_lookup(lsh_hash h, int l, int* ret_i, int ret_i_max) = 0;
1022 };
1023
1024 #endif /* __cplusplus */
1025
1026 #endif /* _CV_HPP_ */
1027
1028 /* End of file. */