ITK 转换成VTK ImageData 后用QT 显示的错误记录

最近要使用ITK 进行一些分割算法的实现,所以就联合了之前的VTK+QT 做了一个小的测试,现在把过程和错误及解决方案记录下来,以便以后少踩坑。
环境配置:
VTK 7.0
QT 5.7
ITK 4.11
vs2015
系统64位

1、使用Cmake编译ITK 的时候过程基本和VTK 差不多,但是这里没有编译成功ITK 的python接口。尝试了一下,发现在后面的生成的时候会缺少python27_d.dll. 因为python不是自己编译的,所以就放弃了Debug模型下的python接口编译。后面在release 模式下页尝试了编译,但是仍然有错误。因为暂时不需要使用python所以就跳过了。如果有编译成功的,也希望大家能分享一下自己的经验。接下来就是为了要配合vtk的使用,在camke编译的时候勾选vtkglue 这个module就可以了。编译过程比较顺利没有什么问题。
2、找了一个example来实现ITK image To Vtk。
example:Itk image convert to vtk image example

主要的代码如下:

  typedef itk::Image<itk::RGBPixel<unsigned char>, 2> ImageType;
  typedef itk::ImageFileReader<ImageType>             ReaderType;
  typedef itk::ImageToVTKImageFilter<ImageType>       ConnectorType;

  ReaderType::Pointer reader = ReaderType::New();
  ConnectorType::Pointer connector = ConnectorType::New();

  reader->SetFileName(argv[1]);
  connector->SetInput(reader->GetOutput());

  vtkSmartPointer<vtkImageActor> actor =
    vtkSmartPointer<vtkImageActor>::New();
#if VTK_MAJOR_VERSION <= 5
  actor->SetInput(connector->GetOutput());
#else
  connector->Update();
  actor->GetMapper()->SetInputData(connector->GetOutput());
#endif
  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(actor);
  renderer->ResetCamera();

  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);

  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  vtkSmartPointer<vtkInteractorStyleImage> style =
    vtkSmartPointer<vtkInteractorStyleImage>::New();

  renderWindowInteractor->SetInteractorStyle(style);

  renderWindowInteractor->SetRenderWindow(renderWindow);
  renderWindowInteractor->Initialize();

  renderWindowInteractor->Start();

上述代码在VTK当中运行的没有问题,还尝试了ITK 自带的QuickViewr,都ok。但是在我将最后的renderWindow 放入的QVTWidg中时就报错了,我的代码如下:

    this->ui.vtkWidget1->SetRenderWindow(renderWindow);
    renderWindow->AddRenderer(renderer);
    this->ui.vtkWidget1->GetRenderWindow()->Start();

错误如下:
ITK 图片通过VTK 显示的错误

中断之后就是:帧不在模块中了,对于我来说去看反汇编更不可能了。
就只能慢慢分析问题的可能原因了:
1、使用VTK自带的窗口和itk的quickview显示都没有问题,那么矛头就是在QWidget上了。
2、QWidget这个是大神写的估计本身应该没有问题,而且之前使用的时候和VTK 兼容的很好。
3、那就可能是数据的问题,而且是访问冲突的错误,那么就是itktovtk的imagedata和vtk自身读取的imagedata的问题。关于两个数据的差别,网上都有,但是不影响显示,那么访问冲突的话,我就试试把数据拷贝一下吧。
4、vtkImageData* myvtkImageData = connector->GetOutput();
vtkImageData* img = vtkImageData::New();
img->DeepCopy(myvtkImageData);

使用上面的深拷贝把imagedata的数据拷贝一下,然后再用img去显示,就没有问题了。
5、qt的界面显示是在最后main函数里面的show调用后。但是我把函数写在整个界面生成之前(直接运行就出来结果那种),则在界面生成前数据就已经准备好了,但是最后生成界面的时候再去访问这个数据,可能就发生了冲突(虽然之前VTK,没有这样的问题)觉得这可能是ITK自身数据存储的问题。
6、那么除了深拷贝,按照上面的逻辑,我可以先生成Qwidget界面后再通过按钮之类的来显示呢,是否就会避免上述的问题呢?
好吧,还是有问题,看来这个数据无论如何都不能被QT 拿来显示了,所以先用深拷贝了,也试过用static 静态数据,都没有用。
7、结果通过深拷贝:

Image show from vtkImageData converted from ITk

完整的代码如下:

void itk_example::myItkTest()
{

    itk::PNGImageIOFactory::RegisterOneFactory();
    typedef itk::Image<itk::RGBPixel<unsigned char>, 2> ImageType;
    typedef itk::ImageFileReader<ImageType>             ReaderType;
    typedef itk::ImageToVTKImageFilter<ImageType>       ConnectorType;

    ReaderType::Pointer reader = ReaderType::New();
    ConnectorType::Pointer connector = ConnectorType::New();
    reader->SetFileName("C:\\Users\\jhj\\Documents\\Visual Studio 2015\\Projects\\itk_example\\itk_example\\Resources\\12.png");
    connector->SetInput(reader->GetOutput());
    vtkSmartPointer<vtkImageActor> actor =
        vtkSmartPointer<vtkImageActor>::New();
    connector->Update();                               // VTK 7.0 must update
    vtkImageData* img = vtkImageData::New();      //deep copy 
    img->DeepCopy(connector->GetOutput());
    actor->GetMapper()->SetInputData(img);
    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->ResetCamera();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    ui.vtkWidget1->SetRenderWindow(renderWindow);
    ui.vtkWidget1->update();
}

conclusion:

1、首先遇到问题不要慌,多看看官方的文档,多问问有经验的人(师兄就给了比较好的建议)
2、自己分析问题的思路还不够清晰,导致这个问题纠结了很久,当然知识储备量不够要背锅。
3、这个问题个人很有兴趣深挖下去(可以学到很多更深层次的东西),但是由于项目时间紧张,以后有时间再挖吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

皮尔菲特

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

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

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

打赏作者

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

抵扣说明:

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

余额充值