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 /*F///////////////////////////////////////////////////////////////////////////////////////
     44 //    Name: cvMatchContours
     45 //    Purpose:
     46 //      Calculates matching of the two contours
     47 //    Context:
     48 //    Parameters:
     49 //      contour_1 - pointer to the first input contour object.
     50 //      contour_2 - pointer to the second input contour object.
     51 //      method - method for the matching calculation
     52 //      (now CV_IPPI_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2 or
     53 //      CV_CONTOURS_MATCH_I3 only  )
     54 //      rezult - output calculated measure
     55 //
     56 //F*/
     57 CV_IMPL  double
     58 cvMatchShapes( const void* contour1, const void* contour2,
     59                int method, double /*parameter*/ )
     60 {
     61     CvMoments moments;
     62     CvHuMoments huMoments;
     63     double ma[7], mb[7];
     64     int i, sma, smb;
     65     double eps = 1.e-5;
     66     double mmm;
     67     double result = 0;
     68 
     69     CV_FUNCNAME( "cvMatchShapes" );
     70 
     71     __BEGIN__;
     72 
     73     if( !contour1 || !contour2 )
     74         CV_ERROR( CV_StsNullPtr, "" );
     75 
     76 /*   first moments calculation */
     77     CV_CALL( cvMoments( contour1, &moments ));
     78 
     79 /*  Hu moments calculation   */
     80     CV_CALL( cvGetHuMoments( &moments, &huMoments ));
     81 
     82     ma[0] = huMoments.hu1;
     83     ma[1] = huMoments.hu2;
     84     ma[2] = huMoments.hu3;
     85     ma[3] = huMoments.hu4;
     86     ma[4] = huMoments.hu5;
     87     ma[5] = huMoments.hu6;
     88     ma[6] = huMoments.hu7;
     89 
     90 
     91 /*   second moments calculation  */
     92     CV_CALL( cvMoments( contour2, &moments ));
     93 
     94 /*  Hu moments calculation   */
     95     CV_CALL( cvGetHuMoments( &moments, &huMoments ));
     96 
     97     mb[0] = huMoments.hu1;
     98     mb[1] = huMoments.hu2;
     99     mb[2] = huMoments.hu3;
    100     mb[3] = huMoments.hu4;
    101     mb[4] = huMoments.hu5;
    102     mb[5] = huMoments.hu6;
    103     mb[6] = huMoments.hu7;
    104 
    105     switch (method)
    106     {
    107     case 1:
    108         {
    109             for( i = 0; i < 7; i++ )
    110             {
    111                 double ama = fabs( ma[i] );
    112                 double amb = fabs( mb[i] );
    113 
    114                 if( ma[i] > 0 )
    115                     sma = 1;
    116                 else if( ma[i] < 0 )
    117                     sma = -1;
    118                 else
    119                     sma = 0;
    120                 if( mb[i] > 0 )
    121                     smb = 1;
    122                 else if( mb[i] < 0 )
    123                     smb = -1;
    124                 else
    125                     smb = 0;
    126 
    127                 if( ama > eps && amb > eps )
    128                 {
    129                     ama = 1. / (sma * log10( ama ));
    130                     amb = 1. / (smb * log10( amb ));
    131                     result += fabs( -ama + amb );
    132                 }
    133             }
    134             break;
    135         }
    136 
    137     case 2:
    138         {
    139             for( i = 0; i < 7; i++ )
    140             {
    141                 double ama = fabs( ma[i] );
    142                 double amb = fabs( mb[i] );
    143 
    144                 if( ma[i] > 0 )
    145                     sma = 1;
    146                 else if( ma[i] < 0 )
    147                     sma = -1;
    148                 else
    149                     sma = 0;
    150                 if( mb[i] > 0 )
    151                     smb = 1;
    152                 else if( mb[i] < 0 )
    153                     smb = -1;
    154                 else
    155                     smb = 0;
    156 
    157                 if( ama > eps && amb > eps )
    158                 {
    159                     ama = sma * log10( ama );
    160                     amb = smb * log10( amb );
    161                     result += fabs( -ama + amb );
    162                 }
    163             }
    164             break;
    165         }
    166 
    167     case 3:
    168         {
    169             for( i = 0; i < 7; i++ )
    170             {
    171                 double ama = fabs( ma[i] );
    172                 double amb = fabs( mb[i] );
    173 
    174                 if( ma[i] > 0 )
    175                     sma = 1;
    176                 else if( ma[i] < 0 )
    177                     sma = -1;
    178                 else
    179                     sma = 0;
    180                 if( mb[i] > 0 )
    181                     smb = 1;
    182                 else if( mb[i] < 0 )
    183                     smb = -1;
    184                 else
    185                     smb = 0;
    186 
    187                 if( ama > eps && amb > eps )
    188                 {
    189                     ama = sma * log10( ama );
    190                     amb = smb * log10( amb );
    191                     mmm = fabs( (ama - amb) / ama );
    192                     if( result < mmm )
    193                         result = mmm;
    194                 }
    195             }
    196             break;
    197         }
    198     default:
    199         CV_ERROR_FROM_STATUS( CV_BADCOEF_ERR );
    200     }
    201 
    202     __END__;
    203 
    204     return result;
    205 }
    206 
    207 
    208 
    209 /*F///////////////////////////////////////////////////////////////////////////////////////
    210 //    Name: icvMatchContourTrees
    211 //    Purpose:
    212 //      Calculates matching of the two contour trees
    213 //    Context:
    214 //    Parameters:
    215 //      tree1 - pointer to the first input contour tree object.
    216 //      tree2 - pointer to the second input contour tree object.
    217 //      method - method for the matching calculation
    218 //      (now CV_CONTOUR_TREES_MATCH_I1 only  )
    219 //      threshold - threshold for the contour trees matching
    220 //      result - output calculated measure
    221 //F*/
    222 CV_IMPL  double
    223 cvMatchContourTrees( const CvContourTree* tree1, const CvContourTree* tree2,
    224                      int method, double threshold )
    225 {
    226     _CvTrianAttr **ptr_p1 = 0, **ptr_p2 = 0;    /*pointers to the pointer's buffer */
    227     _CvTrianAttr **ptr_n1 = 0, **ptr_n2 = 0;    /*pointers to the pointer's buffer */
    228     _CvTrianAttr **ptr11, **ptr12, **ptr21, **ptr22;
    229 
    230     int lpt1, lpt2, lpt, flag, flag_n, i, j, ibuf, ibuf1;
    231     double match_v, d12, area1, area2, r11, r12, r21, r22, w1, w2;
    232     double eps = 1.e-5;
    233     char s1, s2;
    234     _CvTrianAttr tree_1, tree_2;        /*current vertex 1 and 2 tree */
    235     CvSeqReader reader1, reader2;
    236     double result = 0;
    237 
    238     CV_FUNCNAME("cvMatchContourTrees");
    239     __BEGIN__;
    240 
    241     if( !tree1 || !tree2 )
    242         CV_ERROR( CV_StsNullPtr, "" );
    243 
    244     if( method != CV_CONTOUR_TREES_MATCH_I1 )
    245         CV_ERROR( CV_StsBadArg, "Unknown/unsupported comparison method" );
    246 
    247     if( !CV_IS_SEQ_POLYGON_TREE( tree1 ))
    248         CV_ERROR( CV_StsBadArg, "The first argument is not a valid contour tree" );
    249 
    250     if( !CV_IS_SEQ_POLYGON_TREE( tree2 ))
    251         CV_ERROR( CV_StsBadArg, "The second argument is not a valid contour tree" );
    252 
    253     lpt1 = tree1->total;
    254     lpt2 = tree2->total;
    255     lpt = lpt1 > lpt2 ? lpt1 : lpt2;
    256 
    257     ptr_p1 = ptr_n1 = ptr_p2 = ptr_n2 = NULL;
    258     CV_CALL( ptr_p1 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * )));
    259     CV_CALL( ptr_p2 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * )));
    260 
    261     CV_CALL( ptr_n1 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * )));
    262     CV_CALL( ptr_n2 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * )));
    263 
    264     cvStartReadSeq( (CvSeq *) tree1, &reader1, 0 );
    265     cvStartReadSeq( (CvSeq *) tree2, &reader2, 0 );
    266 
    267 /*read the root of the first and second tree*/
    268     CV_READ_SEQ_ELEM( tree_1, reader1 );
    269     CV_READ_SEQ_ELEM( tree_2, reader2 );
    270 
    271 /*write to buffer pointers to root's childs vertexs*/
    272     ptr_p1[0] = tree_1.next_v1;
    273     ptr_p1[1] = tree_1.next_v2;
    274     ptr_p2[0] = tree_2.next_v1;
    275     ptr_p2[1] = tree_2.next_v2;
    276     i = 2;
    277     match_v = 0.;
    278     area1 = tree_1.area;
    279     area2 = tree_2.area;
    280 
    281     if( area1 < eps || area2 < eps || lpt < 4 )
    282         CV_ERROR( CV_StsBadSize, "" );
    283 
    284     r11 = r12 = r21 = r22 = w1 = w2 = d12 = 0;
    285     flag = 0;
    286     s1 = s2 = 0;
    287     do
    288     {
    289         if( flag == 0 )
    290         {
    291             ptr11 = ptr_p1;
    292             ptr12 = ptr_n1;
    293             ptr21 = ptr_p2;
    294             ptr22 = ptr_n2;
    295             flag = 1;
    296         }
    297         else
    298         {
    299             ptr11 = ptr_n1;
    300             ptr12 = ptr_p1;
    301             ptr21 = ptr_n2;
    302             ptr22 = ptr_p2;
    303             flag = 0;
    304         }
    305         ibuf = 0;
    306         for( j = 0; j < i; j++ )
    307         {
    308             flag_n = 0;
    309             if( ptr11[j] != NULL )
    310             {
    311                 r11 = ptr11[j]->r1;
    312                 r12 = ptr11[j]->r2;
    313                 flag_n = 1;
    314                 w1 = ptr11[j]->area / area1;
    315                 s1 = ptr11[j]->sign;
    316             }
    317             else
    318             {
    319                 r11 = r21 = 0;
    320             }
    321             if( ptr21[j] != NULL )
    322             {
    323                 r21 = ptr21[j]->r1;
    324                 r22 = ptr21[j]->r2;
    325                 flag_n = 1;
    326                 w2 = ptr21[j]->area / area2;
    327                 s2 = ptr21[j]->sign;
    328             }
    329             else
    330             {
    331                 r21 = r22 = 0;
    332             }
    333             if( flag_n != 0 )
    334 /* calculate node distance */
    335             {
    336                 switch (method)
    337                 {
    338                 case 1:
    339                     {
    340                         double t0, t1;
    341                         if( s1 != s2 )
    342                         {
    343                             t0 = fabs( r11 * w1 + r21 * w2 );
    344                             t1 = fabs( r12 * w1 + r22 * w2 );
    345                         }
    346                         else
    347                         {
    348                             t0 = fabs( r11 * w1 - r21 * w2 );
    349                             t1 = fabs( r12 * w1 - r22 * w2 );
    350                         }
    351                         d12 = t0 + t1;
    352                         break;
    353                     }
    354                 }
    355                 match_v += d12;
    356                 ibuf1 = ibuf + 1;
    357 /*write to buffer the pointer to child vertexes*/
    358                 if( ptr11[j] != NULL )
    359                 {
    360                     ptr12[ibuf] = ptr11[j]->next_v1;
    361                     ptr12[ibuf1] = ptr11[j]->next_v2;
    362                 }
    363                 else
    364                 {
    365                     ptr12[ibuf] = NULL;
    366                     ptr12[ibuf1] = NULL;
    367                 }
    368                 if( ptr21[j] != NULL )
    369                 {
    370                     ptr22[ibuf] = ptr21[j]->next_v1;
    371                     ptr22[ibuf1] = ptr21[j]->next_v2;
    372                 }
    373                 else
    374                 {
    375                     ptr22[ibuf] = NULL;
    376                     ptr22[ibuf1] = NULL;
    377                 }
    378                 ibuf += 2;
    379             }
    380         }
    381         i = ibuf;
    382     }
    383     while( i > 0 && match_v < threshold );
    384 
    385     result = match_v;
    386 
    387     __END__;
    388 
    389     cvFree( &ptr_n2 );
    390     cvFree( &ptr_n1 );
    391     cvFree( &ptr_p2 );
    392     cvFree( &ptr_p1 );
    393 
    394     return result;
    395 }
    396 
    397 
    398 /* End of file. */
    399