3

我正在使用vtkImageImport从 opencv 矩阵转换为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();
}

关于在进行这种导入时如何管理指针和内存,我有 2 个问题。

  1. 导入器是否为创建的vtkImageData创建并分配新的数据指针,以便在opencv矩阵被销毁时不影响vtk图像。
  2. 一旦导入器被销毁,返回的 vtkImageData* 是否仍然有效,或者我应该返回一个智能指针以保持引用计数 > 0?我的理由是,如果导入器在内部对 vtkImageData 使用智能指针,那么图像将在导入器被销毁时被销毁。VTK 示例始终在与随后使用数据的范围相同的范围内使用导入器。

谢谢

4

1 回答 1

4

当您要求时,进口商会复制一份。

void vtkImageImport::SetImportVoidPointer (void* ptr, int save);存储你的void*指针而不复制数据,savearg用于ImgImport的析构函数,如果save为1,你存储的指针不会被删除。

void SetImportVoidPointer (void *ptr)用 调用以前的方法save=1,因此在您的代码中,data来自 CV::Mat 将不会被破坏。注意:两者都使用相同的指针:修改你的 CV::Mat; 进口商的结果会有所不同。

void CopyImportVoidPointer (void *ptr, vtkIdType size);复制您的数据,在这种情况下,在内部,ImgImport 将复制数据,存储新指针,并在析构函数中将其删除。您可以删除您的 CV::Mat,它可能不会影响 Importer。

对于第二个问题,我不确定检索输出的内部行为,但将 vtkAlgorithm 的输出存储在 vtkSmartPointer 中允许您删除算法而不会损坏数据。

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() 只是一个例子。我尝试了一个基本示例,并且我能够使用 vtkAlgorithm 的输出,而无需将输出存储在 smartPointer 中。但是阅读Vtk 官方教程(“使用智能指针获取对象”部分),如果您不将输出存储在智能指针中,则导入器可能会在范围结束时被删除,数据也会被删除。

这就是为什么我不确定:我仍然可以使用 convertImage 方法返回的“直接”指针。您必须使用 VTK 教程中描述的智能指针。这是确保您的数据有效的最佳方式。

希望它有所帮助。

于 2013-05-29T12:43:56.487 回答