繁体   English   中英

指针作为ITK / C ++中的函数参数-无法使其正常工作

[英]Pointer as function argument in ITK/C++ - can't get it working

我是ITK和C ++的新手,目前正在为图像配准算法设置测试程序。 在我的消息中,我将详细说明我在使用ITK术语时正在做的事情。 但是,我希望任何有经验的C ++程序员都应该能够在不理解ITK细节的情况下告诉我代码有什么问题,因为我认为我在引用/解引用中所做的只是错误。 此处要跟踪的内容(下面将详细说明)是MetaDataContainer类型的变量,在所有函数中均称为metaData。 如果有任何ITK方面的细节使您感到困惑,请询问更多详细信息,但是我不想让此原始消息太长。 无论如何,这里是这样:

我将不得不在程序执行过程中多次读写dicom图像,因此,我决定不为它们编写单独的函数,而不必每次都执行读/写过程的所有步骤。 由于我必须使用读取过程中的一些数据,例如输出中的MetaDataDictionaryArray,因此readDicom函数(以及另一个函数preregistrationOperations)返回一个元组:

typedef std::tuple< ImageType::Pointer, MetaDataContainer, FileNamesContainer > ImageMetaOutputTuple;

要注意的另一个重要的typedef是MetaDataContainer,它本身是指向DictionaryRawPointer-vector的指针。 从ItkImageSeriesReader.h:

typedef MetaDataDictionary                  DictionaryType;
typedef MetaDataDictionary *                DictionaryRawPointer;
typedef std::vector< DictionaryRawPointer > DictionaryArrayType;
typedef const DictionaryArrayType *         DictionaryArrayRawPointer;

在我自己的头文件feir.h中:

typedef itk::ImageSeriesWriter< ImageType, Image2DType >::DictionaryArrayRawPointer  MetaDataContainer;

其他类型与Dicom处理的ITK示例相同。 我的程序的大致布局如下所示。

但是,该程序在writeDicom函数中崩溃,并显示错误“…向量下标超出范围”。 我将错误的范围缩小到与MetaDataDictionaryArray有关。 首次在reaDicom中读取dicoms时,其大小为64(序列中的文件数),但是当将其返回到preRegistrationOperations时,其大小突然为0,然后通过此零大小的容器崩溃的writeDicom。

编辑:崩溃本身发生在seriesWriter->Update()

我试图通过改用MetaDataContainer-pointers来解决此问题,但问题仍然存在。 我可能还会补充说,我对C ++也很陌生(更多是物理学家,而不是程序员)。 有人可以帮我吗? 从readDicom的元组中返回MetaDataContainer,将其解压缩到preRegistrationOperations中,然后将其传递给writeDicom应该足够简单,但是无论如何尝试,我都无法使其正常工作。

最好的问候,Mikael

ImageMetaOutputTuple preRegistrationOperations( std::string inputDir,  std::string outputDir, std::string seriesNumber, bool preparationsDone = false, bool verbose = true )
{ 
   // No output verbose if operations have already been done
   if (preparationsDone) verbose = false;

   // Read input-Dicoms
   ImageType::Pointer image;
   MetaDataContainer metaData;
   FileNamesContainer outputFilenames; 
   ImageMetaOutputTuple returnTuple = readDicom( inputDir, outputDir, seriesNumber, verbose );
   std::tie (image, metaData, outputFilenames) = returnTuple;    

   // Pass image and directory and filename information to writeDicom and write into outputDir
   if (!preparationsDone) {                
          try {
                 int resultCode = writeDicom( image, outputDir, outputFilenames, metaData );
          }
          catch (itk::ExceptionObject &ex) {
                 std::cout << "Exception caught in writeDICOM:" << std::endl;
                 std::cout << ex << std::endl;            
          }      
   }      
   return returnTuple;
}

--

int writeDicom ( ImageType::Pointer image, std::string inputDir, FileNamesContainer filenames, MetaDataContainer metaData )
{ 
            …
            seriesWriter->SetMetaDataDictionaryArray( metaData );  
            try {       
                 seriesWriter->Update();        
                 return 0;
               }
            catch {
                   ...
                  }
   …
}

--

ImageMetaOutputTuple readDicom ( std::string inputDir, std::string outputDir = "", std::string seriesNumber = "", bool verbose = true)
{      
   …
   image = reader->GetOutput();
   files = nameGenerator->GetOutputFileNames();
   MetaDataContainer metaData = reader->GetMetaDataDictionaryArray();
          …
ImageMetaOutputTuple returnTuple (image, metaData, files);
return returnTuple;
}

--

int main( int argc, char* argv[] )
{
   …
   ImageType::Pointer moving; 
   ImageType::Pointer target;
   std::tie(moving, std::ignore, std::ignore) = preRegistrationOperations( inputDir, movingDir, movingSeriesNumber, preparationsDone, verbose );       
   std::tie(target, std::ignore, std::ignore) = preRegistrationOperations( inputDir, targetDir, targetSeriesNumber, preparationsDone, verbose );       
   …
}

可能是GetMetaDataDictionaryArray仅返回系列阅读器成员的原始指针,但是当您从readDicom退出时,阅读器将超出范围。 我希望您在这种情况下遇到段错误,但这可能是研究的方向。 除了返回元组,您还可以在函数中添加4个额外的参数来存储结果(以便于调试)。

触摸字典总是很讨厌,这是一个示例http://www.itk.org/Wiki/ITK/Examples/DICOM/ResampleDICOM (但在这里他们逐片阅读字典)。 您确定需要更新吗? dicom编写器会自动更新某些字段(例如,方向),无论如何您都不能强制执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM