4 #include <vtkPolyData.h> 5 #include <vtkSmartPointer.h> 6 #include <vtkImageData.h> 8 #include <vtkCellArray.h> 9 #include "vtkCardinalSpline.h" 11 #include <boost/math/special_functions/round.hpp> 33 mRoutePositions.clear();
34 int N = route->GetNumberOfPoints();
35 for(vtkIdType i = 0; i < N; i++)
39 Eigen::Vector3d position;
40 position(0) = p[0]; position(1) = p[1]; position(2) = p[2];
41 mRoutePositions.push_back(position);
48 mInputImage = inputImage->getBaseVtkImageData();
49 mVtkScalarType = mInputImage->GetScalarType();
50 mMinVoxelValue = inputImage->getMin();
55 mThicknessUp = thicknessUp;
56 mThicknessDown = thicknessDown;
62 newImage->DeepCopy(mInputImage);
64 switch (mVtkScalarType)
67 newImage->AllocateScalars(VTK_CHAR, 1);
68 this->insertValuesAtInitialization(static_cast<char*> (newImage->GetScalarPointer()), newImage);
70 case VTK_UNSIGNED_CHAR:
71 newImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
72 this->insertValuesAtInitialization(static_cast<unsigned char*> (newImage->GetScalarPointer()), newImage);
75 newImage->AllocateScalars(VTK_SIGNED_CHAR, 1);
76 this->insertValuesAtInitialization(static_cast<signed char*> (newImage->GetScalarPointer()), newImage);
78 case VTK_UNSIGNED_SHORT:
79 newImage->AllocateScalars(VTK_UNSIGNED_SHORT, 1);
80 this->insertValuesAtInitialization(static_cast<unsigned short*> (newImage->GetScalarPointer()), newImage);
83 newImage->AllocateScalars(VTK_SHORT, 1);
84 this->insertValuesAtInitialization(static_cast<short*> (newImage->GetScalarPointer()), newImage);
86 case VTK_UNSIGNED_INT:
87 newImage->AllocateScalars(VTK_UNSIGNED_INT, 1);
88 this->insertValuesAtInitialization(static_cast<unsigned int*> (newImage->GetScalarPointer()), newImage);
91 newImage->AllocateScalars(VTK_INT, 1);
92 this->insertValuesAtInitialization(static_cast<int*> (newImage->GetScalarPointer()), newImage);
95 reportError(QString(
"Unknown VTK ScalarType: %1").arg(mVtkScalarType));
107 int* dim = accusurfImage->GetDimensions();
108 double* spacing = accusurfImage->GetSpacing();
109 std::vector<int> yIndexes (dim[2],0);
111 for (
int i = 0; i<mRoutePositions.size(); i++)
116 if (z >= 0 && z < dim[2] && y >= 0 && y < dim[1])
120 for (
int i = 1; i<dim[2]; i++)
122 if (yIndexes[i] == 0)
123 yIndexes[i] = yIndexes[i-1];
125 for (
int i = dim[2]-2; i>=0; i--)
127 if (yIndexes[i] == 0)
128 yIndexes[i] = yIndexes[i+1];
132 switch (mVtkScalarType)
135 this->insertValuesFromOriginalImage<char>(accusurfImage, dim, yIndexes);
137 case VTK_UNSIGNED_CHAR:
138 this->insertValuesFromOriginalImage<unsigned char>(accusurfImage, dim, yIndexes);
140 case VTK_SIGNED_CHAR:
141 this->insertValuesFromOriginalImage<signed char>(accusurfImage, dim, yIndexes);
143 case VTK_UNSIGNED_SHORT:
144 insertValuesFromOriginalImage<unsigned short>(accusurfImage, dim, yIndexes);
147 this->insertValuesFromOriginalImage<short>(accusurfImage, dim, yIndexes);
149 case VTK_UNSIGNED_INT:
150 this->insertValuesFromOriginalImage<unsigned int>(accusurfImage, dim, yIndexes);
153 this->insertValuesFromOriginalImage<int>(accusurfImage, dim, yIndexes);
156 reportError(QString(
"Unknown VTK ScalarType: %1").arg(mVtkScalarType));
160 int yMin = *std::min_element(yIndexes.begin(), yIndexes.end());
161 int yMax = *std::max_element(yIndexes.begin(), yIndexes.end());
162 accusurfImage = crop(accusurfImage, yMin, yMax);
164 return accusurfImage;
167 void Accusurf::smoothPositions()
169 int numberOfInputPoints = mRoutePositions.size();
170 int controlPointFactor = 10;
171 int numberOfControlPoints = numberOfInputPoints / controlPointFactor;
177 if (numberOfControlPoints >= 2)
180 for(
int j=0; j<numberOfControlPoints; j++)
182 int indexP = (j*numberOfInputPoints)/numberOfControlPoints;
183 splineX->AddPoint(indexP,mRoutePositions[indexP](0));
184 splineY->AddPoint(indexP,mRoutePositions[indexP](1));
185 splineZ->AddPoint(indexP,mRoutePositions[indexP](2));
188 splineX->AddPoint(numberOfInputPoints-1,mRoutePositions[numberOfInputPoints-1](0));
189 splineY->AddPoint(numberOfInputPoints-1,mRoutePositions[numberOfInputPoints-1](1));
190 splineZ->AddPoint(numberOfInputPoints-1,mRoutePositions[numberOfInputPoints-1](2));
193 std::vector< Eigen::Vector3d > smoothingResult;
194 for(
int j=0; j<numberOfInputPoints; j++)
196 double splineParameter = j;
197 Eigen::Vector3d tempPoint;
198 tempPoint(0) = splineX->Evaluate(splineParameter);
199 tempPoint(1) = splineY->Evaluate(splineParameter);
200 tempPoint(2) = splineZ->Evaluate(splineParameter);
201 smoothingResult.push_back(tempPoint);
203 mRoutePositions.clear();
204 mRoutePositions = smoothingResult;
210 int* dim = image->GetDimensions();
211 IntBoundingBox3D cropbox(0, dim[0], std::max(0, ymin-mThicknessUp-2) , std::min(dim[1]-1, ymax+mThicknessDown+2) , 0, dim[2]);
216 template <
class TYPE>
217 void Accusurf::insertValuesAtInitialization(TYPE* dataPtr,
vtkImageDataPtr image)
219 int* dim = image->GetDimensions();
220 int numVoxels = dim[0]*dim[1]*dim[2];
221 for (
int i = 0; i < numVoxels; ++i)
223 dataPtr[i] = mMinVoxelValue;
227 template <
class TYPE>
228 void Accusurf::insertValuesFromOriginalImage(
vtkImageDataPtr image,
int* dim, std::vector<int> yIndexes)
230 for (
int z = 0; z<dim[2]; z++)
232 for (
int x = 0; x<dim[0]; x++)
234 int ymin = std::max(yIndexes[z]-mThicknessUp,0);
235 int ymax = std::min(yIndexes[z]+mThicknessDown,dim[1]-1);
236 for (
int y = ymin; y<=ymax; y++)
239 TYPE* dataPtrInputImage =
static_cast<TYPE*
> (mInputImage->GetScalarPointer(x,y,z));
240 TYPE* dataPtrAccusurfImage =
static_cast<TYPE*
> (image->GetScalarPointer(x,y,z));
241 dataPtrAccusurfImage[0] = dataPtrInputImage[0];
void reportError(QString msg)
vtkImageDataPtr cropImage(vtkImageDataPtr input, IntBoundingBox3D cropbox)
boost::shared_ptr< class Image > ImagePtr
void setInputImage(ImagePtr inputImage)
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
void setRoutePositions(vtkPolyDataPtr route)
Representation of an integer bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
void setThickness(int thicknessUp, int thicknessDown)
void setDeepModified(vtkImageDataPtr image)
Vector3D round(const Vector3D &a)
vtkImageDataPtr createAccusurfImage()
Namespace for all CustusX production code.