arwtyxouymz
(Ryutaro Matsumoto)
June 19, 2018, 11:49am
1
Hi,
I’m using ITK5 and VTK9, and I’m very confusing about itkImageToVtkImageFilter
returns.
This is my code
class Window {
public:
Window();
explicit Window(const ImageType::Pointer image);
virtual ~Window();
Window(const Window& other);
Window& operator=(const Window& other);
vtkImageData* ConvertItkToVtk();
private:
ImageType::Pointer _image;
};
vtkImageData* Window::ConvertItkToVtk()
{
constexpr unsigned int Dimension = 2;
using PixelType = unsigned char;
using ImageType = itk::Image< PixelType, Dimension >;
using ReaderType = itk::ImageFileReader< ImageType >;
using itkVtkFilterType = itk::ImageToVTKImageFilter< ImageType >;
itkVtkFilterType::Pointer filter = itkVtkFilterType::New();
filter->SetInput(this->_image);
try {
filter->Update();
} catch (itk::ExceptionObject & error) {
std::cerr << "Error: " << error << std::endl;
return nullptr;
}
filter->GetOutput()->Print(std::cout) // 1
return filter->GetOutput();
}
int main(int argc, char *argv[])
{
if (argc < 2) {
std::cerr << "Invalid Usage!" << std::endl;
std::cerr << "Usage: " << argv[0] << ", {filename}.dcm" << std::endl;
return EXIT_FAILURE;
}
Program program(argv[1]);
Window w(program.ReadImage());
w.ConvertItkToVtk()->Print(std::cout); // 2
return EXIT_SUCCESS;
}
In the place of 1
, itkImageToVtkFilter
returns vtkImageData
object correctly like this
vtkImageData (0x7f93899b68a0)
Debug: Off
Modified Time: 230
Reference Count: 1
Registered Events: (none)
Information: 0x7f93899b6a40
Data Released: False
Global Release Data: Off
UpdateTime: 231
Field Data:
Debug: Off
Modified Time: 150
.....
But in the 2
, It becomes vtkObjectBase
like this
vtkObjectBase (0x7f93899b68a0)
Reference Count: 0
Why this problem occurs?
I’m sorry I’m a beginner of itk and vtk.
please help me.
tim-evain
(Tim Evain)
June 19, 2018, 12:29pm
2
Hi,
It’s because the image is discarded because the only registered reference that linked it was the filter which created it. When the function end, the filter is discarded, thus also the image. Try returning a vtkSmartPointer< vtkImageData > rather than vtkImageData*.
HTH,
Tim
arwtyxouymz
(Ryutaro Matsumoto)
June 19, 2018, 12:38pm
3
@tim-evain
Thank you for your reply!
I tried it, but it doesn’t work…
this is my updated code
vtkImageData* Window::ConvertItkToVtk()
{
itkVtkFilterType::Pointer filter = itkVtkFilterType::New();
filter->SetInput(this->_image);
try {
filter->Update();
} catch (itk::ExceptionObject & error) {
std::cerr << "Error: " << error << std::endl;
return nullptr;
}
vtkSmartPointer<vtkImageData> image = filter->GetOutput();
return image;
}
Is it impossible to return vtkImageData
object?
tim-evain
(Tim Evain)
June 19, 2018, 12:47pm
4
It’s possible, no worries .
You haven’t changed the return type of your function, so you are not returning the smart pointer. Change for :
vtkSmartPointer<vtkImageData> Window::ConvertItkToVtk()
If it still fails, add a vtkSmartPointer<vtkImageData> member to your class, and assign the filter output to it, then return the member to keep a reference.
arwtyxouymz
(Ryutaro Matsumoto)
June 19, 2018, 12:56pm
5
@tim-evain
Awesome!!!
It work!!!
Thank you very much!
If i try to convert from vtkImageData
to itkImage
and want to return that,
do i need to use itk::SmartPointer
?
tim-evain
(Tim Evain)
June 19, 2018, 1:07pm
6
@arwtyxouymz
If you want to keep the same logic, yes.
Just keep in mind that ITK/VTK use their smartpointers and reference counts to keep a track when a object is used or become useless. That doesn’t formally prevent you from using raw pointers, but the reference tracking will be blind to them, eventually leading to issues like yours.
arwtyxouymz
(Ryutaro Matsumoto)
June 19, 2018, 2:08pm
7
@tim-evain
Thank you for your teaching!
1 Like
arwtyxouymz
(Ryutaro Matsumoto)
June 19, 2018, 4:22pm
8
@tim-evain
I’m sorry that i ask you the same type question again…
Based on your explanation, I tried to use itk::Image
as a member of class, but it cannot be displayed by QuickView
.
This is my code:
constexpr unsigned int Dimension = 2;
using PixelType = unsigned char;
using ImageType = itk::Image< PixelType, Dimension >;
class Program {
public:
Program();
explicit Program(const std::string& filename);
virtual ~Program();
Program(const Program& other);
Program& operator=(const Program& other);
void ReadImage();
itk::SmartPointer<ImageType> GetImage();
private:
const std::string _filename;
itk::SmartPointer<ImageType> _image;
};
void Program::ReadImage()
{
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(this->_filename);
this->_image = reader->GetOutput();
}
itk::SmartPointer<ImageType> Program::GetImage()
{
return this->_image;
}
int main(int argc, char *argv[])
{
if (argc < 2) {
std::cerr << "Invalid Usage!" << std::endl;
std::cerr << "Usage: " << argv[0] << ", {filename}.dcm" << std::endl;
return EXIT_FAILURE;
}
Program program(argv[1]);
program.ReadImage();
QuickView q;
q.AddImage(program.GetImage().GetPointer());
q.Visualize();
return EXIT_SUCCESS;
}
I tried
private:
ImageType::Pointer _image;
But this also doesn’t work.
I’m so sorry to ask about same question, but i wanna your help
please help me
tim-evain
(Tim Evain)
June 19, 2018, 5:02pm
9
I think it because you forgot the Update() call on the reader in your ReadImage function (before the assign to the member).
On side notes:
The smartpointers decay into raw pointers, so you can call directly “q.AddImage(program.GetImage())”
Smartpointers in ITK can also be obtained like “ImageType::Pointer” rather than “itk::SmartPointer<ImageType>”. Just mentioning since this way is used in the ITK code/examples