Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkPlaneFit.h"
00019
00020 #include "mitkPlaneGeometry.h"
00021 #include "mitkGeometryData.h"
00022
00023 #include <vnl/algo/vnl_svd.h>
00024 #include <vcl_iostream.h>
00025
00026
00027 mitk::PlaneFit::PlaneFit()
00028 : m_PointSet( NULL )
00029 {
00030 m_TimeSlicedGeometry = mitk::TimeSlicedGeometry::New();
00031 }
00032
00033 mitk::PlaneFit::~PlaneFit()
00034 {
00035 }
00036
00037
00038 void mitk::PlaneFit::GenerateOutputInformation()
00039 {
00040 mitk::PointSet::ConstPointer input = this->GetInput();
00041 mitk::GeometryData::Pointer output = this->GetOutput();
00042
00043 itkDebugMacro(<<"GenerateOutputInformation()");
00044
00045 if (input.IsNull()) return;
00046
00047 if ( m_PointSet == NULL )
00048 {
00049 return;
00050 }
00051
00052 bool update = false;
00053 if ( output->GetGeometry() == NULL || output->GetTimeSlicedGeometry() == NULL )
00054 update = true;
00055 if ( ( ! update ) && ( output->GetTimeSlicedGeometry()->GetTimeSteps() != input->GetTimeSlicedGeometry()->GetTimeSteps() ) )
00056 update = true;
00057 if ( update )
00058 {
00059 mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
00060
00061 m_TimeSlicedGeometry->InitializeEvenlyTimed(
00062 planeGeometry, m_PointSet->GetPointSetSeriesSize() );
00063
00064 unsigned int t;
00065 for ( t = 0;
00066 (t < m_PointSet->GetPointSetSeriesSize())
00067 && (t < m_Planes.size());
00068 ++t )
00069 {
00070 m_TimeSlicedGeometry->SetGeometry3D( m_Planes[t], (int) t );
00071 }
00072
00073 output->SetGeometry( m_TimeSlicedGeometry );
00074 }
00075 }
00076
00077 void mitk::PlaneFit::GenerateData()
00078 {
00079 unsigned int t;
00080 for ( t = 0; t < m_PointSet->GetPointSetSeriesSize(); ++t )
00081 {
00082
00083 if ( m_PointSet->GetSize( t ) >= 3 )
00084 {
00085 this->CalculateCentroid( t );
00086
00087 this->ProcessPointSet( t );
00088
00089 this->InitializePlane( t );
00090 }
00091 }
00092 }
00093
00094 void mitk::PlaneFit::SetInput( const mitk::PointSet* pointSet )
00095 {
00096
00097 this->ProcessObject::SetNthInput(0,
00098 const_cast< mitk::PointSet * >( pointSet ) );
00099
00100 m_PointSet = pointSet;
00101 unsigned int pointSetSize = pointSet->GetPointSetSeriesSize();
00102
00103 m_Planes.resize( pointSetSize );
00104 m_Centroids.resize( pointSetSize );
00105 m_PlaneVectors.resize( pointSetSize );
00106
00107 unsigned int t;
00108 for ( t = 0; t < pointSetSize; ++t )
00109 {
00110 m_Planes[t] = mitk::PlaneGeometry::New();
00111 }
00112 }
00113
00114 const mitk::PointSet* mitk::PlaneFit::GetInput()
00115 {
00116 if (this->GetNumberOfInputs() < 1)
00117 {
00118 return 0;
00119 }
00120
00121 return static_cast<const mitk::PointSet * > (this->ProcessObject::GetInput(0) );
00122 }
00123
00124
00125 void mitk::PlaneFit::CalculateCentroid( int t )
00126 {
00127 if ( m_PointSet == NULL ) return;
00128
00129 int ps_total = m_PointSet->GetSize( t );
00130
00131 m_Centroids[t][0] = m_Centroids[t][1] = m_Centroids[t][2] = 0.0;
00132
00133
00134 mitk::PointSet::PointsContainer::Iterator pit, end;
00135 pit = m_PointSet->GetPointSet( t )->GetPoints()->Begin();
00136 end = m_PointSet->GetPointSet( t )->GetPoints()->End();
00137 for ( ; pit!=end; ++pit )
00138 {
00139 mitk::Point3D p3d = pit.Value();
00140 m_Centroids[t][0] += p3d[0];
00141 m_Centroids[t][1] += p3d[1];
00142 m_Centroids[t][2] += p3d[2];
00143 }
00144
00145
00146 m_Centroids[t][0] /= ps_total;
00147 m_Centroids[t][1] /= ps_total;
00148 m_Centroids[t][2] /= ps_total;
00149 }
00150
00151
00152 void mitk::PlaneFit::ProcessPointSet( int t )
00153 {
00154 if (m_PointSet == NULL ) return;
00155
00156
00157 vnl_matrix<mitk::ScalarType> dataM( m_PointSet->GetSize( t ), 3);
00158
00159
00160 mitk::PointSet::PointsContainer::Iterator pit, end;
00161 pit = m_PointSet->GetPointSet( t )->GetPoints()->Begin();
00162 end = m_PointSet->GetPointSet( t )->GetPoints()->End();
00163
00164 for (int p=0; pit!=end; pit++, p++)
00165 {
00166 mitk::Point3D p3d = pit.Value();
00167 dataM[p][0] = p3d[0] - m_Centroids[t][0];
00168 dataM[p][1] = p3d[1] - m_Centroids[t][1];
00169 dataM[p][2] = p3d[2] - m_Centroids[t][2];
00170 }
00171
00172
00173
00174 vnl_svd<mitk::ScalarType> svd(dataM, 0.0);
00175
00176
00177 vnl_vector<mitk::ScalarType> v = svd.nullvector();
00178
00179
00180
00181
00182 if ( v[0] < 0 )
00183 {
00184 v = -v;
00185 }
00186
00187 m_PlaneVectors[t][0] = v[0];
00188 m_PlaneVectors[t][1] = v[1];
00189 m_PlaneVectors[t][2] = v[2];
00190
00191 }
00192
00193 mitk::PlaneGeometry::Pointer mitk::PlaneFit::GetPlaneGeometry( int t )
00194 {
00195 return m_Planes[t];
00196 }
00197
00198 const mitk::Vector3D &mitk::PlaneFit::GetPlaneNormal( int t ) const
00199 {
00200 return m_PlaneVectors[t];
00201 }
00202
00203 const mitk::Point3D &mitk::PlaneFit::GetCentroid( int t ) const
00204 {
00205 return m_Centroids[t];
00206 }
00207
00208 void mitk::PlaneFit::InitializePlane( int t )
00209 {
00210 m_Planes[t]->InitializePlane( m_Centroids[t], m_PlaneVectors[t] );
00211 }
00212