VTK学习笔记(三十六)VTK图像填充

VTK学习笔记(三十六)VTK图像填充

1、官方示例

来自官方示例代码,自己只是添加了理解。

代码:

#include <vtkCamera.h>
#include <vtkImageActor.h>
#include <vtkImageConstantPad.h>
#include <vtkImageMapToWindowLevelColors.h>
#include <vtkImageMapper3D.h>
#include <vtkImageMirrorPad.h>
#include <vtkImageProperty.h>
#include <vtkImageReader2.h>
#include <vtkImageReader2Factory.h>
#include <vtkInteractorStyleImage.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>

int main(int argc, char* argv[])
{
  vtkNew<vtkNamedColors> colors;

  // Verify input arguments
  if (argc < 2)
  {
    std::cout << "Usage: " << argv[0] << " Filename e.g. FullHead.mhd"
              << std::endl;
    return EXIT_FAILURE;
  }

  // Read the image
  vtkNew<vtkImageReader2Factory> readerFactory;
  vtkSmartPointer<vtkImageReader2> reader;
  reader.TakeReference(readerFactory->CreateImageReader2(argv[1]));
  reader->SetFileName(argv[1]);
  reader->Update();

  // Pipelines
  vtkNew<vtkImageConstantPad> constantPad;
  constantPad->SetInputConnection(reader->GetOutputPort());
  constantPad->SetConstant(800);
  constantPad->SetOutputWholeExtent(-127, 383, -127, 383, 22, 22);

  vtkNew<vtkImageMirrorPad> mirrorPad;
  mirrorPad->SetInputConnection(reader->GetOutputPort());
  mirrorPad->SetOutputWholeExtent(constantPad->GetOutputWholeExtent());

  // Create actors

  vtkNew<vtkImageMapToWindowLevelColors> constantPadColor;
  constantPadColor->SetWindow(2000);
  constantPadColor->SetLevel(1000);
  constantPadColor->SetInputConnection(constantPad->GetOutputPort());

  vtkNew<vtkImageActor> constantPadActor;
  constantPadActor->GetMapper()->SetInputConnection(
      constantPadColor->GetOutputPort());
  constantPadActor->GetProperty()->SetInterpolationTypeToNearest();

  vtkNew<vtkImageMapToWindowLevelColors> mirrorPadColor;
  mirrorPadColor->SetWindow(2000);
  mirrorPadColor->SetLevel(1000);
  mirrorPadColor->SetInputConnection(mirrorPad->GetOutputPort());

  vtkNew<vtkImageActor> mirrorPadActor;
  mirrorPadActor->GetMapper()->SetInputConnection(
      mirrorPadColor->GetOutputPort());
  mirrorPadActor->GetProperty()->SetInterpolationTypeToNearest();

  // Setup renderers
  vtkNew<vtkRenderer> constantPadRenderer;
  constantPadRenderer->SetViewport(0.0, 0.0, 0.5, 1.0);
  constantPadRenderer->AddActor(constantPadActor);
  constantPadRenderer->ResetCamera();
  constantPadRenderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  vtkNew<vtkRenderer> mirrorPadRenderer;
  mirrorPadRenderer->SetViewport(0.5, 0.0, 1.0, 1.0);
  mirrorPadRenderer->AddActor(mirrorPadActor);
  mirrorPadRenderer->SetActiveCamera(constantPadRenderer->GetActiveCamera());
  mirrorPadRenderer->SetBackground(
      colors->GetColor3d("LightSlateGray").GetData());

  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->SetSize(600, 300);
  renderWindow->SetWindowName("Pad");
  renderWindow->AddRenderer(constantPadRenderer);
  renderWindow->AddRenderer(mirrorPadRenderer);

  vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
  vtkNew<vtkInteractorStyleImage> style;

  renderWindowInteractor->SetInteractorStyle(style);

  renderWindowInteractor->SetRenderWindow(renderWindow);
  constantPadRenderer->GetActiveCamera()->Dolly(1.2);
  constantPadRenderer->ResetCameraClippingRange();
  renderWindow->Render();
  renderWindowInteractor->Initialize();

  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

输入图像:FullHead.mhd

在这里插入图片描述

执行结果:

在这里插入图片描述

解释: 程序中执行了2个pad操作,分别为 常数pad操作和镜像pad操作,分别如上图左右所示。

 vtkNew<vtkImageConstantPad> constantPad;
  constantPad->SetInputConnection(reader->GetOutputPort());
  constantPad->SetConstant(800);
  constantPad->SetOutputWholeExtent(-127, 383, -127, 383, 22, 22);

以左图结果为例, constantPad 按照extent从原图取图像,x和y的范围正负方向分别向外扩展了127,z轴只取了第22层的一层数据。

参考:Pad

2、其他例子

#include <vtkCamera.h>
#include <vtkImageActor.h>
#include <vtkImageConstantPad.h>
#include <vtkImageMapToWindowLevelColors.h>
#include <vtkImageMapper3D.h>
#include <vtkImageMirrorPad.h>
#include <vtkImageProperty.h>
#include <vtkImageReader2.h>
#include <vtkImageReader2Factory.h>
#include <vtkInteractorStyleImage.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkNIFTIImageReader.h>
#include <vtkNIFTIImageWriter.h>
#include <vtkImageData.h>
#include <vtkMatrix3x3.h>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
  vtkNew<vtkNamedColors> colors;

  // Verify input arguments
 /* if (argc < 2)
  {
    std::cout << "Usage: " << argv[0] << " Filename e.g. FullHead.mhd"
              << std::endl;
    return EXIT_FAILURE;
  }*/

  string fileName = "input.nii.gz";
  vtkSmartPointer<vtkImageData> input;
  vtkSmartPointer <vtkNIFTIImageReader> niftireader = vtkSmartPointer<vtkNIFTIImageReader>::New();
  niftireader->SetFileName(fileName.c_str());
  niftireader->Update();
  input = niftireader->GetOutput();
  int inputDims[3] = { 0 };
  int extent[6] = { 0 };
  double origin[3] = { 0 };
  double spacing[3] = { 0 };
  input->GetDimensions(inputDims);
  input->GetExtent(extent);
  input->GetOrigin(origin);
  input->GetSpacing(spacing);
  auto matrix = input->GetDirectionMatrix();
  matrix->Print(std::cout);
  matrix->SetElement(0, 0, -1);
  matrix->SetElement(1, 1, -1);
  matrix->Print(std::cout);
  vtkNew<vtkImageConstantPad> constantPad;
  constantPad->SetInputConnection(niftireader->GetOutputPort());
  constantPad->SetConstant(800);
  constantPad->SetOutputWholeExtent(0, 100, 40, 88, 100, 200);
  constantPad->Update();
  input->GetDirectionMatrix()->Print(std::cout);
  vtkImageData* extracted = constantPad->GetOutput();
  double  newOrigin[3];
  //newOrigin[0] = origin[0] + 127 * spacing[0];
  newOrigin[1] = origin[1] + 40 * spacing[1];
  newOrigin[2] = origin[2] + 100 * spacing[2];
  extracted->SetOrigin(newOrigin);
  extracted->SetDirectionMatrix(matrix);
  
  string dstfileName = "constantPad.nii.gz";
  vtkSmartPointer<vtkNIFTIImageWriter> envImageWriter = vtkSmartPointer<vtkNIFTIImageWriter>::New();
  envImageWriter->SetInputData(extracted);
  envImageWriter->SetFileName(dstfileName.c_str());
  envImageWriter->Write();
  return EXIT_SUCCESS;

}

输入图像:
在这里插入图片描述

输出图像:

在这里插入图片描述
二者显示在一起:
在这里插入图片描述

可以看到输入图像和输出图像是不对齐的,并且二者的方向也不一致。
当给输出图像增加一个变换,使其IJK to RAS 矩阵也为-1,-1,1时,如下图所示:
可以看到二者是对齐的。
并且发现下面这段代码对于方向并不起作用,可能需要其他设置才可以指定IJK to RAS 矩阵。为-1,-1,1

 extracted->SetDirectionMatrix(matrix);

在这里插入图片描述

总结

通过这个示例说明使用vtkImageConstantPad 可以实现图像的基于体素的裁剪。但是需要注意方向和原点,避免数据对不齐。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花逐流水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值