[vtkusers] Threading issue when extracting surfaces from a labeled ImageData
Sébastien Valette
sebastien.valette at creatis.insa-lyon.fr
Wed Mar 30 11:59:20 EDT 2011
Hi,
I'm trying to extract the surfaces from labeled volume data. The source
code is pasted at the end of this message. The code works when the
number of threads is set to 1 (uncomment the only commented line) but
when using multithreading, the output is randomly corrupted (but parts
of the surfaces are still correct).
My workflow is as follows :
ImageData->vtkThreshold->vtkDataSetSurfaceFilter->vtkPolyDataWriter.
Does anyone knows where the problem could come from? Or is there any
better workflow for this? I'm using vtk 5.4.2 on linux (Ubuntu 10.10).
Thanks,
Sebastien
#include <sstream>
#include <vtkImageData.h>
#include <vtkMetaImageReader.h>
#include <vtkIdList.h>
#include <vtkThreshold.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPolyDataWriter.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkMultiThreader.h>
class MyThreaderHelperClass
{
public:
vtkImageData *Image;
vtkIdList *Labels;
};
VTK_THREAD_RETURN_TYPE ThreadedSurfaceExtraction (void *arg)
{
vtkMultiThreader::ThreadInfo *Info =
(vtkMultiThreader::ThreadInfo*) arg;
MyThreaderHelperClass *Helper = (MyThreaderHelperClass *)
Info->UserData;
int MyId = Info->ThreadID;
int NumberOfThreads=Info->NumberOfThreads;
vtkImageData *Image=vtkImageData::New();
Image->ShallowCopy(Helper->Image);
vtkIdList *Labels=Helper->Labels;
vtkThreshold *Threshold=vtkThreshold::New();
Threshold->SetInput(Image);
vtkDataSetSurfaceFilter *Geometry=vtkDataSetSurfaceFilter::New();
vtkPolyDataWriter *Writer=vtkPolyDataWriter::New();
for (int i=MyId;i<Labels->GetNumberOfIds();i+=NumberOfThreads)
{
double Level=Labels->GetId(i);
Threshold->ThresholdBetween(Level-0.5,Level+0.5);
Geometry->SetInput((vtkDataObject *)Threshold->GetOutput());
Geometry->Update();
std::stringstream Name;
Name<<Level<<".vtk";
Writer->SetFileName(Name.str().c_str());
Geometry->GetOutput()->GetCellData()->Initialize();
Geometry->GetOutput()->GetPointData()->Initialize();
Writer->SetInput(Geometry->GetOutput());
Writer->Write();
}
Threshold->Delete();
Geometry->Delete();
Writer->Delete();
return (VTK_THREAD_RETURN_VALUE);
}
int main( int argc, char *argv[] )
{
if (argc<2)
{
cout<<"Usage : VolumeAnalysis file.mhd"<<endl;
exit(1);
}
// Load Volume
cout <<"load : "<<argv[1]<<endl;
vtkMetaImageReader *Reader=vtkMetaImageReader::New();
Reader->SetFileName(argv[1]);
Reader->Update();
vtkImageData *Image=Reader->GetOutput();
vtkIdList *Labels=vtkIdList::New();
int Dimensions[3];
Image->GetDimensions(Dimensions);
std::cout<<"Image dimensions : "<<Dimensions[0]<<"
"<<Dimensions[1]<<" "<<Dimensions[2]<<endl;
//collect labels
for (int z=0;z<Dimensions[2];z++)
{
for (int y=0;y<Dimensions[1];y++)
{
for (int x=0;x<Dimensions[0];x++)
{
int Label=Image->GetScalarComponentAsFloat (x,y,z,0);
if (Labels->IsId(Label)==-1)
Labels->InsertNextId(Label);
}
}
}
cout<<"Found "<<Labels->GetNumberOfIds()<<" labels"<<endl;
MyThreaderHelperClass Helper;
Helper.Image=Image;
Helper.Labels=Labels;
vtkMultiThreader *Threader=vtkMultiThreader::New();
// Threader->SetNumberOfThreads(1);
Threader->SetSingleMethod (ThreadedSurfaceExtraction, (void *)
&Helper);
Threader->SingleMethodExecute ();
return (0);
}
More information about the vtkusers
mailing list