PyQt5+VTK環境搭建
VTK 簡介及安裝
VTK 介紹
VTK(visualization toolkit)是一個開源的免費軟件系統,主要用於三維計算機圖形學、圖像處理和可視化。Vtk 是在面向對象原理的基礎上設計和實現的,它的內核是用 C++ 構建的,包含有大約 250,000 行代碼,2000 多個類,還包含有幾個轉換界面,因此也可以自由的通過 Java,Tcl/Tk 和 Python 各種語言使用 VTK。
VTK 是一個開放源碼、自由獲取的軟件系統,全世界的數以千計的研究人員和開發人員用它來進行 3D 計算機圖形,圖像處理,可視化。VTK 包含一個 c++類庫,衆多的翻譯接口層,包括 Tcl/Tk,Java,Python。 Visualization Toolkit 是一個用於可視化應用程序構造與運行的支撐環境,它是在三維函數庫 OpenGL 的基礎上採用面向對象的設計方法發展起來的,它將我們在可視化開發過程中會經常遇到的細節屏蔽起來,並將一些常用的算法封裝起來。比如 Visualization Toolkit 將我們在表面重建中比較常見的 MarchingCubes 算法封裝起來,以類的形式給我們以支持,這樣我們在對三維規則點陣數據進行表面重建時就不必再重複編寫 MarchingCubes 算法的代碼,而直接使用 Visualization Toolkit 中已經提供的 vtkMarchingCubes 類。Visualization Toolkit 是給從事可視化應用程序開發工作的研究人員提供直接的技術支持的一個強大的可視化開發工具。
VTK 在 Python 環境下安裝
方法一 安裝 anaconda,使用 conda install 安裝:
注意不同版本的 Python 對應不同的命令。
適用於 python3
install -n envA -c menpo vtk=7 python=3
或者具體到某個版本:
conda install -n envB -c menpo vtk=7 python=3.5
適用於 python 2
conda install -n envC vtk python=2
適用於 3.6:
conda install -c clinicalgraphics vtk=7.1.0
以上的命令都可以不加版本號
方法二:鏡像安裝
由於國內的鏡像裏沒有 vtk,所以直接用 conda 安裝會非常慢,推薦下載 whl 文件後使用 pip 安裝。
提供一個下載 VTK 的 whl 文件的網址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#vtk
我是 win10 系統 64 位下,使用的 python3.7,下載的是:VTK‑8.1.2‑cp37‑cp37m‑win32.whl
然後進入下載目錄,啓動 cmd, window power shell 或者 git bash,輸入命令: pip install VTK-7.1.1-cp36-cp36m-win_amd64.whl
完成安裝。
安裝完成後,在使用處導入vtk包即可。
檢測安裝成功
示例代碼:
import vtk
cone_a = vtk.vtkConeSource()
coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInputConnection(cone_a.GetOutputPort())
coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
ren1 = vtk.vtkRenderer()
ren1.AddActor(coneActor)
ren1.SetBackground(1.0, 1.0, 1.0)
ren1.SetBackground2(0.1, 0.2, 0.4)
ren1.SetGradientBackground(1)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren1)
renWin.SetSize(300, 300)
renWin.Render()
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
iren.Start()
運行結果如圖所示:
VTK簡單示例
繪製立方體
#!/usr/bin/env python
# This is (almost) a direct C++ to Python transliteration of
# <VTK-root>/Examples/DataManipulation/Cxx/Cube.cxx from the VTK
# source distribution, which "shows how to manually create vtkPolyData"
#
# A convenience function, mkVtkIdList(), has been added and one if/else
# so the example also works in version 6 or later.
#
# Lines like `obj->Delete()` have been transliterated as `del obj` to,
# preserve the resemblance to the original C++ example, although I
# doubt this achieves anything beyond what Python's garbage collection
# would do anyway.
import vtk
# Makes a vtkIdList from a Python iterable. I'm kinda surprised that
# this is necessary, since I assumed that this kind of thing would
# have been built into the wrapper and happen transparently, but it
# seems not.
def mkVtkIdList(it):
vil = vtk.vtkIdList()
for i in it:
vil.InsertNextId(int(i))
return vil
# 繪製通用方法
def myShow(cube):
# Now we'll look at it.
cubeMapper = vtk.vtkPolyDataMapper()
if vtk.VTK_MAJOR_VERSION <= 5:
cubeMapper.SetInput(cube)
else:
cubeMapper.SetInputData(cube)
cubeMapper.SetScalarRange(0, 7)
cubeActor = vtk.vtkActor()
cubeActor.SetMapper(cubeMapper)
# The usual rendering stuff.
camera = vtk.vtkCamera()
camera.SetPosition(1, 1, 1)
camera.SetFocalPoint(0, 0, 0)
renderer = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(renderer)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
renderer.AddActor(cubeActor)
renderer.SetActiveCamera(camera)
renderer.ResetCamera()
renderer.SetBackground(0, 0, 0)
renderer.SetBackground(1.0, 1.0, 1.0)
renderer.SetBackground2(0.1, 0.2, 0.4)
renderer.SetGradientBackground(1)
renWin.SetSize(300, 300)
# interact with data
renWin.Render()
iren.Start()
del cubeMapper
del cubeActor
del camera
del renderer
del renWin
del iren
def main():
# x = array of 8 3-tuples of float representing the vertices of a cube:
# 8個三維值代表長方體的8個頂點
x = [(0.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0),
(0.0, 0.0, 1.0), (1.0, 0.0, 1.0), (1.0, 1.0, 1.0), (0.0, 1.0, 1.0)]
# pts = array of 6 4-tuples of vtkIdType (int) representing the faces
# of the cube in terms of the above vertices
# 點的編號0-7,每個面由4個點組成
pts = [(0, 1, 2, 3), (4, 5, 6, 7), (0, 1, 5, 4),
(1, 2, 6, 5), (2, 3, 7, 6), (3, 0, 4, 7)]
# We'll create the building blocks of polydata including data attributes.
cube = vtk.vtkPolyData()
points = vtk.vtkPoints()
polys = vtk.vtkCellArray()
scalars = vtk.vtkFloatArray()
# Load the point, cell, and data attributes.
for i in range(8):
points.InsertPoint(i, x[i])
for i in range(6):
polys.InsertNextCell(mkVtkIdList(pts[i]))
for i in range(8):
scalars.InsertTuple1(i, i)
# We now assign the pieces to the vtkPolyData.
cube.SetPoints(points)
del points
cube.SetPolys(polys)
del polys
cube.GetPointData().SetScalars(scalars)
del scalars
myShow(cube)
# Clean up
del cube
main()
運行結果如圖所示:
PyQt5中引入VTK渲染窗口
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import vtk
from PyQt5 import QtCore, QtGui, QtWidgets
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class myMainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.frame = QtWidgets.QFrame()
self.vl = QtWidgets.QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
# Create source
source = vtk.vtkConeSource()
source.SetCenter(0, 0, 0)
source.SetRadius(0.1)
source1 = vtk.vtkSphereSource()
source1.SetCenter(0, 0, 0)
source1.SetRadius(0.3)
# Create a mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(source.GetOutputPort())
mapper1 = vtk.vtkPolyDataMapper()
mapper1.SetInputConnection(source1.GetOutputPort())
# Create an actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor1 = vtk.vtkActor()
actor1.SetMapper(mapper1)
self.ren.AddActor(actor)
self.ren.AddActor(actor1)
self.ren.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.iren.Initialize()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = myMainWindow()
sys.exit(app.exec_())
運行結果:
PyQt5中使用VTK讀取STL文件
# 部分代碼,在PyQt主程序中以addWidget形式嵌入到主窗口中
# 添加VTK顯示窗讀取STL文件===============================================
self.vtkWidget = QVTKRenderWindowInteractor(self.centralwidget) # 提供平臺獨立的響應鼠標、鍵盤和時鐘事件的交互機制
self.verticalLayout_3.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer() # 負責管理場景的渲染過程
self.ren.SetBackground(1.0, 1.0, 1.0) # 設置頁面底部顏色值
self.ren.SetBackground2(0.1, 0.2, 0.4) # 設置頁面頂部顏色值
self.ren.SetGradientBackground(1) # 開啓漸變色背景設置
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
# 交互器樣式的一種,該樣式下,用戶是通過控制相機對物體作旋轉、放大、縮小等操作
style = vtk.vtkInteractorStyleTrackballCamera()
self.iren.SetInteractorStyle(style)
# Read from STL file
stlreader = vtk.vtkSTLReader()
stlreader.SetFileName("test.stl")
# Read from OBJ file
# objReader = vtk.vtkOBJReader()
# objReader.SetFileName("test.obj")
# Create a mapper
mapper = vtk.vtkPolyDataMapper() # 渲染多邊形幾何數據
mapper.SetInputConnection(stlreader.GetOutputPort())
# VTK可視化管線的輸入數據接口 ,對應的可視化管線輸出數據的接口爲GetOutputPort();
# mapper.SetInputConnection(objReader.GetOutputPort())
# Create an actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# 設置生成幾何圖元的Mapper。即連接一個Actor到可視化管線的末端(可視化管線的末端就是Mapper)。
self.ren.AddActor(actor)
self.ren.ResetCamera()
self.centralwidget.setLayout(self.verticalLayout_3)
self.setCentralWidget(self.centralwidget)
self.vtkWidget.show()
self.iren.Initialize()
運行結果:
VTK支持的3D文件格式
VTK中可以導入/導出或讀/寫多種三維格式的文件,可以參考What 3D file formats can VTK import and export? The following table identifies the file formats that VTK can read and write. Importer and Exporter classes move full scene information into or out of VTK. Reader and Writer classes move just geometry.
File Format | Read | Write |
---|---|---|
3D Studio | vtk3DSImporter | |
AVS “UCD” format | vtkAVSucdReader | |
Movie BYU | vtkBYUReader | vtkBYUWriter |
Renderman | vtkRIBExporter | |
Open Inventor 2.0 | vtkIVExporter/vtkIVWriter | |
CAD STL | vtkSTLReader | vtkSTLWriter |
Fluent GAMBIT ASCII | vtkGAMBITReader | |
Unigraphics Facet Files | vtkUGFacetReader | |
Marching Cubes | vtkMCubesReader | vtkMCubesWriter |
Wavefront OBJ | vtkOBJExporter | |
VRML 2.0 | vtkVRMLExporter | |
VTK Structured Grid † | vtkStructuredGridReader | vtkStructuredWriter |
VTK Poly Data † | vtkPolyDataReader | vtkPolyDataWriter |
PLOT3D | vtkPLOT3DReader | |
CGM | vtkCGMWriter | |
OBJ | vtkOBJReader | |
Particle | vtkParticleReader | |
PDB | vtkPDBReader | |
PLY | vtkPLYReader | vtkPLYWriter |
Gaussian | vtkGaussianCubeReader | |
Facet | vtkFacetReader | vtkFacetWriter |
XYZ | vtkXYZMolReader | |
Ensight ‡ | vtkGenericEnSightReader |
本文作者: 旌旗
原文鏈接: https://seekzzh.site/pyqt5-vtk/
版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明出處!