15 #include "PlusConfigure.h" 16 #include "igsioCommon.h" 20 #include "vtkXMLDataElement.h" 23 #include "vtkImageData.h" 24 #include "vtkInformation.h" 25 #include "vtkInformationVector.h" 26 #include "vtkObjectFactory.h" 27 #include "vtkStreamingDemandDrivenPipeline.h" 79 int* inputImageExtent,
double radiusStartMm,
double radiusStopMm,
double thetaStartDeg,
double thetaStopDeg,
80 int* outputImageExtent,
double* outputImageSpacing,
double* transducerCenterPixel,
double intensityScaling )
85 bool modifiedScanConversionParams =
false;
86 for (
int i = 0;
i < 6;
i++ )
90 modifiedScanConversionParams =
true;
94 modifiedScanConversionParams =
true;
97 for (
int i = 0;
i < 3;
i++ )
101 modifiedScanConversionParams =
true;
112 modifiedScanConversionParams =
true;
115 if ( !modifiedScanConversionParams )
123 for (
int i = 0;
i < 6;
i++ )
128 for (
int i = 0;
i < 3;
i++ )
144 int numberOfSamples = inputImageExtent[1] - inputImageExtent[0] + 1;
145 int numberOfLines = inputImageExtent[3] - inputImageExtent[2] + 1;
146 double radiusDeltaMm = ( radiusStopMm - radiusStartMm ) / numberOfSamples;
147 double thetaStartRad = vtkMath::RadiansFromDegrees( thetaStartDeg );
148 double thetaDeltaRad = 0;
149 if ( numberOfLines > 1 )
151 thetaDeltaRad = vtkMath::RadiansFromDegrees( ( thetaStopDeg - thetaStartDeg ) / ( numberOfLines - 1 ) );
153 int outputImageSizePixelsX = outputImageExtent[1] - outputImageExtent[0] + 1;
154 int outputImageSizePixelsY = outputImageExtent[3] - outputImageExtent[2] + 1;
157 double dx = outputImageSpacing[0];
158 double dz = outputImageSpacing[1];
162 for (
int i = 0;
i < outputImageSizePixelsY;
i++ )
167 for (
int j = 0; j < outputImageSizePixelsX; j++ )
170 double radius = sqrt( z2 +
x *
x );
171 double theta = atan2 (
x, z );
172 double samp = ( radius - radiusStartMm ) / radiusDeltaMm;
173 double line = ( theta - thetaStartRad ) / thetaDeltaRad;
174 int index_samp = floor( samp );
175 int index_line = floor(
line );
177 if ( ( index_samp >= 0 ) && ( index_samp + 1 < numberOfSamples ) &&
178 ( index_line >= 0 ) && ( index_line + 1 < numberOfLines ) )
182 double samp_val = samp - index_samp;
183 double line_val =
line - index_line;
209 vtkInformation* outInfo = outputVector->GetInformationObject( 0 );
210 vtkInformation* inInfo = inputVector[0]->GetInformationObject( 0 );
212 outInfo->Set( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->
OutputImageExtent, 6 );
215 double spacing[3] = {1.0, 1.0, 1.0};
216 outInfo->Set( vtkDataObject::SPACING(), spacing, 3 );
217 double origin[3] = {0, 0, 0};
218 outInfo->Set( vtkDataObject::ORIGIN(), origin, 3 );
220 int inExtent[6] = {0};
221 inInfo->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inExtent );
235 vtkInformation* inInfo = inputVector[0]->GetInformationObject( 0 );
236 int extent[6] = {0, -1, 0, -1, 0, -1};
237 inInfo->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent );
238 inInfo->Set( vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), extent, 6 );
249 Superclass::AllocateOutputData( output, outInfo, uExtent );
253 unsigned char* outPtrZ = static_cast<unsigned char*>( output->GetScalarPointerForExtent( uExtent ) );
256 vtkIdType outIncX, outIncY, outIncZ;
257 output->GetIncrements( outIncX, outIncY, outIncZ );
258 int typeSize = output->GetScalarSize();
264 int rowLength = ( uExtent[1] - uExtent[0] + 1 ) * output->GetNumberOfScalarComponents();
265 rowLength *= typeSize;
266 int maxY = uExtent[3] - uExtent[2];
267 int maxZ = uExtent[5] - uExtent[4];
270 for (
int idxZ = 0; idxZ <= maxZ; idxZ++ )
272 unsigned char* outPtrY = outPtrZ;
273 for (
int idxY = 0; idxY <= maxY; idxY++ )
275 memset( outPtrY, 0, rowLength );
287 vtkImageData* inData, T* inPtr,
288 vtkImageData* outData, T* outPtr,
289 int interpolationTableExt[6],
int id )
291 T* envelope_data = inPtr;
292 int numberOfSamples = inData->GetExtent()[1] - inData->GetExtent()[0] + 1;
296 std::vector<vtkPlusUsScanConvertCurvilinear::InterpolatedPoint>::const_iterator firstPoint =
self->GetInterpolatedPointArray().begin() + interpolationTableExt[0];
297 std::vector<vtkPlusUsScanConvertCurvilinear::InterpolatedPoint>::const_iterator afterLastPoint =
self->GetInterpolatedPointArray().begin() + interpolationTableExt[1] + 1;
298 for ( std::vector<vtkPlusUsScanConvertCurvilinear::InterpolatedPoint>::const_iterator it = firstPoint; it != afterLastPoint; ++it )
300 T* env_pointer = ( T* ) & ( envelope_data[it->inputPixelIndex] );
301 image[it->outputPixelIndex] =
302 it->weightCoefficients[0] * env_pointer[0]
303 + it->weightCoefficients[1] * env_pointer[1]
304 + it->weightCoefficients[2] * env_pointer[numberOfSamples]
305 + it->weightCoefficients[3] * env_pointer[numberOfSamples + 1]
312 vtkInformation* vtkNotUsed( request ),
313 vtkInformationVector** vtkNotUsed( inputVector ),
314 vtkInformationVector* vtkNotUsed( outputVector ),
315 vtkImageData** *inData,
316 vtkImageData** outData,
317 int outExt[6],
int id )
320 void* inPtr = inData[0][0]->GetScalarPointer();
321 void* outPtr = outData[0]->GetScalarPointer();
324 if ( inData[0][0]->GetScalarType() != outData[0]->GetScalarType() )
326 vtkErrorMacro(
"Execute: input ScalarType, " 327 << inData[0][0]->GetScalarType()
328 <<
", must match out ScalarType " 329 << outData[0]->GetScalarType() );
333 switch ( inData[0][0]->GetScalarType() )
337 static_cast<VTK_TT*>( inPtr ), outData[0],
338 static_cast<VTK_TT*>( outPtr ),
341 vtkErrorMacro( <<
"Execute: Unknown ScalarType" );
352 os << indent <<
"RadiusStartMm: " << this->
RadiusStartMm <<
"\n";
353 os << indent <<
"RadiusStopMm: " << this->
RadiusStopMm <<
"\n";
354 os << indent <<
"ThetaStartDeg: " << this->
ThetaStartDeg <<
"\n";
355 os << indent <<
"ThetaStopDeg: " << this->
ThetaStopDeg <<
"\n";
390 int range = max - min + 1;
391 int valuesPerThread = static_cast<int>( ceil( range / static_cast<double>( total ) ) );
392 int maxThreadIdUsed = static_cast<int>( ceil( range / static_cast<double>( valuesPerThread ) ) ) - 1;
393 if ( num < maxThreadIdUsed )
395 splitExt[0] = splitExt[0] + num * valuesPerThread;
396 splitExt[1] = splitExt[0] + valuesPerThread - 1;
398 if ( num == maxThreadIdUsed )
400 splitExt[0] = splitExt[0] + num * valuesPerThread;
403 vtkDebugMacro(
" Split Piece: ( " << splitExt[0] <<
", " << splitExt[1] <<
", " 404 << splitExt[2] <<
", " << splitExt[3] <<
", " 405 << splitExt[4] <<
", " << splitExt[5] <<
")" );
407 return maxThreadIdUsed + 1;
413 LOG_TRACE(
"vtkPlusUsScanConvertCurvilinear::ReadConfiguration" );
419 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double,
RadiusStartMm, scanConversionElement );
420 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double,
RadiusStopMm, scanConversionElement );
430 double outputImageStartDepthMm = 0;
431 if ( scanConversionElement->GetScalarAttribute(
"OutputImageStartDepthMm", outputImageStartDepthMm ) )
435 LOG_WARNING(
"Transducer center position in the image is specified by the TransducerCenterPixel attribute, therefore the OutputImageStartDepthMm will be ignored. Please remove the OutputImageStartDepthMm attribute from the configuration." );
442 LOG_WARNING(
"OutputImageStartDepthMm is deprecated. Use the following equivalent attribute instead: TransducerCenterPixel=\"" 447 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double,
ThetaStartDeg, scanConversionElement );
448 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double,
ThetaStopDeg, scanConversionElement );
456 LOG_TRACE(
"vtkPlusUsScanConvertCurvilinear::WriteConfiguration" );
462 scanConversionElement->SetDoubleAttribute(
"RadiusStartMm", this->
RadiusStartMm );
463 scanConversionElement->SetDoubleAttribute(
"RadiusStopMm", this->
RadiusStopMm );
465 scanConversionElement->SetDoubleAttribute(
"ThetaStartDeg", this->
ThetaStartDeg );
466 scanConversionElement->SetDoubleAttribute(
"ThetaStopDeg", this->
ThetaStopDeg );
479 double thetaDeltaDeg = 0;
480 if ( numberOfLines > 1 )
484 double thetaRad = vtkMath::RadiansFromDegrees( this->
ThetaStartDeg + scanLineIndex * thetaDeltaDeg );
488 scanlineStartPoint_OutputImage[2] = 0;
489 scanlineStartPoint_OutputImage[3] = 1;
493 scanlineEndPoint_OutputImage[2] = 0;
494 scanlineEndPoint_OutputImage[3] = 1;
503 if ( scanLineLengthPixels < 1 )
505 LOG_ERROR(
"Cannot determine DistanceBetweenScanlineSamplePointsMm because scanLineLengthPixels=" << scanLineLengthPixels <<
" is invalid" );
508 double distanceBetweenScanlineSamplePointsMm = ( this->
RadiusStopMm - this->
RadiusStartMm ) /
double( scanLineLengthPixels );
509 return distanceBetweenScanlineSamplePointsMm;
515 return vtkImageAlgorithm::GetOutput();
double InterpRadiusStartMm
double TransducerCenterPixel[2]
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *scanConversionElement)
double weightCoefficients[4]
virtual void ThreadedRequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector, vtkImageData ***inData, vtkImageData **outData, int outExt[6], int id)
int InterpInputImageExtent[6]
double InterpOutputImageSpacing[3]
bool TransducerCenterPixelSpecified
void ComputeInterpolatedPointArray(int *inputImageExtent, double radiusStartMm, double radiusStopMm, double thetaStartDeg, double thetaStopDeg, int *outputImageExtent, double *outputImageSpacing, double *transducerCenterPixel, double intensityScaling)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual vtkImageData * GetOutput()
virtual void AllocateOutputData(vtkImageData *output, vtkInformation *outInfo, int *uExtent)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *scanConversionElement)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *scanConversionElement)
void vtkPlusUsScanConvertExecute(vtkPlusUsScanConvertCurvilinear *self, vtkImageData *inData, T *inPtr, vtkImageData *outData, T *outPtr, int interpolationTableExt[6], int id)
double OutputImageSpacing[3]
std::vector< InterpolatedPoint > InterpolatedPointArray
PlusStatus GetScanLineEndPoints(int scanLineIndex, double scanlineStartPoint_OutputImage[4], double scanlineEndPoint_OutputImage[4])
double OutputImageStartDepthMm
virtual double GetDistanceBetweenScanlineSamplePointsMm()
double InterpThetaStopDeg
virtual int SplitExtent(int splitExt[6], int startExt[6], int num, int total)
virtual ~vtkPlusUsScanConvertCurvilinear()
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
This class performs scan conversion from scan lines for curvilinear probes.
vtkStandardNewMacro(vtkPlusUsScanConvertCurvilinear)
virtual int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *)
virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *)
int InterpOutputImageExtent[6]
double InterpIntensityScaling
double InterpTransducerCenterPixel[2]
double OutputIntensityScaling
double InterpThetaStartDeg
double InterpRadiusStopMm
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *scanConversionElement)
vtkPlusUsScanConvertCurvilinear()