Update to 2.0.0 tree from current Fremantle build
[opencv] / src / cvaux / cvcorrespond.cpp
diff --git a/src/cvaux/cvcorrespond.cpp b/src/cvaux/cvcorrespond.cpp
new file mode 100644 (file)
index 0000000..1eef4a7
--- /dev/null
@@ -0,0 +1,398 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                        Intel License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of Intel Corporation may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+#include "_cvaux.h"
+#include "_cvvm.h"
+#include <stdlib.h>
+#include <assert.h>
+
+
+/*======================================================================================*/
+
+CvStatus
+icvDynamicCorrespond( int *first,       /* first sequence of runs */
+                      /* s0|w0|s1|w1|...|s(n-1)|w(n-1)|sn */
+                      int first_runs,   /* number of runs */
+                      int *second,      /* second sequence of runs */
+                      int second_runs, int *first_corr, /* s0'|e0'|s1'|e1'|... */
+                      int *second_corr )
+{
+
+    float Pd, Fi, S;
+    float Occlusion;
+    float *costTable;
+    uchar *matchEdges;
+    int prev;
+    int curr;
+    int baseIndex;
+    int i, j;
+    int i_1, j_1;
+    int n;
+    int l_beg, r_beg, l_end, r_end, l_len, r_len;
+    int first_curr;
+    int second_curr;
+    int l_color, r_color;
+    int len_color;
+    float cost, cost1;
+    float min1, min2, min3;
+    float cmin;
+    uchar cpath;
+    int row_size;
+
+    /* Test arguments for errors */
+
+    if( (first == 0) ||
+        (first_runs < 1) ||
+        (second == 0) || (second_runs < 1) || (first_corr == 0) || (second_corr == 0) )
+
+        return CV_BADFACTOR_ERR;
+
+
+    Pd = 0.95f;
+    Fi = (float) CV_PI;
+    S = 1;
+
+    Occlusion = (float) log( Pd * Fi / ((1 - Pd) * sqrt( fabs( (CV_PI * 2) * (1. / S) ))));
+
+    costTable = (float *)cvAlloc( (first_runs + 1) * (second_runs + 1) * sizeof( float ));
+
+    if( costTable == 0 )
+        return CV_OUTOFMEM_ERR;
+
+    matchEdges = (uchar *)cvAlloc( (first_runs + 1) * (second_runs + 1) * sizeof( uchar ));
+
+    if( matchEdges == 0 )
+    {
+        cvFree( &costTable );
+        return CV_OUTOFMEM_ERR;
+    }
+
+    row_size = first_runs + 1;
+
+    /* ============= Fill costTable ============= */
+
+    costTable[0] = 0.0f;
+
+    /* Fill upper line in the cost Table */
+
+    prev = first[0];
+    curr = 2;
+
+    for( n = 0; n < first_runs; n++ )
+    {
+
+        l_end = first[curr];
+        curr += 2;
+        costTable[n + 1] = costTable[n] + Occlusion * (l_end - prev);
+        prev = l_end;
+
+    }                           /* for */
+
+    /* Fill lefter line in the cost Table */
+
+    prev = second[0];
+    curr = 2;
+    baseIndex = 0;
+
+    for( n = 0; n < second_runs; n++ )
+    {
+
+        l_end = second[curr];
+        curr += 2;
+        costTable[baseIndex + row_size] = costTable[baseIndex] + Occlusion * (l_end - prev);
+        baseIndex += row_size;
+        prev = l_end;
+
+    }                           /* for */
+
+    /* Count costs in the all rest cells */
+
+    first_curr = 0;
+    second_curr = 0;
+
+    for( i = 1; i <= first_runs; i++ )
+    {
+        for( j = 1; j <= second_runs; j++ )
+        {
+
+            first_curr = (i - 1) * 2;
+            second_curr = (j - 1) * 2;
+
+            l_beg = first[first_curr];
+            first_curr++;
+            l_color = first[first_curr];
+            first_curr++;
+            l_end = first[first_curr];
+            l_len = l_end - l_beg + 1;
+
+            r_beg = second[second_curr];
+            second_curr++;
+            r_color = second[second_curr];
+            second_curr++;
+            r_end = second[second_curr];
+            r_len = r_end - r_beg + 1;
+
+            i_1 = i - 1;
+            j_1 = j - 1;
+
+            if( r_len == l_len )
+            {
+                cost = 0;
+            }
+            else
+            {
+
+                if( r_len > l_len )
+                {
+                    cost = (float) (r_len * r_len - l_len * l_len) * (1 / (r_len * l_len));
+                }
+                else
+                {
+                    cost = (float) (l_len * l_len - r_len * r_len) * (1 / (r_len * l_len));
+                }
+            }                   /* if */
+
+            len_color = r_color - l_color;
+
+            cost1 = (float) ((len_color * len_color) >> 2);
+
+            min2 = costTable[i_1 + j * row_size] + Occlusion * l_len;
+
+            min3 = costTable[i + j_1 * row_size] + Occlusion * r_len;
+
+            min1 = costTable[i_1 + j_1 * row_size] + cost + (float) cost1;
+
+            if( min1 < min2 )
+            {
+
+                if( min1 < min3 )
+                {
+                    cmin = min1;
+                    cpath = 1;
+                }
+                else
+                {
+                    cmin = min3;
+                    cpath = 3;
+                }               /* if */
+
+            }
+            else
+            {
+
+                if( min2 < min3 )
+                {
+                    cmin = min2;
+                    cpath = 2;
+                }
+                else
+                {
+                    cmin = min3;
+                    cpath = 3;
+                }               /* if */
+
+            }                   /* if */
+
+            costTable[i + j * row_size] = cmin;
+            matchEdges[i + j * row_size] = cpath;
+        }                       /* for */
+    }                           /* for */
+
+    /* =========== Reconstruct the Path =========== */
+
+    i = first_runs;
+    j = second_runs;
+
+    first_curr = i * 2 - 2;
+    second_curr = j * 2 - 2;
+
+
+    while( i > 0 && j > 0 )
+    {
+
+        /* Connect begins */
+        switch (matchEdges[i + j * row_size])
+        {
+
+        case 1:                /* to diagonal */
+
+            first_corr[first_curr] = second[second_curr];
+            first_corr[first_curr + 1] = second[second_curr + 2];
+            second_corr[second_curr] = first[first_curr];
+            second_corr[second_curr + 1] = first[first_curr + 2];
+
+            first_curr -= 2;
+            second_curr -= 2;
+            i--;
+            j--;
+
+            break;
+
+        case 2:                /* to left */
+
+            first_corr[first_curr] = second[second_curr + 2];
+            first_corr[first_curr + 1] = second[second_curr + 2];
+
+            first_curr -= 2;
+            i--;
+
+            break;
+
+        case 3:                /* to up */
+
+            second_corr[second_curr] = first[first_curr + 2];
+            second_corr[second_curr + 1] = first[first_curr + 2];
+
+            second_curr -= 2;
+            j--;
+
+            break;
+        }                       /* switch */
+    }                           /* while */
+
+    /* construct rest of horisontal path if its need */
+    while( i > 0 )
+    {
+
+        first_corr[first_curr] = second[second_curr + 2];       /* connect to begin */
+        first_corr[first_curr + 1] = second[second_curr + 2];   /* connect to begin */
+
+        first_curr -= 2;
+        i--;
+
+    }                           /* while */
+
+    /* construct rest of vertical path if its need */
+    while( j > 0 )
+    {
+
+        second_corr[second_curr] = first[first_curr + 2];
+        second_corr[second_curr + 1] = first[first_curr + 2];
+
+        second_curr -= 2;
+        j--;
+
+    }                           /* while */
+
+    cvFree( &costTable );
+    cvFree( &matchEdges );
+
+    return CV_NO_ERR;
+}                               /* icvDynamicCorrespond */
+
+
+/*======================================================================================*/
+
+static CvStatus
+icvDynamicCorrespondMulti( int lines,   /* number of scanlines */
+                           int *first,  /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
+                           int *first_runs,     /* numbers of runs */
+                           int *second, int *second_runs, int *first_corr,      /* s0'|e0'|s1'|e1'|... */
+                           int *second_corr )
+{
+    CvStatus error;
+
+    int currFirst;
+    int currSecond;
+    int currFirstCorr;
+    int currSecondCorr;
+    int n;
+
+    /* Test errors */
+
+    if( (lines < 1) ||
+        (first == 0) ||
+        (first_runs == 0) ||
+        (second == 0) || (second_runs == 0) || (first_corr == 0) || (second_corr == 0) )
+        return CV_BADFACTOR_ERR;
+
+    currFirst = 0;
+    currSecond = 0;
+    currFirstCorr = 0;
+    currSecondCorr = 0;
+
+    for( n = 0; n < lines; n++ )
+    {
+
+        error = icvDynamicCorrespond( &(first[currFirst]),
+                                      first_runs[n],
+                                      &(second[currSecond]),
+                                      second_runs[n],
+                                      &(first_corr[currFirstCorr]),
+                                      &(second_corr[currSecondCorr]) );
+
+        if( error != CV_NO_ERR )
+            return error;
+
+        currFirst += first_runs[n] * 2 + 1;
+        currSecond += second_runs[n] * 2 + 1;
+        currFirstCorr += first_runs[n] * 2;
+        currSecondCorr += second_runs[n] * 2;
+
+    }
+
+    return CV_NO_ERR;
+
+}                               /* icvDynamicCorrespondMulti */
+
+
+/*======================================================================================*/
+
+/*F///////////////////////////////////////////////////////////////////////////////////////
+//    Name: cvDynamicCorrespondMulti
+//    Purpose: The functions 
+//    Context:
+//    Parameters:  
+//
+//    Notes:  
+//F*/
+CV_IMPL void
+cvDynamicCorrespondMulti( int lines,    /* number of scanlines */
+                          int *first,   /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
+                          int *first_runs,      /* numbers of runs */
+                          int *second, int *second_runs, int *first_corr,       /* s0'|e0'|s1'|e1'|... */
+                          int *second_corr )
+{
+    IPPI_CALL( icvDynamicCorrespondMulti( lines,        /* number of scanlines */
+                                          first,        /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
+                                          first_runs,   /* numbers of runs */
+                                          second, second_runs, first_corr,      /* s0'|e0'|s1'|e1'|... */
+                                          second_corr ));
+}