VTK读取图片,然后QT显示

Posted fantianliang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VTK读取图片,然后QT显示相关的知识,希望对你有一定的参考价值。

一、前言

            今天实现的主要功能是通过vtk读取jpg图片(只能够读取.jpg文件),然后通过QT显示出来,整个程序的框架是QT GUIApplication

            版本:

VS 2019
VTK 8.2.0
QT 5.13.1
版本配置

VS 为release x64(这个是工程建立的时候设置的解决方案属性

VTK也是使用relealse x64编译获得的(这个是VTK安装的过程的编译选项)

QT也使用msvc2017-64bit(这个是QT安装的时候在VS平台配置的,如果发现不对要更改)

二、参考博客

          博客:https://blog.csdn.net/qq_41969439/article/details/88666629?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

           

三、工程建立

        1、新建一个QGui Application

           设置VS项目解决方案配置为release x64:

              技术图片

        2、打开.ui文件

           这个时候会出现一个QT designer界面,我们需要注意是否存在QVTKWidget控件

         技术图片

         如果存在这个控件(如果没有参见后面的解决办法),那么我们把这个控件拖动到中间。

         3、然后拖动一个pushButton,一个linText, 形成的界面和上一个例子大概是一样的,最后的显示功能也是一样,只不过这个时候是采用的vtk显示图像。

         技术图片

 

         4、保存ui文件,然后关闭

         5、按照之前的博客讲述的方法编译ui文件,重新扫描解决方案

         6、在属性管理器Release x64下面添加属性表:

             把配置好的两个属性表复制到本工程目录,然后点击Release x64,然后右键,选择添加现有属性表

                    技术图片

 

         7、将代码复制到文件中:

          这里我的项目名字为:VTKReadJpg_InQT_Test

          各个文件代码如下:

           VTKReadJpg_InQT_Test.h

技术图片
#pragma once
//#pragma warning(disable: 26498 )
/*QT file*/
#include <QtWidgets/QMainWindow>
#include "ui_VTKReadJpg_InQT_Test.h"
#include <QFileDialog>
#include <QDir>
#include <qstring.h>
#include <qlineedit.h>
#include <QpushButton>
/*vtk File*/
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkImageViewer2.h>
#include <QVTKWidget.h>
#include <vtkBMPReader.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkEventQtSlotConnect.h>
#include "vtkCommand.h"
#include <vtkOutputWindow.h>
#include "vtkSmartPointer.h"
//为了能够使用vtk添加代码
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
using namespace std;
class vtkImageViewer2;
class vtkRenderer;
class vtkEventQtSlotConnect;
class QVTKWidget;

class VTKReadJpg_InQT_Test : public QMainWindow
{
    Q_OBJECT

public:
    VTKReadJpg_InQT_Test(QWidget* parent = Q_NULLPTR);

private:
    Ui::VTKReadJpg_InQT_TestClass ui;
private slots:
    void onOpenSlot(void);
private:
    vtkSmartPointer<vtkImageViewer2> m_pImageViewer;
    vtkSmartPointer<vtkRenderer> m_pRenderer;
    //QVTKWidget m_qvtkWidget;
};
View Code

           VTKReadJpg_InQT_Test.cpp

技术图片
#include "VTKReadJpg_InQT_Test.h"

VTKReadJpg_InQT_Test::VTKReadJpg_InQT_Test(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    m_pImageViewer = vtkSmartPointer<vtkImageViewer2>::New();
    m_pRenderer = vtkSmartPointer<vtkRenderer>::New();

    //设置qvtkWidget的渲染器
    ui.qvtkWidget->GetRenderWindow()->AddRenderer(m_pRenderer);
    //m_qvtkWidget.GetRenderWindow()->AddRenderer(m_pRenderer);
    //连接信号和槽
    //
    connect(ui.pushButton, SIGNAL(clicked(bool)), this, SLOT(onOpenSlot()));

}
void VTKReadJpg_InQT_Test::onOpenSlot(void)
{
    QString FileInstruction;
    FileInstruction = "Image Files(*.jpg *.jpeg);;All(*.*)";
    QDir FileDir;
    //QString fileName = QFileDialog::getOpenFileName(this, QString(tr("打开图像")), "", File);
    QString fileName = QFileDialog::getOpenFileName(this,
                                                   "please choose an image file",
                                                   "",
                                                   FileInstruction);
    
    if (fileName.isEmpty() == true)
    {
        cout << "error" << endl;
        return;
    }
    //显示路径
    QFileInfo OpenFileInfo;
    OpenFileInfo = QFileInfo(fileName);
    QString OpenFilePath = OpenFileInfo.filePath();
    ui.lineEdit->setText(OpenFilePath);
    // 支持带中文路径的读取
    QByteArray ba = fileName.toLocal8Bit();
    const char* fileName_str = ba.data();
    //使用vtkJPEGReader读取图像
    vtkSmartPointer<vtkJPEGReader>reader = vtkSmartPointer<vtkJPEGReader>::New();
    reader->SetFileName(fileName_str);
    //reader->SetFileName("D:Pictures1.jpg");
    reader->Update();
    //将reader 的输出作为 viewer的输入,并且设置Viewer与渲染器的关联
    //m_pImageViewer->SetInputData(reader->GetOutput());
    m_pImageViewer->SetInputData(reader->GetOutput());
    
    m_pImageViewer->UpdateDisplayExtent();
    m_pImageViewer->SetRenderWindow(ui.qvtkWidget->GetRenderWindow());
    m_pImageViewer->SetRenderer(m_pRenderer);
    m_pImageViewer->SetupInteractor(ui.qvtkWidget->GetRenderWindow()->GetInteractor());
    m_pImageViewer->SetSliceOrientationToXY();//默认就是这个方向
    m_pImageViewer->GetImageActor()->InterpolateOff();

    m_pRenderer->ResetCamera();
    m_pRenderer->DrawOn();
    ui.qvtkWidget->SetRenderWindow(m_pImageViewer->GetRenderWindow());
    ui.qvtkWidget->GetRenderWindow()->Render();
    

}
View Code

          main.cpp

技术图片
#include "VTKReadJpg_InQT_Test.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    vtkOutputWindow::SetGlobalWarningDisplay(0);
    QApplication a(argc, argv);
    VTKReadJpg_InQT_Test w;
    w.show();
    return a.exec();
}
View Code

         7、运行出现的结果

                技术图片

 

四、出现问题

           工程建立的过程出现了以下的几个问题:

           1-在单独打开的QT designer里面可以找到 QVTKWidget, 但是VS打开的QT designer( 也就是我们打开的ui文件出现的界面)里面找不到QVTKWidget.

             解决办法:参考博客:在QtDesigner中添加QVTKWidget

             1.1这个时候首先我们先要检查有没有添加.dll文件:

             找到QVTKWidget.dll文件:

           技术图片

          复制到下面文件夹:

             技术图片

             1.2然后在打开 ui界面里面点击:

             帮助-》关于插件-》刷新

             技术图片

             技术图片

             多尝试几次

 

      2、在ui界面已经定义的控件,在cpp里面不能调用

            这个方法在上面一个博客里面已经讲过了

      3、无法解析的外部符号

             技术图片

 

 

            这个时候找到了一个相同的帖子,和我的情况是完全一样的:

            https://bbs.csdn.net/topics/391908935?page=1

            别人说是链接的问题。

            所以我重新更新了一遍vtk属性表里面的链接器-》输入-》附加依赖项里面的.lib列表

            这个问题就没有出现了.

            不过这个时候也要注意,也有可能是你的vtk在安装的时候没有完全勾选与QT有关的选项,所以导致有的.lib文件没有生成。

             遇到这种情况大家应该想一想是不是自己的属性表配置有问题或者是不全

      4、运行出现了版本警告

            技术图片

              这个时候我为了不显示,使用了下面的代码注释了警告:

//添加头文件
#include <vtkOutputWindow.h>
//在main.cpp的main函数开头添加
vtkOutputWindow::SetGlobalWarningDisplay(0);

      5、再次运行发现什么反应都没有

            经过检查发现是我因为我把所有警告注释掉了,所以没有生成程序界面,也没有任何反应。

            警告如下:

            技术图片

            为了解决第三个警告,添加了如下的代码(实际上为了在VS里面使用VTK,下面的代码是最好要添加的

#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);

       6、在打开的QT designer里面发现插件QVTKWidget加载失败

            这个我重新打开就好了,也不知道为什么,很迷。

五、一点体会

          感觉怎么说呢,本来想着从网上借鉴一下程序,结果发现各种错误层出不穷,搞的自己筋疲力尽,不过好在程序终于跑出来了,不知道别人有没有我这么艰难,起码我是感觉自己快吐了。

六、参考链接

        一、程序来源:程序

        二、在QT designer 添加QVTKWidget

        三、no override found for vtkImageSliceMapper

        四、ui界面有控件,但是cpp里面显示没有成员(注释:无法使用控件)

        

 

            

   

 

以上是关于VTK读取图片,然后QT显示的主要内容,如果未能解决你的问题,请参考以下文章

十ITK读取一张dcm图像然后通过vtk显示

ifstream读取图片,Qt载入显示

Qt&Vtk-008-Cone3

win10环境下VTK7.1的编译和Qt调用VTK的详细教程(本文链接含VTK库和测试代码的分享)

使用 QT+VTK+ITK 构建项目时出现 FDFImageIO 错误

Qt下使用OpenGL读取和显示3ds模型