18 #ifndef __itkMeshFromContinuousSphericalFunctionImageFilter_hxx 19 #define __itkMeshFromContinuousSphericalFunctionImageFilter_hxx 24 #include "itkImageRegionIterator.h" 25 #include "itkImageRegionIteratorWithIndex.h" 26 #include "vtkColorTransferFunction.h" 28 #include <vtkFloatArray.h> 29 #include <itkProgressReporter.h> 37 template<
class TInputImage,
class TOutputMesh>
42 m_TessellationOrder = 3;
43 m_BasicShape = SphereTessellatorType::ICOSAHEDRON;
44 m_SphereTessellator = SphereTessellatorType::New();
50 template<
class TInputImage,
class TOutputMesh>
55 Superclass::PrintSelf(os, indent);
56 os << indent <<
"m_BasicShape: " << m_BasicShape << std::endl;
57 os << indent <<
"m_TessellationOrder: " << m_TessellationOrder << std::endl;
58 os << indent <<
"m_Stretch: " << m_Stretch << std::endl;
62 template <
class TInputImage,
class TOutputMesh>
63 typename LightObject::Pointer
67 typename LightObject::Pointer loPtr = Superclass::InternalClone();
72 itkExceptionMacro(<<
"downcast to type " << this->GetNameOfClass()<<
" failed.");
75 rval->m_SphereTessellator = m_SphereTessellator;
76 rval->m_BasicShape = m_BasicShape;
77 rval->m_TessellationOrder = m_TessellationOrder;
79 rval->m_Stretch = m_Stretch;
81 rval->m_BasisMatrix = m_BasisMatrix;
86 template <
class TInputImage,
class TOutputMesh>
94 this->VerifyInputParameters();
96 this->m_SphereTessellator->SetBasicShape(this->m_BasicShape);
97 this->m_SphereTessellator->SetOrder(this->m_TessellationOrder);
98 this->m_SphereTessellator->TessellateSphere();
103 this->ComputeBasisMatrix();
105 if (this->GetDebug())
107 utlGlobalException(this->m_BasisMatrix->Columns()<=0,
"no m_BasisMatrix after run ComputeBasisMatrix()");
111 template <
class TInputImage,
class TOutputMesh>
117 ProgressReporter progress(
this, threadId, regionForThread.GetNumberOfPixels());
122 inputPixel.SetSize(inputPtr->GetNumberOfComponentsPerPixel());
125 unsigned int numberOfBasis = this->m_BasisMatrix->Columns();
132 ImageRegionConstIteratorWithIndex<InputImageType> inputIt(inputPtr, regionForThread);
136 unsigned int numberOfPoints = 0;
137 unsigned int numberOfCells = 0;
138 vnl_matrix<unsigned long> cellMatrix;
140 unsigned long offset = 0;
142 numberOfPoints = this->m_SphereTessellator->GetNumberOfVertices();
143 numberOfCells = this->m_SphereTessellator->GetNumberOfFaces();
144 cellMatrix = this->m_SphereTessellator->GetCellsMatrix();
152 vtkSmartPointer<OutputMeshPointsType> outputMeshPoints = vtkSmartPointer<OutputMeshPointsType>::New();
153 vtkSmartPointer<OutputMeshCellArrayType> outputMeshCellArray = vtkSmartPointer<OutputMeshCellArrayType>::New();
154 vtkSmartPointer<OutputMeshRGBType> outputMeshRGB = vtkSmartPointer<OutputMeshRGBType>::New();
155 outputMeshRGB->SetNumberOfComponents(4);
156 outputMeshRGB->SetName(
"RGBA_scalars");
158 double outputMeshPoint[3];
159 unsigned int numberOfCellPoints = 3;
161 vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction =
162 vtkSmartPointer<vtkColorTransferFunction>::New();
165 colorTransferFunction->SetColorSpaceToHSV();
166 colorTransferFunction->AddRGBPoint(0.0, 0, 0, 1);
167 colorTransferFunction->AddRGBPoint(0.5, 0, 1, 0);
168 colorTransferFunction->AddRGBPoint(1.0, 1, 0, 0);
172 unsigned char RGB[4];
180 if ( this->m_ColorScheme == Superclass::MAGNITUDE )
183 while( !inputIt.IsAtEnd() )
185 inputIndex = inputIt.GetIndex();
186 if (!this->IsPixelIndexVisible(inputIndex))
192 inputPixel = inputIt.Get();
194 for (
unsigned int k=0;k<numberOfBasis;k++)
195 x(k) = inputPixel[k];
197 if (x.GetRootMeanSquares() == 0)
209 if (this->m_Normalization==Superclass::UNIT_INTEGRAL)
211 x = this->NormalizeUnitIntegral(x);
214 sf = (*this->m_BasisMatrix) * x;
220 double maxVal = sf.MaxValue();
221 double minVal = sf.MinValue();
233 if (sfMax-sfMin<1e-2*std::fabs(sfMin))
236 if (sfMax==sfMin || sfMax<0)
242 while( !inputIt.IsAtEnd() )
244 inputIndex = inputIt.GetIndex();
245 if (!this->IsPixelIndexVisible(inputIndex))
248 progress.CompletedPixel();
252 inputPtr->TransformIndexToPhysicalPoint(inputIndex, inputPhysicalPoint);
253 inputPixel = inputIt.Get();
255 for (
unsigned int k=0;k<numberOfBasis;k++)
256 x(k) = inputPixel[k];
258 if (x.GetRootMeanSquares() == 0)
261 progress.CompletedPixel();
265 if (this->GetDebug())
267 std::cout <<
"index = " << inputIndex << std::endl << std::flush;
271 if (this->m_Normalization==Superclass::UNIT_INTEGRAL)
273 x = this->NormalizeUnitIntegral(x);
276 sf = (*this->m_BasisMatrix) * x;
277 if (this->GetDebug())
282 for (
unsigned int k=0;k<numberOfPoints;k++)
284 if ( this->m_ColorScheme == Superclass::MAGNITUDE )
286 colorTransferFunction->GetColor((sf(k)-sfMin)/(sfMax-sfMin), rgb);
287 for (
unsigned int d=0;d<3;d++)
290 outputMeshPoint[d] = sf(k) * (*this->m_Orientations)(k,d) + inputPhysicalPoint[d];
292 outputMeshPoint[d] = this->m_Scale * (*this->m_Orientations)(k,d) + inputPhysicalPoint[d];
293 RGB[d] =
static_cast<VTK_TYPE_NAME_UNSIGNED_CHAR
>(rgb[d]*255.0);
296 else if ( this->m_ColorScheme == Superclass::DIRECTION )
298 for (
unsigned int d=0;d<3;d++)
301 outputMeshPoint[d] = sf(k) * (*this->m_Orientations)(k,d) + inputPhysicalPoint[d];
303 outputMeshPoint[d] = this->m_Scale * (*this->m_Orientations)(k,d) + inputPhysicalPoint[d];
304 RGB[d] =
static_cast<VTK_TYPE_NAME_UNSIGNED_CHAR
>(std::fabs( (*this->m_Orientations)(k,d))*255.0);
310 for (
unsigned int d=0;d<3;d++)
312 if (RGB[d] > max_val)
314 if (RGB[d] < min_val)
319 for (
unsigned int d=0;d<3;d++)
321 RGB[d] =
static_cast<VTK_TYPE_NAME_UNSIGNED_CHAR
>( (RGB[d] - min_val)/(max_val - min_val) * 255.0 );
332 outputMeshPoints->InsertNextPoint( outputMeshPoint );
333 outputMeshRGB->InsertNextTupleValue(RGB);
336 for (vtkIdType c=0;c<numberOfCells;c++)
338 outputMeshCellArray->InsertNextCell(numberOfCellPoints);
340 for( vtkIdType p = 0; p < numberOfCellPoints; p++ )
342 outputMeshCellArray->InsertCellPoint( offset + cellMatrix(c,p) );
346 offset += numberOfPoints;
349 progress.CompletedPixel();
354 this->m_Mesh->SetPoints( outputMeshPoints );
355 this->m_Mesh->SetPolys( outputMeshCellArray );
356 this->m_Mesh->GetPointData()->SetScalars( outputMeshRGB );
362 template<
class TInputImage,
class TOutputMesh>
367 if (this->m_RemoveNegativeValues)
369 for (
unsigned int k=0; k<sf.Size(); k++ )
376 if (std::fabs(this->m_Pow-1.0)>1e-8)
378 for (
int k = 0; k < sf.Size(); k += 1 )
379 sf(k) = std::pow(sf(k), this->m_Pow);
383 if ( this->m_Normalization == Superclass::UNIT_MAX )
385 sf = sf/( sf.MaxValue() + vnl_math::eps );
389 if ( this->m_Normalization==Superclass::MIN_MAX && sf.MaxValue()-sf.MinValue()>1e-8)
391 sf = (sf - sf.MinValue())/( sf.MaxValue() - sf.MinValue() + vnl_math::eps );
Superclass::MatrixType MatrixType
helper functions specifically used in dmritool
InputImageType::IndexType InputImageIndexType
void BeforeThreadedGenerateData() ITK_OVERRIDE
void PrintUtlMatrix(const NDArray< T, 2 > &mat, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout)
void PrintSelf(std::ostream &os, Indent indent) const ITK_OVERRIDE
SmartPointer< Self > Pointer
InputImageType::ConstPointer InputImageConstPointer
const T & max(const T &a, const T &b)
Return the maximum between a and b.
void ThreadedGenerateData(const typename TInputImage::RegionType ®ionForThread, ThreadIdType threadId) ITK_OVERRIDE
#define utlGlobalException(cond, expout)
MeshFromContinuousSphericalFunctionImageFilter()
InputImageType::PointType InputImagePointType
void VnlMatrixToUtlMatrix(const vnl_matrix< T > &mat, utl::NDArray< T, 2 > &matUtl)
#define utlPrintVar(cond,...)
LightObject::Pointer InternalClone() const ITK_OVERRIDE
Compute mesh from general spherical function.
Compute mesh from continuous spherical function linearly represented by a set of bases.
InputImageType::PixelType InputImagePixelType
#define utlShowPosition(cond)
void PrintUtlVector(const NDArray< T, 1 > &vec, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout, bool showStats=true)
void ScaleSamples(VectorType &b) const
Superclass::VectorType VectorType