Go to the documentation of this file.00001
00002 #include "rgrl_feature_face_region.h"
00003 #include <rgrl/rgrl_transformation.h>
00004 #include <vnl/algo/vnl_svd.h>
00005
00006 #include <vcl_cassert.h>
00007 #include <rgrl/rgrl_cast.h>
00008 #include <rgrl/rgrl_util.h>
00009
00010 rgrl_feature_face_region ::
00011 rgrl_feature_face_region( vnl_vector< double > const& location,
00012 vnl_vector< double > const& normal )
00013 : rgrl_feature_face_pt( location, normal ),
00014 thickness_( 0.0 ), radius_( 0.0 )
00015 {
00016 }
00017
00018
00019 rgrl_feature_face_region ::
00020 rgrl_feature_face_region( vnl_vector< double > const& location,
00021 vnl_vector< double > const& normal,
00022 double thickness,
00023 double radius )
00024 : rgrl_feature_face_pt( location, normal ),
00025 thickness_( thickness ), radius_( radius )
00026 {
00027 }
00028
00029
00030
00031 rgrl_feature_face_region ::
00032 rgrl_feature_face_region()
00033 : rgrl_feature_face_pt(),
00034 thickness_( 0 ), radius_( 0 )
00035 {
00036 }
00037
00038 unsigned int
00039 rgrl_feature_face_region::
00040 num_constraints() const
00041 {
00042 return 1;
00043 }
00044
00045 rgrl_feature_sptr
00046 rgrl_feature_face_region::
00047 transform( rgrl_transformation const& xform ) const
00048 {
00049 rgrl_feature_face_region* face_ptr = new rgrl_feature_face_region();
00050
00051
00052 rgrl_feature_sptr result_sptr = face_ptr;
00053
00054 xform.map_location( this->location_, face_ptr->location_ );
00055 xform.map_normal( this->location_, this->normal_, face_ptr->normal_ );
00056
00057 face_ptr->err_proj_ = outer_product( face_ptr->normal_, face_ptr->normal_ );
00058 face_ptr->thickness_ = this->thickness_;
00059 face_ptr->radius_ = this->radius_;
00060 return result_sptr;
00061 }
00062
00063
00064 rgrl_feature_sptr
00065 rgrl_feature_face_region ::
00066 transform_region( rgrl_transformation const& xform ) const
00067 {
00068
00069 rgrl_feature_sptr result_sptr = this -> transform( xform );
00070
00071
00072 rgrl_feature_face_region * face_ptr
00073 = rgrl_cast<rgrl_feature_face_region *> ( result_sptr );
00074
00075
00076
00077
00078
00079
00080 vnl_vector< double > end_point( this -> location_ . size() );
00081 xform . map_location( this -> location_ + this->thickness_ / 2.0
00082 * this -> normal_, end_point );
00083 face_ptr -> thickness_ = ( end_point - face_ptr -> location_) . magnitude() * 2.0;
00084
00085
00086
00087
00088
00089 vnl_matrix<double> one_row( 1, this -> normal_.size() );
00090 one_row.set_row( 0, this -> normal_ );
00091 vnl_svd<double> normal_svd( one_row );
00092 vnl_matrix<double> nullspace = normal_svd.nullspace();
00093 assert( nullspace . columns() == this -> normal_ . size() - 1 );
00094
00095
00096
00097
00098
00099
00100 vnl_vector< double > point_along_dir( this->location_.size() );
00101 double sum_radii = 0;
00102
00103 double this_radius = this->radius_;
00104 for ( unsigned int i=0; i+1 < this -> location_ . size(); ++i )
00105 {
00106 point_along_dir = this -> location();
00107 point_along_dir += this_radius * nullspace . get_column( i );
00108 xform . map_location( point_along_dir, end_point );
00109 sum_radii += ( end_point - face_ptr -> location_ ) . magnitude();
00110 }
00111
00112 face_ptr -> radius_ = sum_radii / ( this -> location_ . size() - 1 );
00113
00114 return result_sptr;
00115 }
00116
00117
00118
00119 void
00120 rgrl_feature_face_region ::
00121 generate_pixel_coordinates( vnl_vector< double > const& spacing_ratio )
00122 {
00123
00124
00125
00126
00127
00128
00129 unsigned int dim = this -> location_ . size();
00130 vnl_matrix< double > tangents = this -> tangent_subspace();
00131 vcl_vector< vnl_vector<double> > directions;
00132 directions.reserve( dim );
00133
00134
00135
00136
00137 vnl_vector< double > location_in_pixel( dim );
00138 vnl_vector< double > radii_in_pixel( dim );
00139 vnl_vector< double > directions_in_pixel( dim );
00140
00141 vnl_vector< double > direction_in_pixel( dim );
00142 for ( unsigned int i = 0; i < dim; ++i )
00143 {
00144 direction_in_pixel[ i ] = this->normal_[ i ] / spacing_ratio[ i ];
00145 location_in_pixel[ i ] = this->location_[ i ] / spacing_ratio[ i ];
00146 }
00147 directions.push_back( direction_in_pixel );
00148
00149 radii_in_pixel[ 0 ] = this -> thickness_ / spacing_ratio[ 0 ] / 2.0;
00150 for ( unsigned int i = 0; i < dim-1; ++i )
00151 {
00152 direction_in_pixel = tangents.get_column( i );
00153 for ( unsigned j = 0; j < dim; ++j )
00154 {
00155 direction_in_pixel[ j ] /= spacing_ratio[ j ];
00156 }
00157 directions.push_back( direction_in_pixel );
00158 radii_in_pixel[ i+1 ] = this -> radius_ / spacing_ratio[ i+1 ];
00159 }
00160
00161
00162
00163
00164 rgrl_util_extract_region_locations( location_in_pixel, directions,
00165 radii_in_pixel, pixel_coordinates_ );
00166
00167 pixel_coordinates_cached_ = true;
00168 }
00169
00170 rgrl_feature_sptr
00171 rgrl_feature_face_region::clone() const
00172 {
00173 return new rgrl_feature_face_region(*this);
00174 }
00175
00176 #if 0 // Keep this for mapping --- move to different code
00177
00178 void
00179 rgrl_feature_face_region :: set_tangents()
00180 {
00181 vnl_matrix<double> one_row( 1, normal_.size() );
00182 one_row.set_row( 0, normal_ );
00183 vnl_svd<double> normal_svd( one_row );
00184
00185 tangent_directions_.clear();
00186 for ( unsigned int i=1; i<normal_.size(); ++i )
00187 {
00188 tangent_directions_.push_back( normal_svd.V().get_column( i ) );
00189 }
00190 }
00191
00192 #endif // 0