7 #include "PlusConfigure.h" 11 #include "vtkImageData.h" 12 #include "vtkInformation.h" 13 #include "vtkInformationVector.h" 14 #include "vtkObjectFactory.h" 15 #include "vtkStreamingDemandDrivenPipeline.h" 40 vtkInformationVector** inputVector,
41 vtkInformationVector* outputVector)
44 vtkInformation* outInfo = outputVector->GetInformationObject(0);
45 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
48 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inExt);
52 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), outExt);
57 case US_IMG_BRIGHTNESS:
62 case US_IMG_RF_I_LINE_Q_LINE:
67 int numberOfBmodeRows = (inExt[3] - inExt[2] + 1) / 2;
68 outExt[2] = inExt[2] / 2;
69 outExt[3] = outExt[2] + numberOfBmodeRows - 1;
80 case US_IMG_RF_IQ_LINE:
85 int numberOfBmodeColumns = (inExt[1] - inExt[0] + 1) / 2;
86 outExt[0] = inExt[0] / 2;
87 outExt[1] = outExt[0] + numberOfBmodeColumns - 1;
91 vtkErrorMacro(
"Unknown RF image type: " << this->
ImageType);
96 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), outExt, 6);
99 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR, -1);
106 vtkInformation* vtkNotUsed(request),
107 vtkInformationVector** inputVector,
108 vtkInformationVector* vtkNotUsed(outputVector),
109 vtkImageData*** inData,
110 vtkImageData** outData,
111 int outExt[6],
int id)
113 if (outData[0]->GetScalarType() != VTK_UNSIGNED_CHAR)
115 vtkErrorMacro(
"Expecting VTK_UNSIGNED_CHAR output pixel type");
120 if (inData[0][0]->GetNumberOfScalarComponents() != 1)
122 vtkErrorMacro(
"Expecting 1 components not " << inData[0][0]->GetNumberOfScalarComponents());
125 if (this->
ImageType != US_IMG_BRIGHTNESS && inData[0][0]->GetScalarType() != VTK_SHORT && inData[0][0]->GetScalarType() != VTK_INT)
127 vtkErrorMacro(
"Expecting VTK_SHORT or VTK_INT as input pixel type, or US_IMG_BRIGHTNESS as image type");
131 int inExt[6] = {outExt[0], outExt[1], outExt[2], outExt[3], outExt[4], outExt[5]};
135 case US_IMG_BRIGHTNESS:
139 case US_IMG_RF_I_LINE_Q_LINE:
144 int numberOfBmodeRows = outExt[3] - outExt[2] + 1;
145 int numberOfRfRows = numberOfBmodeRows * 2;
146 inExt[2] = outExt[2] * 2;
147 inExt[3] = inExt[2] + numberOfRfRows - 1;
158 case US_IMG_RF_IQ_LINE:
163 int numberOfBmodeColumns = outExt[1] - outExt[0] + 1;
164 int numberOfRfColumns = numberOfBmodeColumns * 2;
165 inExt[0] = outExt[0] * 2;
166 inExt[1] = inExt[0] + numberOfRfColumns - 1;
170 vtkErrorMacro(
"Unknown RF image type: " << this->
ImageType);
173 if (inData[0][0]->GetScalarType() == VTK_SHORT)
175 ThreadedLineByLineHilbertTransform<short>(inExt, outExt, inData, outData,
id);
177 else if (inData[0][0]->GetScalarType() == VTK_INT)
179 ThreadedLineByLineHilbertTransform<int>(inExt, outExt, inData, outData,
id);
181 else if (inData[0][0]->GetScalarType() == VTK_UNSIGNED_CHAR)
183 ThreadedLineByLineHilbertTransform<unsigned char>(inExt, outExt, inData, outData,
id);
187 vtkErrorMacro(
"Internal error: unexpected branching");
191 template<
typename ScalarType>
194 vtkIdType inInc0 = 0;
195 vtkIdType inInc1 = 0;
196 vtkIdType inInc2 = 0;
197 inData[0][0]->GetContinuousIncrements(inExt, inInc0, inInc1, inInc2);
198 ScalarType* inPtr = static_cast<ScalarType*>(inData[0][0]->GetScalarPointerForExtent(inExt));
200 vtkIdType outInc0 = 0;
201 vtkIdType outInc1 = 0;
202 vtkIdType outInc2 = 0;
203 outData[0]->GetContinuousIncrements(outExt, outInc0, outInc1, outInc2);
204 unsigned char* outPtr = static_cast<unsigned char*>(outData[0]->GetScalarPointerForExtent(outExt));
206 unsigned long target = static_cast<unsigned long>((outExt[5] - outExt[4] + 1) * (outExt[3] - outExt[2] + 1) / 50.0);
210 int numberOfRfSamplesInScanline = inExt[1] - inExt[0] + 1;
211 int numberOfBmodeSamplesInScanline = outExt[1] - outExt[0] + 1;
213 bool imageTypeValid =
true;
214 unsigned long count = 0;
216 if (this->
ImageType == US_IMG_BRIGHTNESS)
219 unsigned char* inPtrByte = static_cast<unsigned char*>(inData[0][0]->GetScalarPointerForExtent(inExt));
220 for (
int idx2 = outExt[4]; idx2 <= outExt[5]; ++idx2)
222 for (
int idx1 = outExt[2]; !this->AbortExecute && idx1 <= outExt[3]; ++idx1)
227 if (!(
count % target))
229 this->UpdateProgress(
count / (50.0 * target));
233 memcpy(outPtr, inPtrByte, numberOfRfSamplesInScanline + inInc1);
234 inPtrByte += numberOfRfSamplesInScanline + inInc1;
235 outPtr += numberOfRfSamplesInScanline + outInc1;
243 ScalarType* hilbertTransformBuffer =
new ScalarType[numberOfRfSamplesInScanline + 1];
244 for (
int idx2 = outExt[4]; idx2 <= outExt[5]; ++idx2)
246 for (
int idx1 = outExt[2]; !this->AbortExecute && idx1 <= outExt[3]; ++idx1)
251 if (!(
count % target))
253 this->UpdateProgress(
count / (50.0 * target));
260 case US_IMG_RF_I_LINE_Q_LINE:
264 ScalarType* originalSignal = inPtr;
265 inPtr += numberOfRfSamplesInScanline + inInc1;
266 ScalarType* phaseShiftedSignal = inPtr;
267 inPtr += numberOfRfSamplesInScanline + inInc1;
269 outPtr += numberOfBmodeSamplesInScanline + outInc1;
278 inPtr += numberOfRfSamplesInScanline + inInc1;
279 outPtr += numberOfBmodeSamplesInScanline + outInc1;
282 case US_IMG_RF_IQ_LINE:
286 inPtr += numberOfRfSamplesInScanline + inInc1;
287 outPtr += numberOfBmodeSamplesInScanline + outInc1;
291 imageTypeValid =
false;
299 LOG_ERROR(
"Unsupported image type for brightness conversion: "<< igsioCommon::GetStringFromUsImageType(this->
ImageType));
302 delete[] hilbertTransformBuffer;
303 hilbertTransformBuffer = NULL;
308 this->Superclass::PrintSelf(os, indent);
314 LOG_TRACE(
"vtkPlusRfToBrightnessConvert::ReadConfiguration");
315 XML_VERIFY_ELEMENT(rfToBrightnessElement,
"RfToBrightnessConversion");
317 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double,
BrightnessScale, rfToBrightnessElement);
324 LOG_TRACE(
"vtkPlusRfToBrightnessConvert::WriteConfiguration");
326 XML_VERIFY_ELEMENT(rfToBrightnessElement,
"RfToBrightnessConversion");
329 rfToBrightnessElement->SetDoubleAttribute(
"BrightnessScale", this->
BrightnessScale);
350 bool debugOutput =
false;
353 std::cout <<
"hc = [ ";
370 template<
typename ScalarType>
377 LOG_ERROR(
"Insufficient data for performing Hilbert transform");
382 for (
int l = 1; l <= npt - this->NumberOfHilbertFilterCoeffs + 1; l++)
389 hilbertTransformOutput[l] = yt;
395 hilbertTransformOutput[
i] = 0.5 * (hilbertTransformOutput[
i] + hilbertTransformOutput[
i + 1]);
397 for (
int i = npt - this->NumberOfHilbertFilterCoeffs;
i >= 1;
i--)
399 hilbertTransformOutput[
i + this->NumberOfHilbertFilterCoeffs / 2] = hilbertTransformOutput[
i];
403 for (
int i = 1;
i <= this->NumberOfHilbertFilterCoeffs / 2;
i++)
405 hilbertTransformOutput[
i] = 0.0;
406 hilbertTransformOutput[npt + 1 -
i] = 0.0;
412 template<
typename ScalarType>
421 double xt = inputSignal[
i];
422 double xht = inputSignalHilbertTransformed[
i];
423 double brightnessValue = sqrt(sqrt(sqrt(xt * xt + xht * xht))) * this->
BrightnessScale;
426 ampl[
i] = brightnessValue;
443 template<
typename ScalarType>
448 int numberOfIqPairs = floor(
double(npt) / 2);
449 for (
int i = 0;
i < numberOfIqPairs;
i++)
451 double xt = inputSignal[inputIndex++];
452 double xht = inputSignal[inputIndex++];
453 double outputValue = sqrt(sqrt(sqrt(xt * xt + xht * xht))) * this->
BrightnessScale;
456 ampl[outputIndex++] = outputValue;
This class converts ultrasound RF data to brightness values.
void ThreadedRequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector, vtkImageData ***inData, vtkImageData **outData, int outExt[6], int id)
virtual void ComputeHilbertTransformCoeffs()
void ThreadedLineByLineHilbertTransform(int inExt[6], int outExt[6], vtkImageData ***inData, vtkImageData **outData, int threadId)
~vtkPlusRfToBrightnessConvert()
void ComputeAmplitudeILineQLine(unsigned char *ampl, ScalarType *inputSignal, ScalarType *inputSignalHilbertTransformed, int npt)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *rfToBrightnessElement)
vtkStandardNewMacro(vtkPlusRfToBrightnessConvert)
void ComputeAmplitudeIqLine(unsigned char *ampl, ScalarType *inputSignal, const int npt)
virtual int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *outputVector)
std::vector< double > HilbertTransformCoeffs
int NumberOfHilbertFilterCoeffs
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *rfToBrightnessElement)
Phidget_ChannelClass uint32_t * count
PlusStatus ComputeHilbertTransform(ScalarType *hilbertTransformOutput, ScalarType *input, int npt)
const double MAX_BRIGHTNESS_VALUE
vtkPlusRfToBrightnessConvert()
const double MIN_BRIGHTNESS_VALUE
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE