diff options
Diffstat (limited to 'cvaux/src/cvcorrespond.cpp')
-rw-r--r-- | cvaux/src/cvcorrespond.cpp | 403 |
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__; +} |