17 #ifndef __itkEvaluateDirectionImagesFilter_cpp
18 #define __itkEvaluateDirectionImagesFilter_cpp
21 #include <itkImageRegionConstIterator.h>
22 #include <itkImageRegionIterator.h>
23 #include <itkImageDuplicator.h>
24 #include <boost/progress.hpp>
26 #define _USE_MATH_DEFINES
31 template<
class PixelType >
35 m_ReferenceImageSet(NULL),
36 m_IgnoreMissingDirections(false),
37 m_IgnoreEmptyVoxels(false),
40 this->SetNumberOfIndexedOutputs(2);
43 template<
class PixelType >
46 if (m_ImageSet.IsNull() || m_ReferenceImageSet.IsNull())
52 for (
unsigned int i=0; i<m_ImageSet->Size(); i++)
55 duplicator->SetInputImage( m_ImageSet->GetElement(i) );
57 set1->InsertElement(i, dynamic_cast<DirectionImageType*>(duplicator->GetOutput()));
59 for (
unsigned int i=0; i<m_ReferenceImageSet->Size(); i++)
62 duplicator->SetInputImage( m_ReferenceImageSet->GetElement(i) );
64 set2->InsertElement(i, dynamic_cast<DirectionImageType*>(duplicator->GetOutput()));
68 m_ReferenceImageSet = set2;
72 outputImage->SetOrigin( m_ReferenceImageSet->GetElement(0)->GetOrigin() );
73 outputImage->SetRegions( m_ReferenceImageSet->GetElement(0)->GetLargestPossibleRegion() );
74 outputImage->SetSpacing( m_ReferenceImageSet->GetElement(0)->GetSpacing() );
75 outputImage->SetDirection( m_ReferenceImageSet->GetElement(0)->GetDirection() );
76 outputImage->Allocate();
77 outputImage->FillBuffer(0.0);
78 this->SetNthOutput(0, outputImage);
82 outputImage->SetOrigin( m_ReferenceImageSet->GetElement(0)->GetOrigin() );
83 outputImage->SetRegions( m_ReferenceImageSet->GetElement(0)->GetLargestPossibleRegion() );
84 outputImage->SetSpacing( m_ReferenceImageSet->GetElement(0)->GetSpacing() );
85 outputImage->SetDirection( m_ReferenceImageSet->GetElement(0)->GetDirection() );
86 outputImage->Allocate();
87 outputImage->FillBuffer(0.0);
88 this->SetNthOutput(1, outputImage);
90 if (m_MaskImage.IsNull())
93 m_MaskImage->SetOrigin( outputImage->GetOrigin() );
94 m_MaskImage->SetRegions( outputImage->GetLargestPossibleRegion() );
95 m_MaskImage->SetSpacing( outputImage->GetSpacing() );
96 m_MaskImage->SetDirection( outputImage->GetDirection() );
97 m_MaskImage->Allocate();
98 m_MaskImage->FillBuffer(1);
101 m_MeanAngularError = 0.0;
102 m_MedianAngularError = 0;
103 m_MaxAngularError = 0.0;
105 m_VarAngularError = 0.0;
106 m_AngularErrorVector.clear();
108 m_MeanLengthError = 0.0;
109 m_MedianLengthError = 0;
110 m_MaxLengthError = 0.0;
112 m_VarLengthError = 0.0;
113 m_LengthErrorVector.clear();
115 if (m_ImageSet.IsNull() || m_ReferenceImageSet.IsNull())
118 outputImage =
static_cast< OutputImageType*
>(this->ProcessObject::GetOutput(0));
121 ImageRegionIterator< OutputImageType > oit(outputImage, outputImage->GetLargestPossibleRegion());
122 ImageRegionIterator< OutputImageType > oit2(outputImage2, outputImage2->GetLargestPossibleRegion());
123 ImageRegionIterator< UCharImageType > mit(m_MaskImage, m_MaskImage->GetLargestPossibleRegion());
125 int numTestImages = m_ImageSet->Size();
126 int numReferenceImages = m_ReferenceImageSet->Size();
127 int maxNumDirections =
std::max(numReferenceImages, numTestImages);
130 vnl_matrix< float > diffM; diffM.set_size(maxNumDirections, maxNumDirections);
132 boost::progress_display disp(outputImage->GetLargestPossibleRegion().GetSize()[0]*outputImage->GetLargestPossibleRegion().GetSize()[1]*outputImage->GetLargestPossibleRegion().GetSize()[2]);
133 while( !oit.IsAtEnd() )
143 typename OutputImageType::IndexType index = oit.GetIndex();
145 float maxAngularError = 1.0;
152 std::vector< vnl_vector_fixed< PixelType, 3 > > testDirs;
153 std::vector< vnl_vector_fixed< PixelType, 3 > > refDirs;
154 for (
int i=0; i<numReferenceImages; i++)
156 vnl_vector_fixed< PixelType, 3 > refDir = m_ReferenceImageSet->GetElement(i)->GetPixel(index).GetVnlVector();
157 if (refDir.magnitude() > m_Eps )
160 refDirs.push_back(refDir);
164 for (
int i=0; i<numTestImages; i++)
166 vnl_vector_fixed< PixelType, 3 > testDir = m_ImageSet->GetElement(i)->GetPixel(index).GetVnlVector();
167 if (testDir.magnitude() > m_Eps )
170 testDirs.push_back(testDir);
175 if (m_IgnoreEmptyVoxels && (numRefDirs==0 || numTestDirs==0) )
185 for (
int i=0; i<maxNumDirections; i++)
187 bool missingDir =
false;
188 vnl_vector_fixed< PixelType, 3 > refDir;
191 refDir = refDirs.at(i);
192 else if (m_IgnoreMissingDirections)
197 for (
int j=0; j<maxNumDirections; j++)
199 vnl_vector_fixed< PixelType, 3 > testDir;
201 testDir = testDirs.at(j);
202 else if (m_IgnoreMissingDirections || missingDir)
215 diffM[i][j] = fabs(dot_product(refDir, testDir));
217 if (diffM[i][j] < maxAngularError)
218 maxAngularError = diffM[i][j];
225 float angularError = 0.0;
226 float lengthError = 0.0;
228 vnl_matrix< float > diffM_copy = diffM;
229 for (
int k=0; k<maxNumDirections; k++)
233 bool missingDir =
false;
238 for (
int i=0; i<maxNumDirections; i++)
239 for (
int j=0; j<maxNumDirections; j++)
241 if (diffM[i][j]>error && diffM[i][j]<2)
248 else if (diffM[i][j]<0 && error<0)
256 if (a<0 || b<0 || (m_IgnoreMissingDirections && missingDir))
259 if (a>=numRefDirs && b>=numTestDirs)
261 MITK_INFO <<
"ERROR: missing test and reference direction. should not be possible. check code.";
266 diffM.set_row(a, 10.0);
267 diffM.set_column(b, 10.0);
271 for (
int i=0; i<numRefDirs; i++)
272 if (diffM_copy[i][b]>error)
274 error = diffM_copy[i][b];
278 else if (b>=numTestDirs)
280 for (
int i=0; i<numTestDirs; i++)
281 if (diffM_copy[a][i]>error)
283 error = diffM_copy[a][i];
289 float testLength = 1;
291 if (a>=numRefDirs || b>=numTestDirs || error<0)
295 refLength = m_ReferenceImageSet->GetElement(a)->GetPixel(index).GetVnlVector().magnitude();
296 testLength = m_ImageSet->GetElement(b)->GetPixel(index).GetVnlVector().magnitude();
299 m_LengthErrorVector.push_back( fabs(refLength-testLength) );
300 m_AngularErrorVector.push_back( acos(error)*180.0/
M_PI );
302 m_MeanAngularError += m_AngularErrorVector.back();
303 m_MeanLengthError += m_LengthErrorVector.back();
305 angularError += m_AngularErrorVector.back();
306 lengthError += m_LengthErrorVector.back();
312 lengthError /= counter;
313 angularError /= counter;
315 oit2.Set(lengthError);
316 oit.Set(angularError);
323 std::sort( m_AngularErrorVector.begin(), m_AngularErrorVector.end() );
324 m_MeanAngularError /= m_AngularErrorVector.size();
325 for (
unsigned int i=0; i<m_AngularErrorVector.size(); i++)
327 float temp = m_AngularErrorVector.at(i) - m_MeanAngularError;
328 m_VarAngularError += temp*temp;
330 if ( m_AngularErrorVector.at(i)>m_MaxAngularError )
331 m_MaxAngularError = m_AngularErrorVector.at(i);
332 if ( m_AngularErrorVector.at(i)<m_MinAngularError )
333 m_MinAngularError = m_AngularErrorVector.at(i);
335 if (m_AngularErrorVector.size()>1)
337 m_VarAngularError /= (m_AngularErrorVector.size()-1);
340 if (m_AngularErrorVector.size()%2 == 0)
341 m_MedianAngularError = 0.5*( m_AngularErrorVector.at( m_AngularErrorVector.size()/2 ) + m_AngularErrorVector.at( m_AngularErrorVector.size()/2+1 ) );
343 m_MedianAngularError = m_AngularErrorVector.at( (m_AngularErrorVector.size()+1)/2 ) ;
346 std::sort( m_LengthErrorVector.begin(), m_LengthErrorVector.end() );
347 m_MeanLengthError /= m_LengthErrorVector.size();
348 for (
unsigned int i=0; i<m_LengthErrorVector.size(); i++)
350 float temp = m_LengthErrorVector.at(i) - m_MeanLengthError;
351 m_VarLengthError += temp*temp;
353 if ( m_LengthErrorVector.at(i)>m_MaxLengthError )
354 m_MaxLengthError = m_LengthErrorVector.at(i);
355 if ( m_LengthErrorVector.at(i)<m_MinLengthError )
356 m_MinLengthError = m_LengthErrorVector.at(i);
358 if (m_LengthErrorVector.size()>1)
360 m_VarLengthError /= (m_LengthErrorVector.size()-1);
363 if (m_LengthErrorVector.size()%2 == 0)
364 m_MedianLengthError = 0.5*( m_LengthErrorVector.at( m_LengthErrorVector.size()/2 ) + m_LengthErrorVector.at( m_LengthErrorVector.size()/2+1 ) );
366 m_MedianLengthError = m_LengthErrorVector.at( (m_LengthErrorVector.size()+1)/2 ) ;
372 #endif // __itkEvaluateDirectionImagesFilter_cpp
itk::SmartPointer< Self > Pointer
EvaluateDirectionImagesFilter()
Superclass::OutputImageType OutputImageType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.