在ITK管道中使用c++函数

use C++ functions in ITK pipeline

本文关键字:c++ 函数 ITK 管道      更新时间:2023-10-16

我需要帮助解决一个基本的(我想)c++问题。我想使用c++函数来简化ITK管道,但我不知道如何传递参数并获得输出。我已经在ITK示例中看到了如何从main()调用一个函数来创建图像

(如在本例中:http://www.itk.org/Wiki/ITK/Examples/ImageProcessing/LabelGeometryImageFilter)

我想做的是这样的(伪代码):

int main ()
{
Image = reader -> GetOutput();
function1 (input, ouput) // where input is Image 
function2 (input, ouput) // where input now is the output of function1
and so on
}
void function1
{
}
void function2
{
}

欢呼艾琳娜

我的印象是,您是从一个带有ITK管道的长"only-main"函数来的,现在您想通过将其拆分为一些函数来使代码更具可读性,并且您对c++不是很有信心。如果不是那样的话,我的回答可能会重复你已经知道的东西。

首先,ITK有这个很好的管道结构,因此您可以准备一个连接一个接一个过滤器的管道,然后在最后一个过滤器上调用update,并获得整个管道来处理图像。如果将输入更改为第一个过滤器,并再次调用最后一个过滤器的update,则处理将再次开始,因为过滤器检测到它们的输入与上次相比发生了更改。初学者的一个典型错误(至少对我来说是这样)是,试图在分配输入后立即获得过滤器的输出,而不确保从该过滤器或之后的过滤器更新。无论如何,您还可以在每个过滤器之后调用update,以确保一切正常(并且更容易调试)。我不确定是否有性能问题,但在我的应用程序中我没有注意到。
因此,当您从这些函数中获得输出时,请记住这一点!

第二,ITK智能指针可以简化你的编程,因为你不必记得在使用后删除它们,你也不必担心它们会在从函数返回时超出作用域。这也意味着有时事情不会像预期的那样得到更新,因为它们仍然保留旧数据(例如,如果在外部声明了for循环,则必须小心地在for循环中重置过滤器)。但通常它们会简化你的生活。

在每个函数中创建一个小的管道并不太难:你的输出将只是一个指向函数中最后一个过滤器输出的指针。您可以将此指针设置为函数的返回值(参见http://www.itk.org/Wiki/ITK/Examples/Utilities/ReturnObjectFromFunction)。或者您可以通过引用传递输出图像(就像在伪代码中一样,如果您传递的是已经通过引用传递的指针)。有关c++的更新,请参见例如http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/。伪代码:

int main ()
{
  ImageType::Pointer inputimage, output1, output2;
  inputimage = reader -> GetOutput();
  output1 = function1 (inputimage) // where input is Image 
  function2 (output1, output2) // where input now is the output of function1 , pass argument by reference
}
ImageType::Pointer function1 (ImageType::Pointer aInput)
 {
  somefilter::pointer filter = somefilter::new()
  filter ->SetInput( aInput);
  filter->Update(); // unless you know what you are doing (you know that youe will access the data only at the end )
  return filter->GetOutput()
 }
void function2 (ImageType::Pointer aInput, ImageType::Pointer aOutput)
 {
  somefilter::pointer filter = somefilter::new()
  filter ->SetInput( aInput);
  filter->Update(); 
  aOutput = filter->GetOutput()
 }

你甚至可以决定复制一个图像(这样它就独立于生成它的管道)并将其发送到另一个管道,参见http://www.itk.org/Wiki/ITK/Examples/SimpleOperations/ImageDuplicator

作为旁注,您还可以创建自己的类,将itk过滤器作为成员,在初始化时创建管道,然后只需在方法中修改过滤器的输入,而无需每次都重新创建管道。