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
00019 #include <mitkImageToSurfaceFilter.h>
00020
00021 #include <vtkImageData.h>
00022 #include <vtkDecimatePro.h>
00023 #include <vtkImageChangeInformation.h>
00024 #include <vtkLinearTransform.h>
00025 #include <vtkMath.h>
00026 #include <vtkMatrix4x4.h>
00027
00028 #if (VTK_MAJOR_VERSION < 5)
00029 #include <vtkDecimate.h>
00030 #endif
00031
00032 #include "mitkProgressBar.h"
00033
00034 mitk::ImageToSurfaceFilter::ImageToSurfaceFilter():
00035 m_Smooth(false),
00036 m_Decimate( NoDecimation),
00037 m_Threshold(1.0),
00038 m_TargetReduction(0.95f),
00039 m_SmoothIteration(50),
00040 m_SmoothRelaxation(0.1)
00041 {
00042 }
00043
00044 mitk::ImageToSurfaceFilter::~ImageToSurfaceFilter()
00045 {
00046 }
00047
00048 void mitk::ImageToSurfaceFilter::CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface * surface, const ScalarType threshold)
00049 {
00050 vtkImageChangeInformation *indexCoordinatesImageFilter = vtkImageChangeInformation::New();
00051 indexCoordinatesImageFilter->SetInput(vtkimage);
00052 indexCoordinatesImageFilter->SetOutputOrigin(0.0,0.0,0.0);
00053
00054
00055 vtkMarchingCubes *skinExtractor = vtkMarchingCubes::New();
00056 skinExtractor->ComputeScalarsOff();
00057 skinExtractor->SetInput(indexCoordinatesImageFilter->GetOutput());
00058 indexCoordinatesImageFilter->Delete();
00059 skinExtractor->SetValue(0, threshold);
00060
00061 vtkPolyData *polydata;
00062 polydata = skinExtractor->GetOutput();
00063 polydata->Register(NULL);
00064 skinExtractor->Delete();
00065
00066 if (m_Smooth)
00067 {
00068 vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New();
00069
00070 smoother->SetInput(polydata);
00071 smoother->SetNumberOfIterations( m_SmoothIteration );
00072 smoother->SetRelaxationFactor( m_SmoothRelaxation );
00073 smoother->SetFeatureAngle( 60 );
00074 smoother->FeatureEdgeSmoothingOff();
00075 smoother->BoundarySmoothingOff();
00076 smoother->SetConvergence( 0 );
00077
00078 polydata->Delete();
00079 polydata = smoother->GetOutput();
00080 polydata->Register(NULL);
00081 smoother->Delete();
00082 }
00083 ProgressBar::GetInstance()->Progress();
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 if(m_Decimate==DecimatePro)
00096 {
00097 vtkDecimatePro *decimate = vtkDecimatePro::New();
00098 decimate->SplittingOff();
00099 decimate->SetErrorIsAbsolute(5);
00100 decimate->SetFeatureAngle(30);
00101 decimate->PreserveTopologyOn();
00102 decimate->BoundaryVertexDeletionOff();
00103 decimate->SetDegree(10);
00104
00105 decimate->SetInput(polydata);
00106 decimate->SetTargetReduction(m_TargetReduction);
00107 decimate->SetMaximumError(0.002);
00108
00109 polydata->Delete();
00110 polydata = decimate->GetOutput();
00111 polydata->Register(NULL);
00112 decimate->Delete();
00113 }
00114 #if (VTK_MAJOR_VERSION < 5)
00115 else if (m_Decimate==Decimate)
00116 {
00117 vtkDecimate *decimate = vtkDecimate::New();
00118 decimate->SetInput( polydata );
00119 decimate->PreserveTopologyOn();
00120 decimate->BoundaryVertexDeletionOff();
00121 decimate->SetTargetReduction( m_TargetReduction );
00122 polydata->Delete();
00123 polydata = decimate->GetOutput();
00124 polydata->Register(NULL);
00125 decimate->Delete();
00126 }
00127 #endif
00128
00129 polydata->Update();
00130 ProgressBar::GetInstance()->Progress();
00131
00132 polydata->SetSource(NULL);
00133
00134 if(polydata->GetNumberOfPoints() > 0)
00135 {
00136 mitk::Vector3D spacing = GetInput()->GetGeometry(time)->GetSpacing();
00137
00138 vtkPoints * points = polydata->GetPoints();
00139 vtkMatrix4x4 *vtkmatrix = vtkMatrix4x4::New();
00140 GetInput()->GetGeometry(time)->GetVtkTransform()->GetMatrix(vtkmatrix);
00141 double (*matrix)[4] = vtkmatrix->Element;
00142
00143 unsigned int i,j;
00144 for(i=0;i<3;++i)
00145 for(j=0;j<3;++j)
00146 matrix[i][j]/=spacing[j];
00147
00148 unsigned int n = points->GetNumberOfPoints();
00149 vtkFloatingPointType point[3];
00150
00151 for (i = 0; i < n; i++)
00152 {
00153 points->GetPoint(i, point);
00154 mitkVtkLinearTransformPoint(matrix,point,point);
00155 points->SetPoint(i, point);
00156 }
00157 vtkmatrix->Delete();
00158 }
00159 ProgressBar::GetInstance()->Progress();
00160
00161 surface->SetVtkPolyData(polydata, time);
00162 polydata->UnRegister(NULL);
00163 }
00164
00165
00166 void mitk::ImageToSurfaceFilter::GenerateData()
00167 {
00168 mitk::Surface *surface = this->GetOutput();
00169 mitk::Image * image = (mitk::Image*)GetInput();
00170 mitk::Image::RegionType outputRegion = image->GetRequestedRegion();
00171
00172 int tstart=outputRegion.GetIndex(3);
00173 int tmax=tstart+outputRegion.GetSize(3);
00174
00175 if ((tmax-tstart) > 0)
00176 {
00177 ProgressBar::GetInstance()->AddStepsToDo( 4 * (tmax - tstart) );
00178 }
00179
00180
00181 int t;
00182 for( t=tstart; t < tmax; ++t)
00183 {
00184 vtkImageData *vtkimagedata = image->GetVtkImageData(t);
00185 CreateSurface(t,vtkimagedata,surface,m_Threshold);
00186 ProgressBar::GetInstance()->Progress();
00187 }
00188 }
00189
00190 void mitk::ImageToSurfaceFilter::SetSmoothIteration(int smoothIteration)
00191 {
00192 m_SmoothIteration = smoothIteration;
00193 }
00194
00195 void mitk::ImageToSurfaceFilter::SetSmoothRelaxation(float smoothRelaxation)
00196 {
00197 m_SmoothRelaxation = smoothRelaxation;
00198 }
00199
00200 void mitk::ImageToSurfaceFilter::SetInput(const mitk::Image *image)
00201 {
00202
00203 this->ProcessObject::SetNthInput(0, const_cast< mitk::Image * >( image ) );
00204 }
00205
00206
00207 const mitk::Image *mitk::ImageToSurfaceFilter::GetInput(void)
00208 {
00209 if (this->GetNumberOfInputs() < 1)
00210 {
00211 return 0;
00212 }
00213
00214 return static_cast<const mitk::Image * >
00215 ( this->ProcessObject::GetInput(0) );
00216 }
00217
00218
00219 void mitk::ImageToSurfaceFilter::GenerateOutputInformation()
00220 {
00221 mitk::Image::ConstPointer inputImage =(mitk::Image*) this->GetInput();
00222
00223
00224 mitk::Surface::Pointer output = this->GetOutput();
00225
00226 itkDebugMacro(<<"GenerateOutputInformation()");
00227
00228 if(inputImage.IsNull()) return;
00229
00230
00231 }