summaryrefslogtreecommitdiff
path: root/cvaux/src/cvcorrespond.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cvaux/src/cvcorrespond.cpp')
-rw-r--r--cvaux/src/cvcorrespond.cpp403
1 files changed, 403 insertions, 0 deletions
diff --git a/cvaux/src/cvcorrespond.cpp b/cvaux/src/cvcorrespond.cpp
new file mode 100644
index 0000000..c0c55e1
--- /dev/null
+++ b/cvaux/src/cvcorrespond.cpp
@@ -0,0 +1,403 @@
+/*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 )
+{
+ CV_FUNCNAME( "cvDynamicCorrespondMulti" );
+ __BEGIN__;
+
+ 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 ));
+ __CLEANUP__;
+ __END__;
+}