34 #ifndef __INCLUDE_DP_MATCHING_H__
35 #define __INCLUDE_DP_MATCHING_H__
50 template<
typename Type >
51 struct square_error :
public std::binary_function< Type, Type, double >
53 double operator( )(
const Type &v0,
const Type &v1 )
const
55 return ( static_cast< double >( v0 ) - v1 ) * ( static_cast< double >( v0 ) - v1 );
60 template<
typename Type >
61 struct square_error< mist::rgb< Type > > :
public std::binary_function< mist::rgb< Type >, mist::rgb< Type >, double >
65 return ( static_cast< double >( v0.r ) - v1.r ) * ( static_cast< double >( v0.r ) - v1.r ) + ( static_cast< double >( v0.g ) - v1.g ) * ( static_cast< double >( v0.g ) - v1.g ) + ( static_cast< double >( v0.b ) - v1.b ) * ( static_cast< double >( v0.b ) - v1.b );
82 dp_pair(
const size_t a,
const size_t b ) : a_( a ), b_( b )
97 inline bool operator !=(
const dp_pair &p0,
const dp_pair &p1 )
99 return ( ( p0.a( ) != p1.a( ) ) || ( p0.b( ) != p1.b( ) ) );
102 inline std::ostream &
operator <<( std::ostream &out,
const dp_pair &in )
104 return ( out <<
"( " << in.a( ) <<
", " << in.b( ) <<
" )" );
174 template<
typename Value_type,
typename Functor = __dp__::square_error< Value_type > >
177 typedef typename Functor::result_type distance_type;
182 distance_type distance_;
188 distance_type __distance(
const size_t i0,
const size_t i1 )
const
190 return func_( pattern_a_[ i0 ], pattern_b_[ i1 ] );
197 distance_array( 0, 0 ) = __distance( 0, 0 );
198 for(
size_t i = 1 ; i < distance_array.width( ) ; i ++ )
200 distance_array( i, 0 ) =
static_cast< distance_type
>( distance_array( i - 1, 0 ) + __distance( i, 0 ) * weight_0_ );
201 path_array( i, 0 ) = 0;
203 for(
size_t j = 1 ; j < distance_array.height( ) ; j ++ )
205 distance_array( 0, j ) =
static_cast< distance_type
>( distance_array( 0, j - 1 ) + __distance( 0, j ) * weight_2_ );
206 path_array( 0, j ) = 2;
207 for(
size_t i = 1 ; i < distance_array.width( ) ; i ++ )
209 const distance_type
distance = __distance( i, j );
210 const distance_type distance_0 =
static_cast< distance_type
>( distance_array( i - 1, j ) + distance * weight_0_ );
211 const distance_type distance_1 =
static_cast< distance_type
>( distance_array( i - 1, j - 1 ) + distance * weight_1_ );
212 const distance_type distance_2 =
static_cast< distance_type
>( distance_array( i, j - 1 ) + distance * weight_2_ );
213 path_array( i, j ) = ( distance_0 < distance_1 ) ? ( ( distance_0 < distance_2 ) ? 0 : 2 ) : ( ( distance_1 < distance_2 ) ? 1 : 2 );
214 switch( path_array( i, j ) )
217 distance_array( i, j ) = distance_0;
220 distance_array( i, j ) = distance_1;
223 distance_array( i, j ) = distance_2;
230 distance_ = distance_array( distance_array.width( ) - 1, distance_array.height( ) - 1 );
231 std::vector< dp_pair >
path;
232 path.reserve( pattern_a_.
size( ) );
233 size_t mi = pattern_a_.
size( ) - 1;
234 size_t mj = pattern_b_.
size( ) - 1;
235 path.push_back( dp_pair( mi, mj ) );
236 while( dp_pair( mi, mj ) != dp_pair( 0, 0 ) )
238 switch( path_array( mi, mj ) )
241 path.push_back( dp_pair( -- mi, mj ) );
244 path.push_back( dp_pair( -- mi, -- mj ) );
247 path.push_back( dp_pair( mi, -- mj ) );
253 path_.
resize( path.size( ) );
254 for(
size_t i = 0 ; i < path_.
size( ) ; i ++ )
256 path_[ i ] = path[ path_.
size( ) - 1 - i ];
272 : pattern_a_( pattern_a ), pattern_b_( pattern_b ), weight_0_( weight_0 ), weight_1_( weight_1 ), weight_2_( weight_2 ), func_( func )
283 void weights(
const double weight_0,
const double weight_1,
const double weight_2 )
285 weight_0_ = weight_0;
286 weight_1_ = weight_1;
287 weight_2_ = weight_2;
306 return path_.
size( );
328 #endif // __INCLUDE_DP_MATCHING_H__