19 #include <vtkPolyLine.h>
20 #include <vtkCellArray.h>
21 #include <vtkCellData.h>
25 #include <boost/progress.hpp>
29 template<
class OutputImageType >
31 : m_UpsamplingFactor(1)
33 , m_UseImageGeometry(false)
38 template<
class OutputImageType >
43 template<
class OutputImageType >
46 itk::Point<float, 3> itkPoint;
47 itkPoint[0] = point[0];
48 itkPoint[1] = point[1];
49 itkPoint[2] = point[2];
53 template<
class OutputImageType >
56 if(&
typeid(
OutPixelType) != &
typeid(itk::RGBAPixel<unsigned char>))
64 itk::Vector<double,3> newSpacing;
66 itk::Matrix<double, 3, 3> newDirection;
67 ImageRegion<3> upsampledRegion;
68 if (m_UseImageGeometry && !m_InputImage.IsNull())
70 newSpacing = m_InputImage->GetSpacing()/m_UpsamplingFactor;
71 upsampledRegion = m_InputImage->GetLargestPossibleRegion();
72 newOrigin = m_InputImage->GetOrigin();
73 typename OutputImageType::RegionType::SizeType size = upsampledRegion.GetSize();
74 size[0] *= m_UpsamplingFactor;
75 size[1] *= m_UpsamplingFactor;
76 size[2] *= m_UpsamplingFactor;
77 upsampledRegion.SetSize(size);
78 newDirection = m_InputImage->GetDirection();
82 newSpacing = geometry->GetSpacing()/m_UpsamplingFactor;
83 newOrigin = geometry->GetOrigin();
85 newOrigin[0] += bounds.GetElement(0);
86 newOrigin[1] += bounds.GetElement(2);
87 newOrigin[2] += bounds.GetElement(4);
89 for (
int i=0; i<3; i++)
90 for (
int j=0; j<3; j++)
91 newDirection[j][i] = geometry->GetMatrixColumn(i)[j];
92 upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor);
93 upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor);
94 upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor);
96 typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize();
99 outImage->SetSpacing( newSpacing );
100 outImage->SetOrigin( newOrigin );
101 outImage->SetDirection( newDirection );
102 outImage->SetRegions( upsampledRegion );
103 outImage->Allocate();
105 int w = upsampledSize[0];
106 int h = upsampledSize[1];
107 int d = upsampledSize[2];
110 unsigned char* outImageBufferPointer = (
unsigned char*)outImage->GetBufferPointer();
111 float* buffer =
new float[w*h*d*4];
112 for (
int i=0; i<w*h*d*4; i++)
116 float minSpacing = 1;
117 if(newSpacing[0]<newSpacing[1] && newSpacing[0]<newSpacing[2])
118 minSpacing = newSpacing[0];
119 else if (newSpacing[1] < newSpacing[2])
120 minSpacing = newSpacing[1];
122 minSpacing = newSpacing[2];
124 m_FiberBundle = m_FiberBundle->GetDeepCopy();
125 m_FiberBundle->ResampleSpline(minSpacing);
127 vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
128 vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
129 vLines->InitTraversal();
131 int numFibers = m_FiberBundle->GetNumFibers();
132 boost::progress_display disp(numFibers);
133 for(
int i=0; i<numFibers; i++ )
136 vtkIdType numPoints(0);
137 vtkIdType* points(NULL);
138 vLines->GetNextCell ( numPoints, points );
141 std::list< itk::Point<float, 3> > rgbweights;
142 std::list<float> intensities;
144 for(
int j=0; j<numPoints-1; j++)
147 itk::Point<float, 3> vertex = GetItkPoint(fiberPolyData->GetPoint(points[j]));
148 itk::Point<float, 3> vertexPost = GetItkPoint(fiberPolyData->GetPoint(points[j+1]));
150 itk::Point<float, 3> dir;
151 dir[0] = fabs((vertexPost[0] - vertex[0]) * outImage->GetSpacing()[0]);
152 dir[1] = fabs((vertexPost[1] - vertex[1]) * outImage->GetSpacing()[1]);
153 dir[2] = fabs((vertexPost[2] - vertex[2]) * outImage->GetSpacing()[2]);
155 rgbweights.push_back(dir);
157 float intensity = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]);
158 intensities.push_back(intensity);
163 rgbweights.push_back(dir);
164 intensities.push_back(intensity);
169 for(
int j=0; j<numPoints; j++)
171 itk::Point<float, 3> vertex = GetItkPoint(fiberPolyData->GetPoint(points[j]));
173 itk::ContinuousIndex<float, 3> contIndex;
174 outImage->TransformPhysicalPointToIndex(vertex, index);
175 outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);
177 float frac_x = contIndex[0] - index[0];
178 float frac_y = contIndex[1] - index[1];
179 float frac_z = contIndex[2] - index[2];
203 if (px < 0 || px >= w-1)
205 if (py < 0 || py >= h-1)
207 if (pz < 0 || pz >= d-1)
210 float scale = 100 * pow((
float)m_UpsamplingFactor,3);
211 itk::Point<float, 3> rgbweight = rgbweights.front();
212 rgbweights.pop_front();
213 float intweight = intensities.front();
214 intensities.pop_front();
217 buffer[0+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[0] * scale;
218 buffer[0+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[0] * scale;
219 buffer[0+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[0] * scale;
220 buffer[0+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[0] * scale;
221 buffer[0+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[0] * scale;
222 buffer[0+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[0] * scale;
223 buffer[0+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[0] * scale;
224 buffer[0+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[0] * scale;
227 buffer[1+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[1] * scale;
228 buffer[1+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[1] * scale;
229 buffer[1+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[1] * scale;
230 buffer[1+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[1] * scale;
231 buffer[1+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[1] * scale;
232 buffer[1+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[1] * scale;
233 buffer[1+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[1] * scale;
234 buffer[1+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[1] * scale;
237 buffer[2+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[2] * scale;
238 buffer[2+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * rgbweight[2] * scale;
239 buffer[2+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * rgbweight[2] * scale;
240 buffer[2+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * rgbweight[2] * scale;
241 buffer[2+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * rgbweight[2] * scale;
242 buffer[2+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * rgbweight[2] * scale;
243 buffer[2+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * rgbweight[2] * scale;
244 buffer[2+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * rgbweight[2] * scale;
247 buffer[3+4*( px + w*(py + h*pz ))] += (1-frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale;
248 buffer[3+4*( px + w*(py+1+ h*pz ))] += (1-frac_x)*( frac_y)*(1-frac_z) * intweight * scale;
249 buffer[3+4*( px + w*(py + h*pz+h))] += (1-frac_x)*(1-frac_y)*( frac_z) * intweight * scale;
250 buffer[3+4*( px + w*(py+1+ h*pz+h))] += (1-frac_x)*( frac_y)*( frac_z) * intweight * scale;
251 buffer[3+4*( px+1 + w*(py + h*pz ))] += ( frac_x)*(1-frac_y)*(1-frac_z) * intweight * scale;
252 buffer[3+4*( px+1 + w*(py + h*pz+h))] += ( frac_x)*(1-frac_y)*( frac_z) * intweight * scale;
253 buffer[3+4*( px+1 + w*(py+1+ h*pz ))] += ( frac_x)*( frac_y)*(1-frac_z) * intweight * scale;
254 buffer[3+4*( px+1 + w*(py+1+ h*pz+h))] += ( frac_x)*( frac_y)*( frac_z) * intweight * scale;
257 float maxRgb = 0.000000001;
258 float maxInt = 0.000000001;
263 for(
int i=0; i<numPix; i++)
267 if(buffer[i] > maxRgb)
272 if(buffer[i] > maxInt)
278 for(
int i=0; i<numPix; i++)
281 outImageBufferPointer[i] = (
unsigned char) (255.0 * buffer[i] / maxRgb);
283 outImageBufferPointer[i] = (
unsigned char) (255.0 * buffer[i] / maxInt);
virtual ~TractsToRgbaImageFilter()
itk::SmartPointer< Self > Pointer
OutputImageType::PixelType OutPixelType
BoundingBoxType::BoundsArrayType BoundsArrayType
itk::Point< float, 3 > GetItkPoint(double point[3])
TractsToRgbaImageFilter()