I am performing some annotation functions which which modifies the ITK image -> ImageToVTKImageFilter -> vtkImageViewer2.
However, this is quite slow for large images because I need to call ImageToVTKImageFilter.Update() whenever then user mouse drags.
I was looking at the SetRequestedRegion() to see if I can just update the region that was drawn, however ImageToVTKImageFilter does not have SetRequestedRegion.
Is there any way I can update only the drawn region to speed things up?
You might only need to call Modified() on the resulting VTK image.
If that does not solve your problem, you could try using vtkImageImport directly: SetImportVoidPointer to ITK image’s GetBufferPointer(), and call Modified() on the resulting VTK image when needed.
but I guess is not ok, obviously because the code is not correct. How can I migrate SimpleITK image data to vtkImageData.
Sorry for this (maybe) easy question, for me is not
pImageImport->SetImportVoidPointer(&img); this needs to be replaced by pImageImport->SetImportVoidPointer(img.GetBufferAsVoidPointer()); or something similar. Then you need a series of pImageImport->SetSpacing(...); calls for spacing, size/extent, origin. Finally pImageImport->Update();. Why are you trying to mix in DICOM reader?
Kindly thank you Dzenan ! I have just a little until I solve my task
I have just one more question: how to convert from sitk::Image::GetSize into vtkImageImport::SetDataExtent, because there is no SetSize inside of vtkImageImport.
Here is the code source:
sitk::ImportImageFilter importer;
....
importer.SetBufferAsUInt8(in);
.....
sitk::Image img = importer.Execute();
sitk::ConnectedThresholdImageFilter segmentationFilter;
segmentationFilter.SetLower(20.0);
segmentationFilter.SetUpper(1000);
segmentationFilter.SetReplaceValue(255);
img = segmentationFilter.Execute(img);
....
pImageImport->SetImportVoidPointer((void*)img.GetBufferAsUInt8());
std::vector<double> spacing = img.GetSpacing();
std::vector<double> origin = img.GetOrigin();
std::vector<unsigned int> size = img.GetSize();
pImageImport->SetDataSpacing(spacing[0], spacing[1], spacing[2]);
pImageImport->SetDataOrigin(origin[0], origin[1], origin[2]);
pImageImport->SetDataExtent(); // <-- this is the question, what should I put here ? because pImageImport doesn't have SetDataSize(), just SetDataExtent()
pImageImport->Update();
Here is the documentation for vtkImageImport::SetDataExtent:
Get/Set the extent of the data buffer. The dimensions of your data
must be equal to (extent[1]-extent[0]+1) * (extent[3]-extent[2]+1) *
(extent[5]-DataExtent[4]+1). For example, for a 2D image use
Computing the extent should be something like this:
auto index=img->GetLargestPossibleRegion().GetIndex(); // this might be different in SimpleITK
for (unsigned d=0; d<Dimension; d++)
{
extent[d]=index[d];
extent[d+1]=index[d]+size[d]-1;
}
Is there any similar way to find this index with SimpleITK only ? I have struggled days to insert SimpleITK in my project, I don’t want the same experience with ITK
Moreover, my image object with what I have worked is sitk::Image.
I am about to finish my task. But I guess I didn’t done something right:
sitk::Image img = importer.Execute();
spacing = img.GetSpacing();
origin = img.GetOrigin();
size = img.GetSize();
pImageImport->SetDataSpacing(spacing[0], spacing[1], spacing[2]);
pImageImport->SetDataOrigin(origin[0], origin[1], origin[2]);
int extent[6];
int index[3];
index[0] = 0; index[1] = 0; index[2] = 0;
for (unsigned int d = 0; d < img.GetDimension(); ++d)
{
extent[d] = index[d];
extent[d + 1] = index[d] + size[d] - 1;
}
pImageImport->SetDataExtent(extent);
pImageImport->SetImportVoidPointer((void*)img.GetBufferAsUInt8());
pImageImport->Update(); <-- Warning: In D:\VTK\VTK-8.2.0\IO\Image\vtkImageImport.cxx, line 507
vtkImageImport (000001AA5E16E6D0):
There is a distinction between the whole extent and the buffered
extent of an imported image. Use SetWholeExtent to set the extent
of the entire image. Use SetDataExtent to set the extent of the
portion of the image that is in the buffer set with
SetImportVoidPointer. Both should be called even if the extents are
the same.
@dzenanz It looks like you had a bug in the indexing of extent in your proposed code. Should have been something like this:
for (unsigned d=0; d<Dimension; d++)
{
extent[2*d]=0;
extent[2*d+1]=size[d]-1;
}
I also removed the always 0 index;
@flaviu2 Thank you for sharing the solution. I didn’t see the problem with the above code before you posted your solution. I like the way you directly set the extents: