Move the sources to trunk
[opencv] / interfaces / matlab / src / wrappers.cpp
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 #define CV_MCALL( func ) func; \
43         if( cvGetErrStatus() != CV_StsOk ) \
44         { \
45                 OPENCV_RSTERR(); \
46                 throw_error( cvErrorMessage ); \
47         }
48
49 ///////////////////////////////////////////////////////////////////////////////
50 // IMAGE = dllname('PyrUp', IMAGE, NUMERIC filter_type);
51 //
52 WRAPPER (3, 1, wrPyrUp);
53 IMG_IN( 1,      src, ; );
54 NUM_IN( 2, int, filter );
55
56 IMG_OUT( 0, dst, 
57         PARAM( dst, size ).width  = PARAM( src, size ).width  * 2;
58         PARAM( dst, size ).height = PARAM( src, size ).height * 2;
59         PARAM( dst, channels )    = PARAM( src, channels );
60         PARAM( dst, class )       = PARAM( src, class ); );
61
62 CV_MCALL( cvPyrUp( (IplImage *)src, (IplImage *)dst, (CvFilter)filter ) );
63 PUT_IMG( dst );
64 RET
65                    
66 ///////////////////////////////////////////////////////////////////////////////
67 // IMAGE = dllname('PyrDown', IMAGE, NUMERIC filter_type);
68 //
69 WRAPPER (3, 1, wrPyrDown);      
70 IMG_IN( 1,      src, ; );
71 NUM_IN( 2, int, filter );
72
73 IMG_OUT( 0, dst, 
74         PARAM( dst, size ).width  = PARAM( src, size ).width  / 2;
75         PARAM( dst, size ).height = PARAM( src, size ).height / 2;
76         PARAM( dst, channels ) = PARAM( src, channels );
77         PARAM( dst, class )       = PARAM( src, class ); );
78
79 CV_MCALL( cvPyrDown( (IplImage *)src, (IplImage *)dst, (CvFilter)filter ) );
80 PUT_IMG( dst );
81 RET
82
83 ///////////////////////////////////////////////////////////////////////////////
84 // IMAGE = dllname('Laplace', IMAGE, NUMERIC);
85 //
86 WRAPPER (3, 1, wrLaplace);      
87 IMG_IN( 1,      src, ; );
88 NUM_IN( 2, int, apertureSize );
89
90 IMG_OUT( 0, dst, 
91         PARAM( dst, size )     = PARAM( src, size );
92         PARAM( dst, channels ) = PARAM( src, channels );
93         PARAM( dst, class )    = (( PARAM( src, class ) == mxSINGLE_CLASS ) ? 
94                 mxSINGLE_CLASS : mxINT16_CLASS); );
95
96 CV_MCALL( cvLaplace((IplImage *) src, (IplImage *) dst, apertureSize) );
97
98 PUT_IMG( dst );
99 RET
100
101 ///////////////////////////////////////////////////////////////////////////////
102 // IMAGE = dllname('Sobel', IMAGE, NUMERIC, NUMERIC, NUMERIC);
103 //
104 WRAPPER (5, 1, wrSobel);        
105 IMG_IN( 1,      src, ; );
106 NUM_IN( 2, int, xorder );
107 NUM_IN( 3, int, yorder );
108 NUM_IN( 4, int, apertureSize );
109
110 IMG_OUT( 0, dst, 
111         PARAM( dst, size )     = PARAM( src, size );
112         PARAM( dst, channels ) = PARAM( src, channels );
113         PARAM( dst, class )    = (( PARAM( src, class ) == mxSINGLE_CLASS ) ? 
114                 mxSINGLE_CLASS : mxINT16_CLASS); );
115
116 CV_MCALL( cvSobel( (IplImage *)src, (IplImage *)dst,
117                  yorder, xorder, apertureSize ) );
118 PUT_IMG( dst );
119 RET
120
121 ///////////////////////////////////////////////////////////////////////////////
122 // IMAGE = dllname( 'Erode', IMAGE src, 
123 //                  elementValues,// one of the predefined
124 //                                // structuring elements or
125 //                                // matrix for user-defined structuring element
126 //                  elementSize,  // [nRows, nCols, anchorRow, anchorCol] for
127 //                                // the predefined element or
128 //                                // [anchorRow, anchorCol] for
129 //                                // the user-defined element
130 //                  iterations );
131 //
132 WRAPPER( 5, 1, wrErode );
133 IMG_IN( 1, src, ; );
134 STRUCTELEM_IN( 2, 3, element, PARAM( element, allowEmpty ) = true; );
135 NUM_IN( 4, int, iterations );
136
137 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
138                                  PARAM( dst, channels ) = PARAM( src, channels );
139                                  PARAM( dst, class )    = PARAM( src, class ); );
140 CV_MCALL( cvErode( (IplImage *)src, (IplImage *)dst, (IplConvKernel *)element,
141                  iterations ) );
142 PUT_IMG( dst );
143 RET
144
145 ///////////////////////////////////////////////////////////////////////////////
146 // IMAGE = dllname( 'Dilate', IMAGE src, 
147 //                  elementValues,// one of the predefined
148 //                                // structuring elements or
149 //                                // matrix for user-defined structuring element
150 //                  elementSize,  // [nRows, nCols, anchorRow, anchorCol] for
151 //                                // the predefined element or
152 //                                // [anchorRow, anchorCol] for
153 //                                // the user-defined element
154 //                  iterations );
155 //
156 WRAPPER( 5, 1, wrDilate );      
157 IMG_IN( 1, src, ; );
158 STRUCTELEM_IN( 2, 3, element, PARAM( element, allowEmpty ) = true; );
159 NUM_IN( 4, int, iterations );
160
161 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
162                                  PARAM( dst, channels ) = PARAM( src, channels );
163                                  PARAM( dst, class )    = PARAM( src, class ); );
164 CV_MCALL( cvDilate( (IplImage *)src, (IplImage *)dst, (IplConvKernel *)element,
165                   iterations ) );
166 PUT_IMG( dst );
167 RET
168
169 ///////////////////////////////////////////////////////////////////////////////
170 // IMAGE dst = dllname( 'DistTransform', IMAGE src, 
171 //                   dist,    // [disType] or 
172 //                            // 1 by 2 (3) array of numbers that characterize
173 //                            // user-defined metric
174 //                   maskSize // ignored if metric is user-defined
175 //                );
176 //
177 WRAPPER (4, 1, wrDistTransform);        
178 IMG_IN(    1,        src, ; );
179 VECTOR_IN( 2, float, dist, -1, ; );
180
181 int        _maskSize = 0;
182 CvDisType disType  = CV_DIST_USER;
183 float     *mask     = 0;
184
185 if( PARAM( dist, num ) == 1 )
186 {
187         // predefined metric
188         NUM_IN( 3, int, maskSize );
189         _maskSize = maskSize;
190         disType  = (CvDisType)(int)dist[0];
191 }
192 else
193 {
194         // user-defined metric
195         switch( PARAM( dist, num ) )
196         {
197                 case 2: { _maskSize = 3; break; }
198                 case 3: { _maskSize = 5; break; }
199                 default: { throw_error( "Invalid parameter 'dist'." ); }
200         }
201         mask     = (float *)dist;
202 }
203
204 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
205                                  PARAM( dst, channels ) = PARAM( src, channels );
206                                  PARAM( dst, class )    = mxSINGLE_CLASS );
207 CV_MCALL( cvDistTransform( (IplImage *)src, (IplImage *)dst,
208                                  disType, _maskSize, mask ) );
209 PUT_IMG( dst );
210 RET
211
212 ///////////////////////////////////////////////////////////////////////////////
213 // IMAGE dst = dllname('Canny', IMAGE 8U src, DOUBLE low_thresh,
214 //                 DOUBLE high_thresh, INT aperture);
215 //
216 WRAPPER (5, 1, wrCanny);
217 IMG_IN( 1,         src, ; );
218 NUM_IN( 2, double, lowThreshold );
219 NUM_IN( 3, double, highThreshold );
220 NUM_IN( 4, int,    apertureSize );
221
222 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
223                                  PARAM( dst, channels ) = PARAM( src, channels );
224                                  PARAM( dst, class )    = PARAM( src, class ); );
225
226 CV_MCALL( cvCanny( (IplImage *)src, (IplImage *)dst, 
227                  lowThreshold, highThreshold, apertureSize ) );
228 PUT_IMG( dst );
229 RET
230
231 ///////////////////////////////////////////////////////////////////////////////
232 // IMAGE dst = dllname('PreCornerDetect', IMAGE 32F src, INT aperture);
233 //
234 WRAPPER (3, 1, wrPreCornerDetect);
235 IMG_IN( 1,      src, ; );
236 NUM_IN( 2, int, apertureSize );
237
238 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
239                                  PARAM( dst, channels ) = PARAM( src, channels );
240                                  PARAM( dst, class )    = mxSINGLE_CLASS );
241
242 CV_MCALL( cvPreCornerDetect( (IplImage *)src, (IplImage *)dst, apertureSize ) );
243 PUT_IMG( dst );
244 RET
245
246 ///////////////////////////////////////////////////////////////////////////////
247 // IMAGE result = dllname( 'MatchTemplate', 
248 //                         IMAGE array, IMAGE templ, ENUM method );
249 //
250 WRAPPER (4, 1, wrMatchTemplate);
251 IMG_IN( 1,      array, ; );
252 IMG_IN( 2,      templ, ; );
253 NUM_IN( 3, int, method );
254
255 IMG_OUT( 0, result,
256         PARAM( result, size ).width = 
257                 PARAM( array, size ).width - PARAM( templ, size ).width + 1;
258         PARAM( result, size ).height = 
259                 PARAM( array, size ).height - PARAM( templ, size ).height + 1;
260         PARAM( result, channels ) = PARAM( array, channels );
261         PARAM( result, class )    = mxSINGLE_CLASS; );
262
263 CV_MCALL( cvMatchTemplate( (IplImage *)array, (IplImage *)templ,
264                  (IplImage *)result, (CvTemplMatchMethod)method ) );
265
266 PUT_IMG( result );
267 RET
268
269 ///////////////////////////////////////////////////////////////////////////////
270 // IMAGE mhi = dllname( 'UpdateMotionHistory', IMAGE silhouette,
271 //                      DOUBLE timestamp,
272 //                                  DOUBLE mhiduration );
273 //
274 WRAPPER (4, 1, wrUpdateMotionHistory);
275 IMG_IN( 1,         silhouette, ; );
276 NUM_IN( 2, double, timestamp );
277 NUM_IN( 3, double, mhiDuration );
278
279 IMG_OUT( 0, mhi, PARAM( mhi, size )     = PARAM( silhouette, size );
280                                  PARAM( mhi, channels ) = PARAM( silhouette, channels );
281                                  PARAM( mhi, class )    = mxSINGLE_CLASS; );
282
283 CV_MCALL( cvUpdateMotionHistory( (IplImage *)silhouette, (IplImage *)mhi, 
284                                            timestamp, mhiDuration ) );
285 PUT_IMG( mhi );
286 RET
287
288 ///////////////////////////////////////////////////////////////////////////////
289 // [min, max, [Xmin Ymin], [Xmax, Ymax]]=
290 //                      dllname( 'MinMaxLoc', IMAGE src, IMAGE mask );
291 //
292 WRAPPER (3, 4, wrMinMaxLoc);
293 IMG_IN( 1, src, ; );
294 IMG_IN( 2, mask, PARAM( mask, allowEmpty ) = true; );
295
296 NUM_OUT( 0, double, minVal, ; );
297 NUM_OUT( 1, double, maxVal, ; );
298 ARRAY_OUT( 2, CvPoint0S, minLoc, 1, ; );
299 ARRAY_OUT( 3, CvPoint0S, maxLoc, 1, ; );
300
301 CV_MCALL( cvMinMaxLoc( (IplImage *)src, &minVal, &maxVal,
302                          (CvPoint *)minLoc, (CvPoint *)maxLoc, (IplImage *)mask ) );
303
304 PUT_NUM( minVal );
305 PUT_NUM( maxVal );
306 PUT_ARRAY( minLoc );
307 PUT_ARRAY( maxLoc );
308 RET
309
310 ///////////////////////////////////////////////////////////////////////////////
311 // IMAGE dst = dllname( 'Threshold', IMAGE src, DOUBLE thresh, DOUBLE maxValue,
312 //     ENUM type );
313 //
314 WRAPPER( 5, 1, wrThreshold );
315 IMG_IN( 1,         src, ; );
316 NUM_IN( 2, double, thresh );
317 NUM_IN( 3, double, maxValue );
318 NUM_IN( 4, int,    type );
319
320 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
321                                  PARAM( dst, channels ) = PARAM( src, channels );
322                                  PARAM( dst, class )    = PARAM( src, class ); );
323
324 CV_MCALL( cvThreshold( (IplImage *)src, (IplImage *)dst, thresh, maxValue, 
325                  (CvThreshType)(type) ) );
326
327 PUT_IMG( dst );
328 RET
329
330 ///////////////////////////////////////////////////////////////////////////////
331 // IMAGE dst = dllname( 'AdaptiveThreshold',
332 //                 IMAGE src, 
333 //                 maxValue,
334 //                 method,
335 //                 type,
336 //                 parameters );
337 //
338 WRAPPER (6, 1, wrAdaptiveThreshold);    
339 IMG_IN( 1,         src, ; );
340 NUM_IN( 2, double, maxValue );
341 NUM_IN( 3, int,    method );
342 NUM_IN( 4, int,    type );
343 NUM_IN( 5, int,    blockSize );
344 NUM_IN( 6, double, param1 );
345
346 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( src, size );
347                                  PARAM( dst, channels ) = PARAM( src, channels );
348                                  PARAM( dst, class )    = PARAM( src, class ); );
349
350 CV_MCALL( cvAdaptiveThreshold( (IplImage *)src, (IplImage *)dst, 
351                      maxValue, (CvAdaptiveThreshMethod)method, 
352                          (CvThreshType)type, blockSize, param1 ));
353 RET
354
355 ///////////////////////////////////////////////////////////////////////////////
356 // SEQARRAY dst = dllname( 'FindContours', IMAGE src, ENUM mode, ENUM method );
357 //
358 WRAPPER( 4, 1, wrFindContours );
359 IMG_IN(  1,      src,    ; );
360 NUM_IN(  2, int, mode );
361 NUM_IN(  3, int, method );
362
363 SEQ_OUT( 0, dst, ; );
364
365 TEMP_IMAGE( tmpImg, PARAM( src, size ), 
366                                         PARAM( src, depth ), PARAM( src, channels ) );
367 cvCopy( (IplImage *)src, (IplImage *)tmpImg );
368 PARAM( dst, num ) = CV_MCALL( cvFindContours( (IplImage *)tmpImg,
369                                                                  PARAM( dst, storage ),
370                                                                  (CvSeq **)&dst, PARAM( dst, headerSize ),
371                                                                  (CvContourRetrievalMode)(mode),
372                                                                  (CvChainApproxMethod)(method) ) );
373 PUT_SEQ( dst, CvPoint0S, CvRect0S );
374 RET
375
376 ///////////////////////////////////////////////////////////////////////////////
377 // IMAGE dst = dllname( 'DrawContours',
378 //     IMAGE img,            // image
379 //     SEQARRAY seq,         // array of sequences
380 //         INT first,            // index of the first sequence
381 //     DOUBLE externalColor 
382 //     DOUBLE holeColor
383 //     INT maxLevel,
384 //     INT thickness,
385 //     INT connectivity );
386 //
387 WRAPPER( 9, 1, wrDrawContours );
388 IMG_IN( 1,         img, ; );
389 NUM_IN( 3, int,    first );
390 SEQ_IN( 2, first,  seq, CvPoint0S, CvRect0S, PARAM( seq, allowEmpty ) = true; );
391 NUM_IN( 4, double, externalColor );
392 NUM_IN( 5, double, holeColor );
393 NUM_IN( 6, int,    maxLevel );
394 NUM_IN( 7, int,    thickness );
395 NUM_IN( 8, int,    connectivity );
396
397 IMG_OUT( 0, dst, PARAM( dst, size )     = PARAM( img, size );
398                                  PARAM( dst, channels ) = PARAM( img, channels );
399                                  PARAM( dst, class )    = PARAM( img, class ); );
400
401 cvCopy( (IplImage *)img, (IplImage *)dst );
402 if( (CvSeq *)seq )
403 {
404         CV_MCALL( cvDrawContours( (IplImage *)dst, (CvSeq *)seq, 
405                                  externalColor, holeColor, maxLevel, thickness,
406                                  connectivity ) );
407 }
408
409 PUT_IMG( dst );
410 RET
411
412 ///////////////////////////////////////////////////////////////////////////////
413 // SEQARRAY dst = dllname( 'ApproxPoly',
414 //     SEQARRAY seqArray,    // array of sequences
415 //         INT first,            // index of the first sequence
416 //     ENUM method,          // method
417 //     DOUBLE parameter,     // parameter
418 //     INT recursive );
419 //
420 WRAPPER( 6, 1, wrApproxPoly );
421 NUM_IN( 2, int,    first );
422 SEQ_IN( 1, first,  seq, CvPoint, CvRect, PARAM( seq, allowEmpty ) = true; );
423 NUM_IN( 3, int,    method );
424 NUM_IN( 4, double, parameter );
425 NUM_IN( 5, int,    recursive );
426
427 SEQ_OUT( 0, dst, ; );
428
429 if( (CvSeq *)seq )
430 {
431         PARAM( dst, num ) = PARAM( seq, num );
432         dst = (CvContour *)CV_MCALL( cvApproxPoly( (CvSeq *)seq,
433                 PARAM( seq, headerSize ),
434                 PARAM( seq, storage ), (CvPolyApproxMethod)(method),
435                 parameter, recursive ) );
436 }
437 PUT_SEQ( dst, CvPoint, CvRect );
438 RET
439
440 ///////////////////////////////////////////////////////////////////////////////
441 // perimeter = dllname( 'ContourPerimeter',
442 //     points,    // n by 2 array of points
443 //         slice );   // [firstIdx lastIdx]
444 //
445 WRAPPER( 3, 1, wrContourPerimeter );
446 ARRAY_IN( 1, CvPoint,  points, -1, ; );
447 ARRAY_IN( 2, CvSlice0, slice,   1, ; );
448
449 NUM_OUT(  0, double,   perimeter,  ; );
450
451 CvSeq seq;
452 CvSeqBlock block;
453 cvMakeSeqHeaderForArray( CV_SEQ_CONTOUR, sizeof( seq ),
454   sizeof( CvPoint ),
455   (CvArr *)((CvPoint *)points), PARAM( points, num ), &seq, &block );
456 perimeter = CV_MCALL( cvContourPerimeter(&seq) );
457
458 PUT_NUM( perimeter );
459 RET
460
461 ///////////////////////////////////////////////////////////////////////////////
462 // area = dllname( 'ContourArea',
463 //     points,    // n by 2 array of points
464 //         slice );   // [firstIdx lastIdx]
465 //
466 WRAPPER( 3, 1, wrContourArea );
467 ARRAY_IN( 1, CvPoint,  points, -1, ; );
468 ARRAY_IN( 2, CvSlice0, slice,   1, ; );
469
470 NUM_OUT(  0, double,   area,  ; );
471
472 CvSeq seq;
473 CvSeqBlock block;
474 cvMakeSeqHeaderForArray( CV_SEQ_CONTOUR, sizeof( seq ),
475   sizeof( CvPoint ),
476   (CvArr *)((CvPoint *)points), PARAM( points, num ), &seq, &block );
477 area = CV_MCALL( cvContourArea( &seq, *((CvSlice *)slice) ) );
478
479 PUT_NUM( area );
480 RET
481
482 ///////////////////////////////////////////////////////////////////////////////
483 // [IMAGE dst, DOUBLE area, DOUBLE value, [x y width height]] = 
484 //   dllname( 'FloodFill',
485 //            IMAGE src,
486 //            seedPoint,
487 //            DOUBLE newVal,
488 //            DOUBLE loDiff,
489 //            DOUBLE upDiff,
490 //            INT connectivity );
491 //
492 WRAPPER( 7, 4, wrFloodFill );
493 IMG_IN(    1,            src, ; );
494 ARRAY_IN(  2, CvPoint0S, seedPoint, 1, ; );
495 NUM_IN(    3, double,    newVal );
496 NUM_IN(    4, double,    loDiff );
497 NUM_IN(    5, double,    upDiff );
498 NUM_IN(    6, int,       connectivity );
499
500 IMG_OUT(   0,            dst, PARAM( dst, size )     = PARAM( src, size );
501                                                           PARAM( dst, channels ) = PARAM( src, channels );
502                                                           PARAM( dst, class )    = PARAM( src, class ); );
503 NUM_OUT(   1, double,    area, ; );
504 NUM_OUT(   2, double,    value, ; );
505 ARRAY_OUT( 3, CvRect0S,  rect, 1, ; );
506
507 cvCopy( (IplImage *)src, (IplImage *)dst );
508 CvConnectedComp comp;
509 CV_MCALL( cvFloodFill( (IplImage *)dst, *((CvPoint *)seedPoint), 
510         newVal, loDiff, upDiff,
511         &comp, connectivity ) );
512 area               = (double)comp.area;
513 value              = (double)comp.value;
514 *((CvRect *)rect)  = (CvRect)comp.rect;
515
516 PUT_IMG(   dst   );
517 PUT_NUM(   area  );
518 PUT_NUM(   value );
519 PUT_ARRAY( rect  );
520 RET
521
522 ///////////////////////////////////////////////////////////////////////////////
523 // [featuresB, error] = 
524 //   dllname( 'CalcOpticalFlowPyrLK',
525 //            IMAGE imgA, IMAGE imgB, featuresA, guessFeaturesB,
526 //            winSize, INT level,
527 //            [maxIter epsilon] );
528 //
529 WRAPPER( 8, 2, wrCalcOpticalFlowPyrLK );
530 IMG_IN(   1,                 imgA, ; );
531 IMG_IN(   2,                 imgB, ; );
532 ARRAY_IN( 3, CvPoint2D32fS,  featuresA, -1, ; );
533 ARRAY_IN( 4, CvPoint2D32fS,  guessFeaturesB, -1,
534                                                                  PARAM( guessFeaturesB, allowEmpty ) = true; );
535 ARRAY_IN( 5, CvSizeS,        winSize, 1, ; );
536 NUM_IN(   6, int,            level );
537 ARRAY_IN( 7, CvTermCriteria, criteria, 1, ; );
538
539 ARRAY_OUT(  0, CvPoint2D32fS, featuresB, PARAM( featuresA, num), ; );
540 VECTOR_OUT( 1, float,         error,     PARAM( featuresA, num ),
541                                                                  PARAM( error, vecType ) = col; );
542
543 int flags = 0;
544 TEMP_ARRAY( char, status, PARAM( featuresA, num) );
545 if( PARAM( featuresA, num) == PARAM( guessFeaturesB, num) )
546 {
547    // initial guessess
548    memcpy( (void *)((CvPoint2D32f *)featuresB),
549            (void *)((CvPoint2D32f *)guessFeaturesB),
550            sizeof( CvPoint2D32f ) * PARAM( featuresA, num) );
551    flags |= CV_LKFLOW_INITIAL_GUESSES;
552 }
553 CV_MCALL( cvCalcOpticalFlowPyrLK(
554    (IplImage *)imgA, (IplImage *)imgB,
555    0, 0,
556    (CvPoint2D32f *)featuresA, (CvPoint2D32f *)featuresB,
557    PARAM( featuresA, num),
558    *((CvSize *)winSize), level,
559    (char *)status, (float *)error,
560    *((CvTermCriteria *)criteria), flags ) );
561
562 PUT_ARRAY(  featuresB );
563 PUT_VECTOR( error );
564
565 // fill points for which flow was not found with NaN value
566 double NaN = mxGetNaN();
567 double *data0 = (double *)mxGetData( plhs[0] );
568 double *data1 = (double *)mxGetData( plhs[1] );
569 int step0 = mxGetM( plhs[0] );
570 for( int i = 0; i < PARAM( featuresA, num); i++ )
571 {
572    if( *((char *)status + i) == 0 )
573    {
574            data0[i] = NaN;
575            data0[i + step0] = NaN;
576            data1[i] = NaN;
577    }
578 }
579 RET
580
581 ///////////////////////////////////////////////////////////////////////////////
582 // corners = dllname( 'GoodFeaturesToTrack',
583 //             IMAGE image, INT cornerCount,
584 //             DOUBLE qualityLevel, DOUBLE minDistance, 
585 //             IMAGE mask // may be empty matrix
586 //           );
587 //
588 WRAPPER( 6, 1, wrGoodFeaturesToTrack );
589 IMG_IN( 1,         image,        ; );
590 NUM_IN( 2, int,    cornerCount );
591 NUM_IN( 3, double, qualityLevel );
592 NUM_IN( 4, double, minDistance );
593 IMG_IN( 5,         mask, PARAM( mask, allowEmpty ) = true; );
594
595 TEMP_IMAGE( eigImage,  PARAM( image, size ), IPL_DEPTH_32F, 1 );
596 TEMP_IMAGE( tempImage, PARAM( image, size ), IPL_DEPTH_32F, 1 );
597
598 ARRAY_OUT( 0, CvPoint2D32fS, corners, cornerCount, ; );
599
600 CV_MCALL( cvGoodFeaturesToTrack( (IplImage *)image, 
601         (IplImage *)eigImage, (IplImage *)tempImage,
602         (CvPoint2D32f *)corners, &cornerCount, qualityLevel,
603                                    minDistance, (IplImage *)mask ) );
604 PARAM( corners, num ) = cornerCount;
605 PUT_ARRAY( corners );
606 RET