Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vtk memory management when importing data

Tags:

vtk

I am using vtkImageImport to convert from an opencv matrix to vtkImageData.

vtkImageData* convertImage(const cv::Mat& image)
{
  int width = image.cols;
  int height = image.rows;
  vtkSmartPointer<vtkImageImport> importer = vtkSmartPointer<vtkImageImport>::New();
  importer->SetDataScalarTypeToUnsignedChar();
  importer->SetImportVoidPointer(image.data);
  importer->SetWholeExtent(0,width-1,0, height-1, 0, 0);
  importer->SetDataExtentToWholeExtent();
  importer->Update();
  return importer->GetOutput();
}

I have 2 questions on how pointers and memory are managed when doing this kind of import.

  1. Does the importer create and allocate a new data pointer for the vtkImageData created, so that the vtk image is not affected when the opencv matrix is destroyed.
  2. Will the returned vtkImageData* still be valid once the importer is destroyed, or should I return a smart pointer to keep the reference counting > 0? My reasoning is that if the importer uses smart pointers for the vtkImageData internally, then the image will be destroyed as the importer is destroyed. VTK examples always use the importer in the same scope as where the data is then used.

Thank you

like image 871
stropitek Avatar asked Mar 12 '26 07:03

stropitek


1 Answers

The importer does a copy when you ask to do it.

void vtkImageImport::SetImportVoidPointer (void* ptr, int save); stores your void* pointer without copying the data, save arg is used in the destructor of ImgImport, if save is 1, your stored pointer will not be deleted.

void SetImportVoidPointer (void *ptr) calls previous methods with save=1, so in your code, data from CV::Mat, will not be destroyed. Be careful : both use the same pointer : Modify your CV::Mat; and the result from importer will be different.

void CopyImportVoidPointer (void *ptr, vtkIdType size); make a copy of your data, in this case, internally, ImgImport will copy the data, store the new pointer, and delete it in the destructor. You can delete your CV::Mat, it may not affect the Importer.

For the second question, i'm not sure of the internally behavior for retrieve the output but storing the output from a vtkAlgorithm in a vtkSmartPointer allows you to delete the algorithm without corrupt the data.

vtkSmartPointer<vtkImageData> convertImage(const cv::Mat& image)
{
  int width = image.cols;
  int height = image.rows;
  vtkSmartPointer<vtkImageImport> importer = vtkSmartPointer<vtkImageImport>::New();
  importer->SetDataScalarTypeToUnsignedChar();
  importer->SetImportVoidPointer(image.data);
  importer->SetWholeExtent(0,width-1,0, height-1, 0, 0);
  importer->SetDataExtentToWholeExtent();
  importer->Update();

  vtkSmartPointer<vtkImageData> outp = importer->GetOutput();
  importer->Delete (); // this line cause the destruction of the output, unless it's stored in a smartPointer.

  return outp;
}

Importer->Delete() is just for example. I tried with a basic exemple, and I as able to use the output from a vtkAlgorithm, without storing the output in a smartPointer. But reading the Vtk official tutorials (section "Getting an Object with a Smart Pointer"), if you don't store the output in a smartpointer, the importer may be deleted at the end of the scope, the data too.

That's why i'm not sure : I can still use the "direct" pointer returned by the convertImage methods. You must use the smartpointers as describes in the VTK tutos. It's the best way to be sure your data is valid .

Hope it help.

like image 66
Marcassin Avatar answered Mar 16 '26 06:03

Marcassin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!