VTK 圖像濾波

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QDebug>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkJPEGReader.h>
#include <vtkImageData.h>
#include <vtkImageLuminance.h>
#include <vtkImageActor.h>
#include <vtkImageThreshold.h>
#include <vtkInteractorStyleImage.h>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void openFileSlot();
private:
    vtkSmartPointer<vtkRenderer>               pSrcMeanRenderer;
    vtkSmartPointer<vtkRenderer>               pMeanRenderer;

    vtkSmartPointer<vtkRenderer>               pSrcMeadianRenderer;
    vtkSmartPointer<vtkRenderer>               pMeadianRenderer;

    vtkSmartPointer<vtkRenderer>               pSrcGaussianRenderer;
    vtkSmartPointer<vtkRenderer>               pGaussianRenderer;

    vtkSmartPointer<vtkRenderer>               pSrcAnisotropicRenderer;
    vtkSmartPointer<vtkRenderer>               pAnisotropicRenderer;

    vtkSmartPointer<vtkImageActor>             pSrcMeanImageActor;
    vtkSmartPointer<vtkImageActor>             pMeanImageActor;

    vtkSmartPointer<vtkImageActor>             pSrcMeadianImageActor;
    vtkSmartPointer<vtkImageActor>             pMeadianmageActor;

    vtkSmartPointer<vtkImageActor>             pSrcGaussianImageActor;
    vtkSmartPointer<vtkImageActor>             pGaussianImageActor;

    vtkSmartPointer<vtkImageActor>             pSrcAnisotropicImageActor;
    vtkSmartPointer<vtkImageActor>             pAnisotropicImageActor;

    vtkSmartPointer<vtkInteractorStyleImage>   pImageStyle;
    vtkSmartPointer<vtkJPEGReader>             pJpegReader;
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <vtkImageGradient.h>
#include <vtkImageMagnitude.h>
#include <vtkImageShiftScale.h>
#include <vtkImageSobel2D.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageMathematics.h>
#include <vtkImageLuminance.h>
#include <vtkImageCast.h>
#include <vtkImageConvolve.h>
#include <vtkImageHybridMedian2D.h>
#include <vtkImageGaussianSmooth.h>
#include <vtkImageAnisotropicDiffusion2D.h>
#include <vtkImageNoiseSource.h>
#include <vtkImageGaussianSource.h>
#include <vtkImageSinusoidSource.h>
#include <vtkImageIterator.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 均值濾波(各向同性)
    {
        pSrcMeanRenderer         = vtkSmartPointer<vtkRenderer>::New();
        pSrcMeanRenderer->SetBackground(1.0, 0, 0);
        pSrcMeanRenderer->SetViewport(0, 0, 0.5, 0.25);

        pMeanRenderer      = vtkSmartPointer<vtkRenderer>::New();
        pMeanRenderer->SetBackground(1.0, 0, 0);
        pMeanRenderer->SetViewport(0.5, 0, 1.0, 0.25);
    }

    // 中值濾波
    {
        pSrcMeadianRenderer         = vtkSmartPointer<vtkRenderer>::New();
        pSrcMeadianRenderer->SetBackground(0, 1.0, 0);
        pSrcMeadianRenderer->SetViewport(0, 0.25, 0.5, 0.5);

        pMeadianRenderer      = vtkSmartPointer<vtkRenderer>::New();
        pMeadianRenderer->SetBackground(0, 1.0, 0);
        pMeadianRenderer->SetViewport(0.5, 0.25, 1.0, 0.5);
    }

    // 高斯濾波
    {
        pSrcGaussianRenderer         = vtkSmartPointer<vtkRenderer>::New();
        pSrcGaussianRenderer->SetBackground(0, 0, 1.0);
        pSrcGaussianRenderer->SetViewport(0, 0.5, 0.5, 0.75);

        pGaussianRenderer      = vtkSmartPointer<vtkRenderer>::New();
        pGaussianRenderer->SetBackground(0, 0, 1.0);
        pGaussianRenderer->SetViewport(0.5, 0.5, 1.0, 0.75);
    }

    // 各向異性濾波
    {
        pSrcAnisotropicRenderer      = vtkSmartPointer<vtkRenderer>::New();
        pSrcAnisotropicRenderer->SetBackground(1.0, 0, 0);
        pSrcAnisotropicRenderer->SetViewport(0, 0.75, 0.5, 1.0);

        pAnisotropicRenderer      = vtkSmartPointer<vtkRenderer>::New();
        pAnisotropicRenderer->SetBackground(1.0, 0, 0);
        pAnisotropicRenderer->SetViewport(0.5, 0.75, 1.0, 1.0);
    }

    connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(openFileSlot()));
}

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

void MainWindow::openFileSlot()
{
#if 1
    QString selectFilePath = QFileDialog::getOpenFileName(this, QString("選擇圖像文件"), QString(""), QString("圖像(*.jpg)"));
#else
    QString selectFilePath = QFileDialog::getOpenFileName(this, QString("選擇圖像文件"), QString(""), QString("圖像(*.png)"));
#endif
    if(selectFilePath.isEmpty())
    {
        ui->textBrowser->append("選擇圖像路徑爲空!");
        return ;
    }
    else
    {
        ui->textBrowser->append(selectFilePath);
    }

    pJpegReader = vtkSmartPointer<vtkJPEGReader>::New();
    pJpegReader->SetFileName(selectFilePath.toStdString().c_str());
    pJpegReader->Update();

    int dims[3];
    pJpegReader->GetOutput()->GetDimensions(dims);

    qDebug() << "dims = " << dims[0] << ", " << dims[1] << ", " << dims[2];

    vtkSmartPointer<vtkImageLuminance> pImageLuminance = vtkSmartPointer<vtkImageLuminance>::New();
    pImageLuminance->SetInputData(pJpegReader->GetOutput());
    pImageLuminance->Update();

    // 數據類型 unsigned char => float
    vtkSmartPointer<vtkImageCast> pImageCast1 = vtkSmartPointer<vtkImageCast>::New();
    pImageCast1->SetInputData(pImageLuminance->GetOutput());
    pImageCast1->SetOutputScalarTypeToFloat();
    pImageCast1->Update();

    // 均值濾波
    {
        pSrcMeanImageActor = vtkSmartPointer<vtkImageActor>::New();
        pSrcMeanImageActor->SetInputData(pImageLuminance->GetOutput());
        pSrcMeanRenderer->AddActor(pSrcMeanImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pSrcMeanRenderer);

        vtkSmartPointer<vtkImageConvolve> pImageConv = vtkSmartPointer<vtkImageConvolve>::New();
        pImageConv->SetInputData(pImageCast1->GetOutput());

        double kernel[25] ={0.04,0.04,0.04,0.04,0.04,
                            0.04,0.04,0.04,0.04,0.04,
                            0.04,0.04,0.04,0.04,0.04,
                            0.04,0.04,0.04,0.04,0.04,
                            0.04,0.04,0.04,0.04,0.04};

        pImageConv->SetKernel5x5(kernel);
        pImageConv->Update();

        vtkSmartPointer<vtkImageCast> pImageCast2 = vtkSmartPointer<vtkImageCast>::New();
        pImageCast2->SetInputData(pImageConv->GetOutput());
        pImageCast2->SetOutputScalarTypeToUnsignedChar();
        pImageCast2->Update();

        pMeanImageActor = vtkSmartPointer<vtkImageActor>::New();
        pMeanImageActor->SetInputData(pImageCast2->GetOutput());
        pMeanRenderer->AddActor(pMeanImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pMeanRenderer);
    }

    // 高斯濾波
    {
        pSrcGaussianImageActor = vtkSmartPointer<vtkImageActor>::New();
        pSrcGaussianImageActor->SetInputData(pImageLuminance->GetOutput());
        pSrcGaussianRenderer->AddActor(pSrcGaussianImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pSrcGaussianRenderer);

        vtkSmartPointer<vtkImageGaussianSmooth> pImageGaussianSmooth = vtkSmartPointer<vtkImageGaussianSmooth>::New();
        pImageGaussianSmooth->SetInputData(pImageCast1->GetOutput());
        pImageGaussianSmooth->SetDimensionality(2);
        pImageGaussianSmooth->SetRadiusFactor(5);
        pImageGaussianSmooth->SetStandardDeviation(3);
        pImageGaussianSmooth->Update();

        vtkSmartPointer<vtkImageCast> pImageCast2 = vtkSmartPointer<vtkImageCast>::New();
        pImageCast2->SetInputData(pImageGaussianSmooth->GetOutput());
        pImageCast2->SetOutputScalarTypeToUnsignedChar();
        pImageCast2->Update();

        pGaussianImageActor = vtkSmartPointer<vtkImageActor>::New();
        pGaussianImageActor->SetInputData(pImageCast2->GetOutput());
        pGaussianRenderer->AddActor(pGaussianImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pGaussianRenderer);
    }

    // 中值濾波
    {
        pSrcMeadianImageActor = vtkSmartPointer<vtkImageActor>::New();
        pSrcMeadianImageActor->SetInputData(pImageLuminance->GetOutput());
        pSrcMeadianRenderer->AddActor(pSrcMeadianImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pSrcMeadianRenderer);

        vtkSmartPointer<vtkImageHybridMedian2D> pImageMeadian = vtkSmartPointer<vtkImageHybridMedian2D>::New();
        pImageMeadian->SetInputData(pImageCast1->GetOutput());
        pImageMeadian->Update();

        vtkSmartPointer<vtkImageCast> pImageCast2 = vtkSmartPointer<vtkImageCast>::New();
        pImageCast2->SetInputData(pImageMeadian->GetOutput());
        pImageCast2->SetOutputScalarTypeToUnsignedChar();
        pImageCast2->Update();

        pMeadianmageActor = vtkSmartPointer<vtkImageActor>::New();
        pMeadianmageActor->SetInputData(pImageCast2->GetOutput());
        pMeadianRenderer->AddActor(pMeadianmageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pMeadianRenderer);
    }

    // 各向異性
    {
        pSrcAnisotropicImageActor = vtkSmartPointer<vtkImageActor>::New();
        pSrcAnisotropicImageActor->SetInputData(pImageLuminance->GetOutput());
        pSrcAnisotropicRenderer->AddActor(pSrcAnisotropicImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pSrcAnisotropicRenderer);

        vtkSmartPointer<vtkImageAnisotropicDiffusion2D> pImageAnisotropic = vtkSmartPointer<vtkImageAnisotropicDiffusion2D>::New();
        pImageAnisotropic->SetInputData(pImageCast1->GetOutput());
        pImageAnisotropic->SetNumberOfIterations(10);
        pImageAnisotropic->SetDiffusionThreshold(20);
        pImageAnisotropic->Update();

        vtkSmartPointer<vtkImageCast> pImageCast2 = vtkSmartPointer<vtkImageCast>::New();
        pImageCast2->SetInputData(pImageAnisotropic->GetOutput());
        pImageCast2->SetOutputScalarTypeToUnsignedChar();
        pImageCast2->Update();

        pAnisotropicImageActor = vtkSmartPointer<vtkImageActor>::New();
        pAnisotropicImageActor->SetInputData(pImageCast2->GetOutput());
        pAnisotropicRenderer->AddActor(pAnisotropicImageActor);
        ui->qvtkWidget->GetRenderWindow()->AddRenderer(pAnisotropicRenderer);
    }

    pImageStyle       = vtkSmartPointer<vtkInteractorStyleImage>::New();
    ui->qvtkWidget->GetInteractor()->SetInteractorStyle(pImageStyle);

    ui->qvtkWidget->GetRenderWindow()->Render();
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QHBoxLayout" name="horizontalLayout" stretch="2,5">
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QPushButton" name="pushButton">
        <property name="text">
         <string>選擇圖像</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QTextBrowser" name="textBrowser"/>
      </item>
     </layout>
    </item>
    <item>
     <widget class="QVTKWidget" name="qvtkWidget"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <customwidgets>
  <customwidget>
   <class>QVTKWidget</class>
   <extends>QWidget</extends>
   <header>QVTKWidget.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章