Home | History | Annotate | Download | only in src
      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 #include "_cv.h"
     42 
     43 #define  cmp_features( f1, f2 )  (*(f1) > *(f2))
     44 
     45 static CV_IMPLEMENT_QSORT( icvSortFeatures, int *, cmp_features )
     46 
     47 CV_IMPL void
     48 cvGoodFeaturesToTrack( const void* image, void* eigImage, void* tempImage,
     49                        CvPoint2D32f* corners, int *corner_count,
     50                        double quality_level, double min_distance,
     51                        const void* maskImage, int block_size,
     52                        int use_harris, double harris_k )
     53 {
     54     CvMat* _eigImg = 0;
     55     CvMat* _tmpImg = 0;
     56 
     57     CV_FUNCNAME( "cvGoodFeaturesToTrack" );
     58 
     59     __BEGIN__;
     60 
     61     double max_val = 0;
     62     int max_count = 0;
     63     int count = 0;
     64     int x, y, i, k = 0;
     65     int min_dist;
     66     int eig_step, tmp_step;
     67 
     68     /* when selecting points, use integer coordinates */
     69     CvPoint *ptr = (CvPoint *) corners;
     70 
     71     /* process floating-point images using integer arithmetics */
     72     int *eig_data = 0;
     73     int *tmp_data = 0;
     74     int **ptr_data = 0;
     75     uchar *mask_data = 0;
     76     int  mask_step = 0;
     77     CvSize size;
     78 
     79     int    coi1 = 0, coi2 = 0, coi3 = 0;
     80     CvMat  stub, *img = (CvMat*)image;
     81     CvMat  eig_stub, *eig = (CvMat*)eigImage;
     82     CvMat  tmp_stub, *tmp = (CvMat*)tempImage;
     83     CvMat  mask_stub, *mask = (CvMat*)maskImage;
     84 
     85     if( corner_count )
     86     {
     87         max_count = *corner_count;
     88         *corner_count = 0;
     89     }
     90 
     91     CV_CALL( img = cvGetMat( img, &stub, &coi1 ));
     92     if( eig )
     93     {
     94         CV_CALL( eig = cvGetMat( eig, &eig_stub, &coi2 ));
     95     }
     96     else
     97     {
     98         CV_CALL( _eigImg = cvCreateMat( img->rows, img->cols, CV_32FC1 ));
     99         eig = _eigImg;
    100     }
    101 
    102     if( tmp )
    103     {
    104         CV_CALL( tmp = cvGetMat( tmp, &tmp_stub, &coi3 ));
    105     }
    106     else
    107     {
    108         CV_CALL( _tmpImg = cvCreateMat( img->rows, img->cols, CV_32FC1 ));
    109         tmp = _tmpImg;
    110     }
    111 
    112     if( mask )
    113     {
    114         CV_CALL( mask = cvGetMat( mask, &mask_stub ));
    115         if( !CV_IS_MASK_ARR( mask ))
    116         {
    117             CV_ERROR( CV_StsBadMask, "" );
    118         }
    119     }
    120 
    121     if( coi1 != 0 || coi2 != 0 || coi3 != 0 )
    122         CV_ERROR( CV_BadCOI, "" );
    123 
    124     if( CV_MAT_CN(img->type) != 1 ||
    125         CV_MAT_CN(eig->type) != 1 ||
    126         CV_MAT_CN(tmp->type) != 1 )
    127         CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
    128 
    129     if( CV_MAT_DEPTH(tmp->type) != CV_32F ||
    130         CV_MAT_DEPTH(eig->type) != CV_32F )
    131         CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
    132 
    133     if( !corners || !corner_count )
    134         CV_ERROR( CV_StsNullPtr, "" );
    135 
    136     if( max_count <= 0 )
    137         CV_ERROR( CV_StsBadArg, "maximal corners number is non positive" );
    138 
    139     if( quality_level <= 0 || min_distance < 0 )
    140         CV_ERROR( CV_StsBadArg, "quality level or min distance are non positive" );
    141 
    142     if( use_harris )
    143     {
    144         CV_CALL( cvCornerHarris( img, eig, block_size, 3, harris_k ));
    145     }
    146     else
    147     {
    148         CV_CALL( cvCornerMinEigenVal( img, eig, block_size, 3 ));
    149     }
    150     CV_CALL( cvMinMaxLoc( eig, 0, &max_val, 0, 0, mask ));
    151     CV_CALL( cvThreshold( eig, eig, max_val * quality_level,
    152                           0, CV_THRESH_TOZERO ));
    153     CV_CALL( cvDilate( eig, tmp ));
    154 
    155     min_dist = cvRound( min_distance * min_distance );
    156 
    157     size = cvGetMatSize( img );
    158     ptr_data = (int**)(tmp->data.ptr);
    159     eig_data = (int*)(eig->data.ptr);
    160     tmp_data = (int*)(tmp->data.ptr);
    161     if( mask )
    162     {
    163         mask_data = (uchar*)(mask->data.ptr);
    164         mask_step = mask->step;
    165     }
    166 
    167     eig_step = eig->step / sizeof(eig_data[0]);
    168     tmp_step = tmp->step / sizeof(tmp_data[0]);
    169 
    170     /* collect list of pointers to features - put them into temporary image */
    171     for( y = 1, k = 0; y < size.height - 1; y++ )
    172     {
    173         eig_data += eig_step;
    174         tmp_data += tmp_step;
    175         mask_data += mask_step;
    176 
    177         for( x = 1; x < size.width - 1; x++ )
    178         {
    179             int val = eig_data[x];
    180             if( val != 0 && val == tmp_data[x] && (!mask || mask_data[x]) )
    181                 ptr_data[k++] = eig_data + x;
    182         }
    183     }
    184 
    185     icvSortFeatures( ptr_data, k, 0 );
    186 
    187     /* select the strongest features */
    188     for( i = 0; i < k; i++ )
    189     {
    190         int j = count, ofs = (int)((uchar*)(ptr_data[i]) - eig->data.ptr);
    191         y = ofs / eig->step;
    192         x = (ofs - y * eig->step)/sizeof(float);
    193 
    194         if( min_dist != 0 )
    195         {
    196             for( j = 0; j < count; j++ )
    197             {
    198                 int dx = x - ptr[j].x;
    199                 int dy = y - ptr[j].y;
    200                 int dist = dx * dx + dy * dy;
    201 
    202                 if( dist < min_dist )
    203                     break;
    204             }
    205         }
    206 
    207         if( j == count )
    208         {
    209             ptr[count].x = x;
    210             ptr[count].y = y;
    211             if( ++count >= max_count )
    212                 break;
    213         }
    214     }
    215 
    216     /* convert points to floating-point format */
    217     for( i = 0; i < count; i++ )
    218     {
    219         assert( (unsigned)ptr[i].x < (unsigned)size.width &&
    220                 (unsigned)ptr[i].y < (unsigned)size.height );
    221 
    222         corners[i].x = (float)ptr[i].x;
    223         corners[i].y = (float)ptr[i].y;
    224     }
    225 
    226     *corner_count = count;
    227 
    228     __END__;
    229 
    230     cvReleaseMat( &_eigImg );
    231     cvReleaseMat( &_tmpImg );
    232 }
    233 
    234 /* End of file. */
    235