医学四视图-003-解决图像反转(失败)

Posted DreamLife.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了医学四视图-003-解决图像反转(失败)相关的知识,希望对你有一定的参考价值。

​ 先说结论,本文最终也没有解决图像反转问题,仅仅是过程记录。咨询了老大,老大说以我的能力,暂时还搞不定,所以就暂时先搁置。

1 都是演示的错

​ 哎呀,今天可是丢人大方了,今天博士来公司了,我兴匆匆的去嘚瑟下,告诉博士我实现了四视图了,博士说那就给我演示下呗,我这就麻溜的打开我的工程,演示起来,结果,呵呵哒。

​ 如上图所示,我的图像是反转的。

​ 在MITK中打开,人家的是真确的,为此,我编译了VTK官方的示例QtVTKRenderWindow,也是反的,我还以为我抄代码都能抄错了呢。但是问题来了,我改怎么搞呢,为什么是翻的呢,以我目前的认知,应该是坐标系的问题吧。

2 编译MITK2.21.2

​ 其实编译MITK完全是吃饱了撑的,因为不用编译,就可以看到源码,我还是编译了,并且折腾了好久,链接在这里,当你掌握了,就简单了,真的简单,曾经也在多个夜晚骂MITK团队,搞得啥破玩意,最后发现小丑竟是自己哈哈。其实编译MITK是想看看人家是怎么实现的。

https://blog.csdn.net/z609932088/article/details/118831590?spm=1001.2014.3001.5502

3 找问题原因

​ 在读取DICOM文件的时候,我使用的是vtkDICOMImageReader,而且用法也很简单,代码如下,这里不是出问题的地方,而且我也通过另外一个例子证明了。

        if(!reader)
        {
            reader = vtkSmartPointer<vtkDICOMImageReader>::New();
        }
        reader->SetDirectoryName(fn);                              //这里主要,是文件夹哈,不是文件名
        reader->Update();                                          //得更新呀,惰性渲染
        reader->GetOutput()->GetDimensions(imageDims);             //还不理解,翻译为获取维度,注释掉以后三维中有影响

​ 在下面,使用了vtkResliceImageViewer,这里仅仅就是创建了三个vtkResliceImageViewer对象,也是没有问题的。

        for (auto i = 0; i < 3; i++)
        {
            riw[i] = vtkSmartPointer< vtkResliceImageViewer >::New();
//            vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
//            riw[i]->SetRenderWindow(renderWindow);
//            riw[i]->SetColorLevel(128);
//            riw[i]->SetColorWindow(256);
        }

​ 再往下就是设置渲染窗口和设置交互器,也没有问题。

        riw[0]->SetRenderWindow(ui->widget_1->GetRenderWindow());
        riw[0]->SetupInteractor(ui->widget_1->GetRenderWindow()->GetInteractor());

        riw[1]->SetRenderWindow(ui->widget_2->GetRenderWindow());
        riw[1]->SetupInteractor(ui->widget_2->GetRenderWindow()->GetInteractor());

        riw[2]->SetRenderWindow(ui->widget_3->GetRenderWindow());
        riw[2]->SetupInteractor(ui->widget_3->GetRenderWindow()->GetInteractor());

​ 到了怀疑的地方了,这里rep->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(i);,如果把这句话注释掉的话,那就会报错误Resetting view-up since view plane normal is parallel,这个错误里面有一个关键字view-up,通过有道翻译出来的也不咋懂,重置视图,因为视图平面法线是平行的

        for (int i = 0; i < 3; i++)
        {
            vtkResliceCursorLineRepresentation *rep =
                vtkResliceCursorLineRepresentation::SafeDownCast(riw[i]->GetResliceCursorWidget()->GetRepresentation());
            riw[i]->SetResliceCursor(riw[0]->GetResliceCursor());
            rep->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(i);
            riw[i]->SetInputData(reader->GetOutput());
            riw[i]->SetSliceOrientation(i);
//            riw[i]->SetResliceModeToAxisAligned();
            riw[i]->SetResliceModeToOblique();

        }

3.1vtkResliceCursorLineRepresentation

​ 凭着我男人的第六感,我感觉应该是这个类搞得事情,所以我要看看这个类。通过我强大的翻译能力,把这个类名分割一下**Re slice Cursor Line Representation **翻译过来应该是重新切片光标表示。

​ 这里出现了一个新的东西SafeDownCast()开始以为是一个VTK的接口,后面发现在VTK中是搜不到这个东西的,具体是什么,我也不知道,Google以后就只有下面的解释。

3.1.1GetRepresentation

​ 这里可以研究下GetRepresentation()它返回的正是vtkWidgetRepresentation

vtkWidgetRepresentation *GetRepresentation()
  {
      this->CreateDefaultRepresentation();
      return this->WidgetRep;
  }

SetReslicePlaneNormal源码如下:

​ 根据有道翻译,SetReslicePlaneNormal就是设置默认平面的。经过尝试,也不是这里出的问题,仅仅是设置平面。

  enum {XAxis=0,YAxis,ZAxis};

  /**
   * Set the planes that correspond to the reslice axes.
   */
  void SetReslicePlaneNormalToXAxis()
    { this->SetReslicePlaneNormal(XAxis); }
  void SetReslicePlaneNormalToYAxis()
    { this->SetReslicePlaneNormal(YAxis); }
  void SetReslicePlaneNormalToZAxis()
    { this->SetReslicePlaneNormal(ZAxis); }

3.1.2SetSliceOrientation

​ 后面我又开始研究SetSliceOrientation,源码如下:

​ 测试这个接口是有影响,但是呢,运行就死机,好尴尬。

  /**
   * Set/get the slice orientation
   */

  enum
  {
    SLICE_ORIENTATION_YZ = 0,
    SLICE_ORIENTATION_XZ = 1,
    SLICE_ORIENTATION_XY = 2
  };

  vtkGetMacro(SliceOrientation, int);
  virtual void SetSliceOrientation(int orientation);
  virtual void SetSliceOrientationToXY()
    { this->SetSliceOrientation(vtkImageViewer2::SLICE_ORIENTATION_XY); };
  virtual void SetSliceOrientationToYZ()
    { this->SetSliceOrientation(vtkImageViewer2::SLICE_ORIENTATION_YZ); };
  virtual void SetSliceOrientationToXZ()
    { this->SetSliceOrientation(vtkImageViewer2::SLICE_ORIENTATION_XZ); };

​ 在使用原生Demo测试时候,也是会出现错误,VS报告如下:这个Qt就得出来背锅了,不明白的就是为什么设置按照顺序012可以,倒过来就不可以呢,费解,发生这个问题后面找到了解决方法,就是换Qt版本,目前我虽然使用了5.14.2 的壳子,但是内核还是5.7.1 这个版本的的问题还真是多,也不知道算不算是BUG。

​ 更换Qt版本也很简单,如下图所示。

​ 最终测试也不是这里的问题。目前还未解决!!!

​ 2021年7月26日更新,今天问题还是未接,询问博士,博士说我能力暂时搞不定呀,那几只能先开坑,后面再说了。本篇到此结束。

☞ 源码

源码链接:https://github.com/DreamLife-Jianwei/Qt-Vtk

使用方法:☟☟☟


以上是关于医学四视图-003-解决图像反转(失败)的主要内容,如果未能解决你的问题,请参考以下文章

BestMPRBaseVtk-005-翻车加修车

BestMPRBaseVtk-006-继续修VtkImageViewer2的车

医学四视图-004-四视图增加文字显示

医学四视图-002-四视图实现

医学四视图-006-升级Vtk版本至9.0.3

医学四视图-001-基本框架搭建