[vtkusers] trigger the execution of a vtkThreadedImageAlgorithm derived filter by calling Update()
Gomez, Alberto
alberto.gomez at kcl.ac.uk
Wed Dec 16 06:34:25 EST 2015
Hi all,
I am trying to write a multithreaded filter (vtkMeanSSD), derived from
vtkThreadedImageAlgorithm, which will calculate the mean value of the
difference between the intensities of two images (mean SSD).
What I want to achieve is that when I call Update() on my filter, the
calculations occur and then I can retrieve the value by calling another
method GetValue(). This is the snippet from my main file:
vtkSmartPointer<vtkMeanSSD> myfilter = vtkSmartPointer<vtkMeanSSD>::New();
myfilter->SetInput1Data(im1);
myfilter->SetInput2Data(im2);
myfilter->Update();
double val = myfilter->GetValue(); // value is 0, which is the default
by construction
The problem I have is that when I call myfilter->Update() the filter is
not executed. For some reason, it does execute if I plug it to a writer,
for example
vtkSmartPointer<vtkMeanSSD> myfilter = vtkSmartPointer<vtkMeanSSD>::New();
myfilter->SetInput1Data(im1);
myfilter->SetInput2Data(im2);
vtkSmartPointer<vtkNIFTIImageWriter> writer
=vtkSmartPointer<vtkNIFTIImageWriter>::New();
writer->SetFileName("image_SSD.nii");
writer->SetInputConnection(myfilter->GetOutputPort());
writer->Write(); // This triggers the execution
double val = myfilter->GetValue(); // good value
Any advice how I can trigger the ThreadedRequestData method by calling
update? Is there any other better way to achieve the functionality I want?
Thanks for your help. The full filter code is below.
Alberto
======================================= vtkMeanSSD.h
=======================================
// .NAME vtkMeanSSD - Simple SSD image-image filter.
// .SECTION Description
// This calculates the mean sum of squared differences
// 1/N*sum (a -b)^2
#ifndef vtkMeanSSD_h
#define vtkMeanSSD_h
#include "vtkImagingGeneralModule.h" // For export macro
#include "vtkThreadedImageAlgorithm.h"
class VTKIMAGINGGENERAL_EXPORT vtkMeanSSD : public vtkThreadedImageAlgorithm
{
public:
static vtkMeanSSD *New();
vtkTypeMacro(vtkMeanSSD,vtkThreadedImageAlgorithm);
// Description:
// Set the two inputs to this filter
virtual void SetInput1Data(vtkDataObject *in) {
this->SetInputData(0,in); }
virtual void SetInput2Data(vtkDataObject *in) {
this->SetInputData(1,in); }
// Description:
// Get the metric value from the images. This is
// computed when Update() is called.
double GetValue() {return this->m_value;}
protected:
vtkMeanSSD();
~vtkMeanSSD() {}
virtual void ThreadedRequestData(vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector,
vtkImageData ***inData,
vtkImageData **outData,
int extent[6], int threadId);
double m_value;
private:
vtkMeanSSD(const vtkMeanSSD&); // Not implemented.
void operator=(const vtkMeanSSD&); // Not implemented.
};
#endif
// VTK-HeaderTest-Exclude: vtkMeanSSD.h
======================================= vtkMeanSSD.cxx
=======================================
#include "vtkMeanSSD.h"
#include "vtkImageData.h"
#include "vtkImageProgressIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkStandardNewMacro(vtkMeanSSD);
//----------------------------------------------------------------------------
vtkMeanSSD::vtkMeanSSD()
{
this->SetNumberOfInputPorts(2);
this->m_value = 0;
}
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
// Handles the two input operations
template <class T>
void vtkMeanSSDExecute(vtkMeanSSD *self,
vtkImageData *in1Data,
vtkImageData *in2Data,
double *value,
int outExt[6], int id, T *)
{
vtkImageIterator<T> inIt1(in1Data, outExt);
vtkImageIterator<T> inIt2(in2Data, outExt);
// find the region to loop over
int N = in1Data->GetNumberOfPoints();
float val = 0;
// sum (a -b)*(a-b)
/// Calculate the average of each image
while (!inIt1.IsAtEnd())
{
T* inSI1 = inIt1.BeginSpan();
T* inSI2 = inIt2.BeginSpan();
T* inSI1End = inIt1.EndSpan();
while (inSI1 != inSI1End){
T v1 = static_cast<float>(*inSI1);
T v2 = static_cast<float>(*inSI2);
val += (v1-v2)*(v1-v2);
++inSI1;
++inSI2;
}
inIt1.NextSpan();
inIt2.NextSpan();
}
val/=N;
*value = val;
}
//----------------------------------------------------------------------------
// This method is passed a input and output regions, and executes the filter
// algorithm to fill the output from the inputs.
// It just executes a switch statement to call the correct function for
// the regions data types.
void vtkMeanSSD::ThreadedRequestData(
vtkInformation * vtkNotUsed( request ),
vtkInformationVector ** vtkNotUsed( inputVector ),
vtkInformationVector * vtkNotUsed( outputVector ),
vtkImageData ***inData,
vtkImageData **outData,
int outExt[6], int id)
{
// this filter expects that input is the same type as output.
if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
{
vtkErrorMacro(<< "Execute: input1 ScalarType, "
<< inData[0][0]->GetScalarType()
<< ", must match output ScalarType "
<< outData[0]->GetScalarType());
return;
}
if (inData[1][0]->GetScalarType() != outData[0]->GetScalarType())
{
vtkErrorMacro(<< "Execute: input2 ScalarType, "
<< inData[1][0]->GetScalarType()
<< ", must match output ScalarType "
<< outData[0]->GetScalarType());
return;
}
// this filter expects that inputs that have the same number of
components
if (inData[0][0]->GetNumberOfScalarComponents() !=
inData[1][0]->GetNumberOfScalarComponents())
{
vtkErrorMacro(<< "Execute: input1 NumberOfScalarComponents, "
<< inData[0][0]->GetNumberOfScalarComponents()
<< ", must match out input2 NumberOfScalarComponents "
<< inData[1][0]->GetNumberOfScalarComponents());
return;
}
switch (inData[0][0]->GetScalarType())
{
double d;
vtkTemplateMacro(
vtkMeanSSDExecute(this, inData[0][0],
inData[1][0], &this->m_value, outExt, id,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
--
Dr Alberto Gomez
Research Associate
Department of Biomedical Engineering
King's College London
020 7188 7188 ext 50871
4th North Wing
St Thomas' Hospital
SE1 7EH London, UK
More information about the vtkusers
mailing list