20 #include <vtkImageData.h> 40 std::vector<PropertyPtr> retval;
41 retval.push_back(this->getInterpolationStepsOption(root));
45 DoublePropertyPtr PNNReconstructionMethodService::getInterpolationStepsOption(QDomElement root)
49 "Interpolation steps in voxels", 3,
DoubleRange(1, 10, 1), 0, root);
55 double* t = tt.begin();
59 (*p)[0] = t[0] * x + t[1] * y + t[2] * z + t[3];
60 (*p)[1] = t[4] * x + t[5] * y + t[6] * z + t[7];
61 (*p)[2] = t[8] * x + t[9] * y + t[10] * z + t[11];
69 std::vector<TimedPosition> frameInfo = input->getFrames();
70 if (frameInfo.empty())
72 if (input->getDimensions()[2]==0)
77 Eigen::Array3i inputDims = input->getDimensions();
79 Eigen::Array3i targetDims(target->GetDimensions());
80 Vector3D targetSpacing(target->GetSpacing());
86 int* outputDims = tempOutput->GetDimensions();
89 if (inputDims[2] != static_cast<int> (frameInfo.size()))
93 Vector3D inputSpacing(input->getSpacing());
94 Vector3D outputSpacing(tempOutput->GetSpacing());
97 unsigned char *outputPointer =
static_cast<unsigned char*
> (tempOutput->GetScalarPointer());
98 unsigned char* maskPointer =
static_cast<unsigned char*
> (input->getMask()->GetScalarPointer());
101 for (
int record = 0; record < inputDims[2]; record++)
103 unsigned char *inputPointer = input->getFrame(record);
104 boost::array<double, 16> recordTransform = frameInfo[record].mPos.flatten();
106 for (
int beam = 0; beam < inputDims[0]; beam++)
108 for (
int sample = 0; sample < inputDims[1]; sample++)
110 if (!validPixel(beam, sample, inputDims, maskPointer))
112 Vector3D inputPoint(beam * inputSpacing[0], sample * inputSpacing[1], 0.0);
115 int outputVoxelX =
static_cast<int> ((outputPoint[0] / outputSpacing[0]) + 0.5);
116 int outputVoxelY =
static_cast<int> ((outputPoint[1] / outputSpacing[1]) + 0.5);
117 int outputVoxelZ =
static_cast<int> ((outputPoint[2] / outputSpacing[2]) + 0.5);
119 if (validVoxel(outputVoxelX, outputVoxelY, outputVoxelZ, outputDims))
121 int outputIndex = outputVoxelX + outputVoxelY * outputDims[0] + outputVoxelZ * outputDims[0]
123 int inputIndex = beam + sample * inputDims[0];
126 outputPointer[outputIndex] = std::max<unsigned char>(inputPointer[inputIndex], outputPointer[outputIndex]);
128 outputPointer[outputIndex] = std::max<unsigned char>(inputPointer[inputIndex], 1);
136 this->interpolate(tempOutputData, outputData, settings);
146 inline int getIndex_z_last(
int x,
int y,
int z,
const Eigen::Array3i& dim)
148 return x + y*dim[0] + z*dim[0]*dim[1];
152 inline int getIndex_x_last(
int y,
int z,
int x,
const Eigen::Array3i& dim)
154 return x + y*dim[0] + z*dim[0]*dim[1];
158 inline int getIndex_y_last(
int z,
int x,
int y,
const Eigen::Array3i& dim)
160 return x + y*dim[0] + z*dim[0]*dim[1];
169 template <
class FUNCTION>
170 void maskAlongDim(
int a_dim,
int b_dim,
int c_dim,
const Eigen::Array3i& dim,
unsigned char *inputPtr,
unsigned char *maskPtr, FUNCTION getIndex)
172 for (
int a = 0; a < a_dim; a++)
174 for (
int b = 0; b < b_dim; b++)
178 for (
int c = 0; c < c_dim; c++)
180 int index = getIndex(a, b, c, dim);
181 if (inputPtr[index]>0)
187 for (
int c = c_dim-1; c >=0; c--)
189 int index = getIndex(a, b, c, dim);
190 if (inputPtr[index]>0)
196 for (
int c = start; c <= stop; c++)
198 int index = getIndex(a, b, c, dim);
216 Eigen::Array3i dim(inputData->GetDimensions());
217 Vector3D spacing(inputData->GetSpacing());
219 unsigned char *inputPtr =
static_cast<unsigned char*
> (inputData->GetScalarPointer());
220 unsigned char *maskPtr =
static_cast<unsigned char*
> (mask->GetScalarPointer());
223 maskAlongDim(dim[0], dim[1], dim[2], dim, inputPtr, maskPtr, &getIndex_z_last);
224 maskAlongDim(dim[1], dim[2], dim[0], dim, inputPtr, maskPtr, &getIndex_x_last);
225 maskAlongDim(dim[2], dim[0], dim[1], dim, inputPtr, maskPtr, &getIndex_y_last);
233 DoublePropertyPtr interpolationStepsOption = this->getInterpolationStepsOption(settings);
234 int interpolationSteps =
static_cast<int> (interpolationStepsOption->getValue());
240 Eigen::Array3i outputDims(output->GetDimensions());
242 Eigen::Array3i inputDims(input->GetDimensions());
244 unsigned char *inputPointer =
static_cast<unsigned char*
> (input->GetScalarPointer());
245 unsigned char *outputPointer =
static_cast<unsigned char*
> (output->GetScalarPointer());
246 unsigned char *maskPointer =
static_cast<unsigned char*
> (mask->GetScalarPointer());
248 if ((outputDims[0] != inputDims[0]) || (outputDims[1] != inputDims[1]) || (outputDims[2] != inputDims[2]))
253 int total = outputDims[0] * outputDims[1] * outputDims[2];
257 for (
int x = 0; x < outputDims[0]; x++)
259 for (
int y = 0; y < outputDims[1]; y++)
261 for (
int z = 0; z < outputDims[2]; z++)
263 int outputIndex = x + y * outputDims[0] + z * outputDims[0] * outputDims[1];
266 if (maskPointer[outputIndex]==0)
271 else if (inputPointer[outputIndex]>0)
273 outputPointer[outputIndex] = inputPointer[outputIndex];
279 this->fillHole(inputPointer, outputPointer, x, y, z, outputDims, interpolationSteps);
285 int valid = 100*double(ignored)/double(total);
286 int outside = 100*double(removed)/double(total);
287 int holes = 100*double(total-ignored-removed)/double(total);
289 QString(
"PNN: Size: %1Mb, Valid voxels: %2\%, Outside mask: %3\% Filled holes [steps=%4, %5s]: %6\%")
290 .arg(total/1024/1024)
293 .arg(interpolationSteps)
302 void PNNReconstructionMethodService::fillHole(
unsigned char *inputPointer,
unsigned char *outputPointer,
int x,
int y,
int z,
const Eigen::Array3i& dim,
int interpolationSteps)
304 int outputIndex = x + y * dim[0] + z * dim[0] * dim[1];
305 bool interpolated =
false;
313 for (
int i = -localArea; i < localArea + 1; i++)
315 for (
int j = -localArea; j < localArea + 1; j++)
317 for (
int k = -localArea; k < localArea + 1; k++)
319 int localIndex = outputIndex + i + j*dim[0] + k*dim[0]*dim[1];
321 if (validVoxel(x + i, y + j, z + k, dim.data()) && inputPointer[localIndex] > 0.1)
323 tempVal += inputPointer[localIndex];
339 outputPointer[outputIndex] =
static_cast<int> ((tempVal / count) + 0.5);
340 outputPointer[outputIndex] = std::max<unsigned char>(1, outputPointer[outputIndex]);
346 }
while (localArea <= interpolationSteps && !interpolated);
QString qstring_cast(const T &val)
Utility class for describing a bounded numeric range.
boost::shared_ptr< class Image > ImagePtr
virtual QString getName() const
virtual bool reconstruct(ProcessedUSInputDataPtr input, vtkImageDataPtr outputData, QDomElement settings)
void reportWarning(QString msg)
Settings * settings()
Shortcut for accessing the settings instance.
vtkImageDataPtr generateVtkImageData(Eigen::Array3i dim, Vector3D spacing, const unsigned char initValue, int components)
PNNReconstructionMethodService(ctkPluginContext *context)
virtual std::vector< PropertyPtr > getSettings(QDomElement root)
QString getElapsedSecondsAsString() const
virtual ~PNNReconstructionMethodService()
boost::shared_ptr< class DoubleProperty > DoublePropertyPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
void setDeepModified(vtkImageDataPtr image)
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
boost::shared_ptr< class ProcessedUSInputData > ProcessedUSInputDataPtr
void optimizedCoordTransform(Vector3D *p, boost::array< double, 16 > tt)
void reportDebug(QString msg)
Namespace for all CustusX production code.