zl程序教程

您现在的位置是:首页 >  其他

当前栏目

BestMPRBaseVtk-005-翻车加修车

2023-04-18 14:13:39 时间
头图

翻车加修车

​ 翻车了,亲人们,家人们,我翻车了,欢迎大家来看我翻车修车。

​ 事情是这样的,上篇咱不是搬运人家官方的vtkImageViewer2的代码了,但是呢,忘记之前的踩过的坑了,医学四视图-003-解决图像反转(失败)在这里的坑再次出现在我的代码里,但是呢,我TM早就忘记了。看看这次的教训

image-20211209143518344

​ 不过好在咱运气好,遇到了黑山老妖大神不厌其烦的知道,现在终于修车完成,不过已经不是使用vtkImageViewer2,更换了vtkImageReslice;来看看效果吧

image-20211209144734179


关键字: vtkImageResliceMPRVTKvtkImageViewer2vtkMatrix4x4

vtkImageReslice实现MPR

这里就直接上贴上代码吧,目前的能力还没有啥资格来搞这个问题,还是上大神代码

基于VTK的MPR实现

VTK笔记-计算MPR切面-vtkImageReslice类

MyImageResliceWindow.h

#ifndef MYIMAGERESLICEWINDOW_H
#define MYIMAGERESLICEWINDOW_H

#include <QWidget>
#include "QVTKOpenGLNativeWidget.h"
#include "vtkSmartPointer.h"
#include "vtkMetaImageReader.h"
#include "vtkImageData.h"
#include "vtkMatrix4x4.h"
#include "vtkImageReslice.h"
#include "vtkLookupTable.h"
#include "vtkImageMapToColors.h"
#include "vtkImageActor.h"
#include "vtkImageMapper3D.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkDICOMImageReader.h"
#include "vtkCamera.h"
namespace Ui {
class MyImageResliceWindow;
}

class MyImageResliceWindow : public QWidget
{
    Q_OBJECT

public:
    explicit MyImageResliceWindow(QWidget *parent = nullptr);
    ~MyImageResliceWindow();


    /**
     * @brief readDicom
     * @param temp 文件路径
     * 设置读取文件夹
     */
    void readDicom(QString temp);
    /**
     * @brief initImageForm
     * 初始化流水线
     */
    void initImageForm();

private slots:
    /**
     * @brief on_pushButton_reader_clicked
     * 选择读取Dicom文件夹按钮槽函数
     */
    void on_pushButton_reader_clicked();
    /**
     * @brief on_pushButton_reader_2_clicked
     * 直接测试按钮槽函数
     */
    void on_pushButton_reader_2_clicked();
    /**
     * @brief on_pushButton_SetDirection_clicked
     * 切换切面显示槽函数
     */
    void on_pushButton_SetDirection_clicked();

private:
    Ui::MyImageResliceWindow *ui;

    int extent[6];          //序列范围
    double spacing[3];      //图像切片间距
    double origin[3];       //图像原点
    double center[3];       //物体中心点
    //轴状矩阵
    double axialElements[16] = {
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
    };
    //矢状矩阵
    double sagittalElements [16] = {
        0, 0, -1, 0,
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 0, 1 };
    //冠状矩阵
    double coronalElements [16] = {
        1, 0, 0, 0,
        0, 0, -1, 0,
        0, -1, 0, 0,
        0, 0, 0, 1 };

    vtkSmartPointer<vtkDICOMImageReader> reader = nullptr;      //Dicom文件读取器
    vtkSmartPointer<vtkMatrix4x4> resliceAxes[3];               //vtk 4×4矩阵
    vtkSmartPointer<vtkImageReslice> reslice[3];                //vtkImageReslice切片类
    vtkSmartPointer<vtkLookupTable> colorTable[3];              //颜色映射表
    vtkSmartPointer<vtkImageMapToColors> colorMap[3];           //图像彩色映射
    vtkSmartPointer<vtkImageActor> imgActor[3];                 //图像Actor
    vtkSmartPointer<vtkRenderer> renderer[3];                   //图像渲染器
};

#endif // MYIMAGERESLICEWINDOW_H

MyImageResliceWindow.cpp

#include "myimagereslicewindow.h"
#include "ui_myimagereslicewindow.h"
#include <QFileDialog>
#include <QtDebug>
MyImageResliceWindow::MyImageResliceWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyImageResliceWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("MPR Demo And Test");
    reader = vtkDICOMImageReader::New();
    reader->SetDirectoryName("D:\00_Code\ST0\SE2");

    for(int i = 0;i<3;i++)
    {
        reslice[i] = vtkSmartPointer<vtkImageReslice>::New();
        resliceAxes[i] = vtkSmartPointer<vtkMatrix4x4>::New();
        colorTable[i] = vtkSmartPointer<vtkLookupTable>::New();
        colorMap[i] = vtkSmartPointer<vtkImageMapToColors>::New();
        imgActor[i] = vtkSmartPointer<vtkImageActor>::New();
        renderer[i] = vtkSmartPointer<vtkRenderer>::New();
    }
}

MyImageResliceWindow::~MyImageResliceWindow()
{
    delete ui;
}

void MyImageResliceWindow::readDicom(QString temp)
{
    reader->SetDirectoryName(temp.toLocal8Bit().data());                    //设置文件夹路径
    reader->Update();                                                       //更新
    reader->GetOutput()->GetExtent(this->extent);                           //获取图像序列范围
    reader->GetOutput()->GetSpacing(this->spacing);                         //获取数据间距
    reader->GetOutput()->GetOrigin(this->origin);                           //获取原点

    center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);     //获取中心点
    center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);     //获取中心点
    center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);     //获取中心点
}

void MyImageResliceWindow::initImageForm()
{
    resliceAxes[0]->DeepCopy(axialElements);
    resliceAxes[1]->DeepCopy(sagittalElements);
    resliceAxes[2]->DeepCopy(coronalElements);
    for (int i = 0; i< 3; i++ ) {
        reslice[i]->SetInputConnection(reader->GetOutputPort());                    //设置数据输入源
        reslice[i]->SetOutputDimensionality(2);                                     //设置输出为一个切片,而不是一个卷
        reslice[i]->SetResliceAxes(resliceAxes[i]);                                 //设置矩阵
        reslice[i]->SetResliceAxesOrigin(center[0],center[1],center[2]);            //设置切片中心点
        reslice[i]->SetInterpolationModeToLinear();                                 //设置切面算法的插值方式线性插值
        colorTable[i]->SetRange(0, 1000);                                           //设置颜色表范围
        colorTable[i]->SetValueRange(0.0, 1.0);                                     //设置颜色表精度
        colorTable[i]->SetSaturationRange(0.0, 0.0);                                //设置曝光范围 ?
        colorTable[i]->SetRampToLinear();                                           //设置颜色表为线性
        colorTable[i]->Build();                                                     //构建
        colorMap[i]->SetLookupTable(colorTable[i]);                                 //设置颜色表
        colorMap[i]->SetInputConnection(reslice[i]->GetOutputPort());               //设置图像数据
        imgActor[i]->GetMapper()->SetInputConnection(colorMap[i]->GetOutputPort()); //添加映射器
        renderer[i]->AddActor(imgActor[i]);                                         //添加演员
        renderer[i]->SetBackground(0.0, 0.0, 0.0);                                  //设置背景
    }
    ui->openGLWidget_1->renderWindow()->AddRenderer(renderer[0]);                   //UI渲染窗口添加渲染器
    ui->openGLWidget_1->renderWindow()->Render();                                   //开始渲染
    ui->openGLWidget_2->renderWindow()->AddRenderer(renderer[1]);                   //UI渲染窗口添加渲染器
    ui->openGLWidget_2->renderWindow()->Render();                                   //开始渲染
    ui->openGLWidget_3->renderWindow()->AddRenderer(renderer[2]);                   //UI渲染窗口添加渲染器
    ui->openGLWidget_3->renderWindow()->Render();                                   //开始渲染

}

/**
 * @brief MyImageResliceWindow::on_pushButton_reader_clicked
 * 读取Dicom文件
 */
void MyImageResliceWindow::on_pushButton_reader_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("Open Folder"),"D:\00_Code\ST0\SE2",QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);
    if(!dir.isEmpty())
    {
        readDicom(dir);
        initImageForm();
    }
}


void MyImageResliceWindow::on_pushButton_reader_2_clicked()
{
    readDicom(QString("D:\00_Code\ST0\SE2"));
    initImageForm();

    update();
}

/**
 * @brief MyImageResliceWindow::on_pushButton_SetDirection_clicked
 * 切换切面
 */
void MyImageResliceWindow::on_pushButton_SetDirection_clicked()
{

}


心得

​ 这几天就这一个图像方向问题,折腾了好久了,其实还是心态的问题,开始我真的是火急火燎,想在几分钟内解决问题,但是呢,到头来,还是没有解决,感谢黑山老妖,让我还是回到了开发软件的感觉上来,软件开发就是一个耐心吃错,找BUG过程,如果每次都一下就过,那估计离离开也不远了,因为只有写1+1=2 才不会有问题。所以遇到问题还是要耐心,稳定情绪,遇到问题,有一个好的心态,问题已经解决80% 剩下的20%交给时间。

​ 已经2021年12月,这一年眼看就要过完了,话说,大家都挣到钱了吗,咋感觉2021 钱更难挣,更容易花了呢。最后的最后,有人帮我还一点吗?

☞ 源码

源码链接:GitHub仓库自取

使用方法:☟☟☟

源码


博客签名2021