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 "_cvaux.h"
     42 #include "_cvvm.h"
     43 #include <stdlib.h>
     44 #include <assert.h>
     45 
     46 
     47 /*======================================================================================*/
     48 
     49 CvStatus
     50 icvDynamicCorrespond( int *first,       /* first sequence of runs */
     51                       /* s0|w0|s1|w1|...|s(n-1)|w(n-1)|sn */
     52                       int first_runs,   /* number of runs */
     53                       int *second,      /* second sequence of runs */
     54                       int second_runs, int *first_corr, /* s0'|e0'|s1'|e1'|... */
     55                       int *second_corr )
     56 {
     57 
     58     float Pd, Fi, S;
     59     float Occlusion;
     60     float *costTable;
     61     uchar *matchEdges;
     62     int prev;
     63     int curr;
     64     int baseIndex;
     65     int i, j;
     66     int i_1, j_1;
     67     int n;
     68     int l_beg, r_beg, l_end, r_end, l_len, r_len;
     69     int first_curr;
     70     int second_curr;
     71     int l_color, r_color;
     72     int len_color;
     73     float cost, cost1;
     74     float min1, min2, min3;
     75     float cmin;
     76     uchar cpath;
     77     int row_size;
     78 
     79     /* Test arguments for errors */
     80 
     81     if( (first == 0) ||
     82         (first_runs < 1) ||
     83         (second == 0) || (second_runs < 1) || (first_corr == 0) || (second_corr == 0) )
     84 
     85         return CV_BADFACTOR_ERR;
     86 
     87 
     88     Pd = 0.95f;
     89     Fi = (float) CV_PI;
     90     S = 1;
     91 
     92     Occlusion = (float) log( Pd * Fi / ((1 - Pd) * sqrt( fabs( (CV_PI * 2) * (1. / S) ))));
     93 
     94     costTable = (float *)cvAlloc( (first_runs + 1) * (second_runs + 1) * sizeof( float ));
     95 
     96     if( costTable == 0 )
     97         return CV_OUTOFMEM_ERR;
     98 
     99     matchEdges = (uchar *)cvAlloc( (first_runs + 1) * (second_runs + 1) * sizeof( uchar ));
    100 
    101     if( matchEdges == 0 )
    102     {
    103         cvFree( &costTable );
    104         return CV_OUTOFMEM_ERR;
    105     }
    106 
    107     row_size = first_runs + 1;
    108 
    109     /* ============= Fill costTable ============= */
    110 
    111     costTable[0] = 0.0f;
    112 
    113     /* Fill upper line in the cost Table */
    114 
    115     prev = first[0];
    116     curr = 2;
    117 
    118     for( n = 0; n < first_runs; n++ )
    119     {
    120 
    121         l_end = first[curr];
    122         curr += 2;
    123         costTable[n + 1] = costTable[n] + Occlusion * (l_end - prev);
    124         prev = l_end;
    125 
    126     }                           /* for */
    127 
    128     /* Fill lefter line in the cost Table */
    129 
    130     prev = second[0];
    131     curr = 2;
    132     baseIndex = 0;
    133 
    134     for( n = 0; n < second_runs; n++ )
    135     {
    136 
    137         l_end = second[curr];
    138         curr += 2;
    139         costTable[baseIndex + row_size] = costTable[baseIndex] + Occlusion * (l_end - prev);
    140         baseIndex += row_size;
    141         prev = l_end;
    142 
    143     }                           /* for */
    144 
    145     /* Count costs in the all rest cells */
    146 
    147     first_curr = 0;
    148     second_curr = 0;
    149 
    150     for( i = 1; i <= first_runs; i++ )
    151     {
    152         for( j = 1; j <= second_runs; j++ )
    153         {
    154 
    155             first_curr = (i - 1) * 2;
    156             second_curr = (j - 1) * 2;
    157 
    158             l_beg = first[first_curr];
    159             first_curr++;
    160             l_color = first[first_curr];
    161             first_curr++;
    162             l_end = first[first_curr];
    163             l_len = l_end - l_beg + 1;
    164 
    165             r_beg = second[second_curr];
    166             second_curr++;
    167             r_color = second[second_curr];
    168             second_curr++;
    169             r_end = second[second_curr];
    170             r_len = r_end - r_beg + 1;
    171 
    172             i_1 = i - 1;
    173             j_1 = j - 1;
    174 
    175             if( r_len == l_len )
    176             {
    177                 cost = 0;
    178             }
    179             else
    180             {
    181 
    182                 if( r_len > l_len )
    183                 {
    184                     cost = (float) (r_len * r_len - l_len * l_len) * (1 / (r_len * l_len));
    185                 }
    186                 else
    187                 {
    188                     cost = (float) (l_len * l_len - r_len * r_len) * (1 / (r_len * l_len));
    189                 }
    190             }                   /* if */
    191 
    192             len_color = r_color - l_color;
    193 
    194             cost1 = (float) ((len_color * len_color) >> 2);
    195 
    196             min2 = costTable[i_1 + j * row_size] + Occlusion * l_len;
    197 
    198             min3 = costTable[i + j_1 * row_size] + Occlusion * r_len;
    199 
    200             min1 = costTable[i_1 + j_1 * row_size] + cost + (float) cost1;
    201 
    202             if( min1 < min2 )
    203             {
    204 
    205                 if( min1 < min3 )
    206                 {
    207                     cmin = min1;
    208                     cpath = 1;
    209                 }
    210                 else
    211                 {
    212                     cmin = min3;
    213                     cpath = 3;
    214                 }               /* if */
    215 
    216             }
    217             else
    218             {
    219 
    220                 if( min2 < min3 )
    221                 {
    222                     cmin = min2;
    223                     cpath = 2;
    224                 }
    225                 else
    226                 {
    227                     cmin = min3;
    228                     cpath = 3;
    229                 }               /* if */
    230 
    231             }                   /* if */
    232 
    233             costTable[i + j * row_size] = cmin;
    234             matchEdges[i + j * row_size] = cpath;
    235         }                       /* for */
    236     }                           /* for */
    237 
    238     /* =========== Reconstruct the Path =========== */
    239 
    240     i = first_runs;
    241     j = second_runs;
    242 
    243     first_curr = i * 2 - 2;
    244     second_curr = j * 2 - 2;
    245 
    246 
    247     while( i > 0 && j > 0 )
    248     {
    249 
    250         /* Connect begins */
    251         switch (matchEdges[i + j * row_size])
    252         {
    253 
    254         case 1:                /* to diagonal */
    255 
    256             first_corr[first_curr] = second[second_curr];
    257             first_corr[first_curr + 1] = second[second_curr + 2];
    258             second_corr[second_curr] = first[first_curr];
    259             second_corr[second_curr + 1] = first[first_curr + 2];
    260 
    261             first_curr -= 2;
    262             second_curr -= 2;
    263             i--;
    264             j--;
    265 
    266             break;
    267 
    268         case 2:                /* to left */
    269 
    270             first_corr[first_curr] = second[second_curr + 2];
    271             first_corr[first_curr + 1] = second[second_curr + 2];
    272 
    273             first_curr -= 2;
    274             i--;
    275 
    276             break;
    277 
    278         case 3:                /* to up */
    279 
    280             second_corr[second_curr] = first[first_curr + 2];
    281             second_corr[second_curr + 1] = first[first_curr + 2];
    282 
    283             second_curr -= 2;
    284             j--;
    285 
    286             break;
    287         }                       /* switch */
    288     }                           /* while */
    289 
    290     /* construct rest of horisontal path if its need */
    291     while( i > 0 )
    292     {
    293 
    294         first_corr[first_curr] = second[second_curr + 2];       /* connect to begin */
    295         first_corr[first_curr + 1] = second[second_curr + 2];   /* connect to begin */
    296 
    297         first_curr -= 2;
    298         i--;
    299 
    300     }                           /* while */
    301 
    302     /* construct rest of vertical path if its need */
    303     while( j > 0 )
    304     {
    305 
    306         second_corr[second_curr] = first[first_curr + 2];
    307         second_corr[second_curr + 1] = first[first_curr + 2];
    308 
    309         second_curr -= 2;
    310         j--;
    311 
    312     }                           /* while */
    313 
    314     cvFree( &costTable );
    315     cvFree( &matchEdges );
    316 
    317     return CV_NO_ERR;
    318 }                               /* icvDynamicCorrespond */
    319 
    320 
    321 /*======================================================================================*/
    322 
    323 static CvStatus
    324 icvDynamicCorrespondMulti( int lines,   /* number of scanlines */
    325                            int *first,  /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
    326                            int *first_runs,     /* numbers of runs */
    327                            int *second, int *second_runs, int *first_corr,      /* s0'|e0'|s1'|e1'|... */
    328                            int *second_corr )
    329 {
    330     CvStatus error;
    331 
    332     int currFirst;
    333     int currSecond;
    334     int currFirstCorr;
    335     int currSecondCorr;
    336     int n;
    337 
    338     /* Test errors */
    339 
    340     if( (lines < 1) ||
    341         (first == 0) ||
    342         (first_runs == 0) ||
    343         (second == 0) || (second_runs == 0) || (first_corr == 0) || (second_corr == 0) )
    344         return CV_BADFACTOR_ERR;
    345 
    346     currFirst = 0;
    347     currSecond = 0;
    348     currFirstCorr = 0;
    349     currSecondCorr = 0;
    350 
    351     for( n = 0; n < lines; n++ )
    352     {
    353 
    354         error = icvDynamicCorrespond( &(first[currFirst]),
    355                                       first_runs[n],
    356                                       &(second[currSecond]),
    357                                       second_runs[n],
    358                                       &(first_corr[currFirstCorr]),
    359                                       &(second_corr[currSecondCorr]) );
    360 
    361         if( error != CV_NO_ERR )
    362             return error;
    363 
    364         currFirst += first_runs[n] * 2 + 1;
    365         currSecond += second_runs[n] * 2 + 1;
    366         currFirstCorr += first_runs[n] * 2;
    367         currSecondCorr += second_runs[n] * 2;
    368 
    369     }
    370 
    371     return CV_NO_ERR;
    372 
    373 }                               /* icvDynamicCorrespondMulti */
    374 
    375 
    376 /*======================================================================================*/
    377 
    378 /*F///////////////////////////////////////////////////////////////////////////////////////
    379 //    Name: cvDynamicCorrespondMulti
    380 //    Purpose: The functions
    381 //    Context:
    382 //    Parameters:
    383 //
    384 //    Notes:
    385 //F*/
    386 CV_IMPL void
    387 cvDynamicCorrespondMulti( int lines,    /* number of scanlines */
    388                           int *first,   /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
    389                           int *first_runs,      /* numbers of runs */
    390                           int *second, int *second_runs, int *first_corr,       /* s0'|e0'|s1'|e1'|... */
    391                           int *second_corr )
    392 {
    393     CV_FUNCNAME( "cvDynamicCorrespondMulti" );
    394     __BEGIN__;
    395 
    396     IPPI_CALL( icvDynamicCorrespondMulti( lines,        /* number of scanlines */
    397                                           first,        /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
    398                                           first_runs,   /* numbers of runs */
    399                                           second, second_runs, first_corr,      /* s0'|e0'|s1'|e1'|... */
    400                                           second_corr ));
    401     __CLEANUP__;
    402     __END__;
    403 }
    404