1. 程式人生 > >科學計算三維可視化---Mayavi可視化實例

科學計算三維可視化---Mayavi可視化實例

管線 可視化 2.3 extra 過多 like num 路徑 優化

技術分享圖片

一:Dragon繪制實例(三維掃描的繪制)

 三維掃描主要用於對物體空間外形結構以及色彩進行掃描,用以獲得物體表面的空間坐標,

他的主要意義在於能夠將實物的立體信息轉換為計算機能夠直接處理的數據信號,為實物的數字化提供了相對方便快捷的手段,

因此,三維掃描為工業建模,文物保存,虛擬空間構建都起到了非常重要的作用。

下載地址:http://graphics.stanford.edu/data/3Dscanrep/,頁面搜索Dragon即可

提取文件

import tarfile,os
#讀取tar壓縮文件
dragon_tar_file = tarfile.open("dragon_recon.tar.gz
") try: os.mkdir("dragon_data") except: pass dragon_tar_file.extractall("dragon_data") dragon_tar_file.close()

文件路徑拼接

import os

dragon_ply_file = os.path.join("dragon_data","dragon_recon","dragon_vrip.ply")
.ply是一個很通用的三維掃描格式Polygon File Format--->也叫作Stanford Triangle Format  用來存儲三維掃描結果的三維數值通過多邊形面片集合來描述三維物體    分辨率極高

對.ply文件進行三維可視化

技術分享圖片

import os,shutil,tarfile
from mayavi import mlab

#讀取tar壓縮文件
dragon_tar_file = tarfile.open("dragon_recon.tar.gz")
try:
    os.mkdir("dragon_data")
except:
    pass

dragon_tar_file.extractall("dragon_data")
dragon_tar_file.close()

dragon_ply_file = os.path.join("dragon_data","dragon_recon
","dragon_vrip.ply") mlab.pipeline.surface(mlab.pipeline.open(dragon_ply_file)) mlab.show() shutil.rmtree("dragon_data")

技術分享圖片

二:Canyon地形可視化實例

hgt(height File Format)他是存儲在航天,飛機,雷達,地形,測繪任務格式的數據文件,數據中包含空隙,數據丟失部分

下載地址:https://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/(需要FQ)

import zipfile
import numpy as np
from mayavi import mlab


hgt = zipfile.ZipFile("N36W113.hgt.zip").read("N36W113.hgt")

#處理地形數據
data = np.fromstring(hgt,">i2") #構建整數型數據,相當於2*8的16位數組
data.shape = (3601,3601)    #確定數組的行數和列數
data = data.astype(np.float32)  #使用32位浮點型
data = data[:1000,900:1900] #為了提高效率,我們只選取部分數據x:0-1000 y:900-1900
data[data == -32768] = data[data > 0].min() #數據中有-32768表示為空隙數據,將該數據設置為數據中的最小值

#渲染地形hgt的數據data
mlab.figure(size=(400,320),bgcolor=(0.16,0.28,0.46))    #獲取窗口,窗口大小為400,320
mlab.surf(data,colormap="gist_earth",warp_scale=0.2,
          vmin=1200,vmax=1610)

#清空內存
del data
#創建交互式可視化窗口
mlab.view(-5.9,83,570,[5.3,20,238]) #設置相機的視角(可選)(方位角,高度,距離和焦點等)
mlab.show()

技術分享圖片

三:地球儀實例繪制

echarts世界地圖各個國家及中國城市的經緯度數組

(一)數據源

#城市經緯度數據
cities_data = """
阿富汗,67.709953,33.93911
孟加拉國,90.356331,23.684994
津巴布韋,29.154857,-19.015438
泉州,118.58,24.93
廈門,118.1,24.46
牡丹江,129.58,44.6
綿陽,104.73,31.48
鄭州,113.65,34.76
沈陽,123.38,41.8
愛爾蘭,-8.24389,53.41291
烏拉圭,-55.765835,-32.522779
"""

(二)處理數據 ,建立索引字典和坐標列表

csv:數據分析與展示---Numpy數據存取與函數

#建立城市-城索引的字典,城市經緯度的列表
import csv
cities = dict()
coords = list()
for line in list(csv.reader(cities_data.split("\n")))[1:-1]:    #1:-1排除第一行只有一個\n
    name,long_,lat = line
    cities[name] = len(coords)  #建立索引,len會隨著coords增加而增加,這就是索引,我們根據這個去查找列表,更快
    coords.append((float(long_),float(lat)))

(三)進行坐標轉換(在三維空間中實際是按照x,y,z三個軸來表示的,而地球數據是按照經緯度表示,需要將經緯度二維轉三維坐標)

技術分享圖片

#坐標轉換
coords = np.array(coords)
lat, long = coords.T*np.pi/180  #進行轉置
x = np.cos(long)*np.cos(lat)
y = np.cos(long)*np.sin(lat)
z = np.sin(long)

(四)地球繪制部分

技術分享圖片

(1)建立窗口

#繪制窗口
mlab.figure(size=(400,400),bgcolor=(0.48,0.48,0.48))

........

mlab.view(100,60,4,[-0.05,0,0]) #設置相機的視角(可選)(方位角,高度,距離和焦點等)
mlab.show()

(2)繪制地球

#繪制球體mesh也可以,不過效果不好
sphere = mlab.points3d( #繪制半透明球體,表示地球外表面
    0,0,0,
    scale_factor=2,
    color=(0.67,0.77,0.93),
    resolution = 50,
    opacity = 0.7,
    name = "Earth"
)

技術分享圖片

優化(放在後面,在show前面,對整體績效鏡面處理)

#上面效果不是太好,添加鏡面反射等參數
#調整鏡面反射參數
sphere.actor.property.specular = 0.45
sphere.actor.property.specular_power = 5
#設置背面剔除,以更好的顯示透明效果
sphere.actor.property.backface_culling = True

技術分享圖片

(3)在地球相應位置繪制城市名稱(一個點)

#繪制城市名稱
points = mlab.points3d(x,y,z,   #已設置過的三維坐標
                       scale_mode="none",   #放縮模式,標量,矢量,無
                       scale_factor=0.03,   #放縮比例
                       color=(0,0,1))

技術分享圖片

(4)在相應位置繪制城市名稱(mlab.text(x,y,z,text,...)),中文有問題,註意數據選取均勻

#繪制城市名字
for city,index in cities.items():
    label = mlab.text(x[index],y[index],city,z=z[index],    #x,y,city是城市名稱,z坐標,width是文本寬度,name表示文本對象
                      width=0.016*len(city),name=city)
    label.property.shadow = True

技術分享圖片

(5)繪制大洲的邊界

大洲的邊界是一個不規則圖形,很難提供直接的數據,不過vtk給我們提供了多邊形數據源,叫做BuiltinSurface,其中就含有地球大洲邊界現象

技術分享圖片

#繪制地球上大洲的邊界
from mayavi.sources.builtin_surface import BuiltinSurface
#使用mlab的管線繪制表面函數對邊界進行繪制
continents_src = BuiltinSurface(source="earth",name="Continents")
continents = mlab.pipeline.surface(continents_src,color=(0,0,0))

優化:LOD實現近細遠粗

#繪制地球上大洲的邊界
from mayavi.sources.builtin_surface import BuiltinSurface
#使用mlab的管線繪制表面函數對邊界進行繪制
continents_src = BuiltinSurface(source="earth",name="Continents")
#設置模型LOD的層級,實現近細遠粗
continents_src.data_source.on_ratio = 2 #2級lod
continents = mlab.pipeline.surface(continents_src,color=(0,0,0))

技術分享圖片

(6)繪制赤道線

#赤道線numpy數組的構造過程
theta = np.linspace(0,2*np.pi,100)  #由很多小直線組成
x = np.cos(theta)
y = np.sin(theta)
z = np.zeros_like(theta)
#繪制赤道線
mlab.plot3d(x,y,z,color=(1,1,1),
            opacity=0.2,tube_radius=None)

技術分享圖片

(五)全部代碼

import numpy as np
from mayavi import mlab

#城市經緯度數據
cities_data = """
Hong Kong,114.109497,114.109497
Miami,-80.19179,-80.19179
Manila,120.984219,120.984219
Caracas,-66.903606,-66.903606
Nicosia,33.382276,33.382276
Luxembourg,6.129583,6.129583
Mexico City,-99.133208,-99.133208
Doha,51.53104,51.53104
Prague,14.4378,14.4378
Delhi,77.209021,77.209021
Taipei,121.565418,121.565418
Tel Aviv,34.781768,34.781768
S?o Paulo,-46.633309,-46.633309
Oslo,10.752245,10.752245
Milan,9.185924,9.185924
Toronto,-79.383184,-79.383184
Helsinki,24.938379,24.938379
Chicago,-87.629798,-87.629798
Tokyo,139.691706,139.691706
Paris,2.352222,2.352222
Kuala Lumpur,101.686855,101.686855
Manama,50.58605,50.58605
Lyon,4.835659,4.835659
Madrid,-3.70379,-3.70379
Tallinn,24.753575,24.753575
Bucharest,26.102538,26.102538
Montreal,-73.567256,-73.567256
Riga,24.105186,24.105186
Istanbul,28.978359,28.978359
New York,-74.005941,-74.005941
Vilnius,25.279651,25.279651
Moscow,37.6173,37.6173
"""


#1.建立城市-城索引的字典,城市經緯度的列表
import csv
cities = dict()
coords = list()
for line in list(csv.reader(cities_data.split("\n")))[1:-1]:    #1:-1排除第一行只有一個\n
    name,long_,lat = line
    cities[name] = len(coords)  #建立索引,len會隨著coords增加而增加,這就是索引,我們根據這個去查找列表,更快
    coords.append((float(long_),float(lat)))

#2.坐標轉換
coords = np.array(coords)
lat, long = coords.T*np.pi/180  #進行轉置
x = np.cos(long)*np.cos(lat)
y = np.cos(long)*np.sin(lat)
z = np.sin(long)

#3.繪制窗口
mlab.figure(size=(400,400),bgcolor=(0.48,0.48,0.48))

#4.繪制球體mesh也可以,不過效果不好
sphere = mlab.points3d( #繪制半透明球體,表示地球外表面
    0,0,0,
    scale_factor=2,
    color=(0.67,0.77,0.93),
    resolution = 50,
    opacity = 0.7,
    name = "Earth"
)

#5.繪制城市名稱
points = mlab.points3d(x,y,z,   #已設置過的三維坐標
                       scale_mode="none",   #放縮模式,標量,矢量,無
                       scale_factor=0.03,   #放縮比例
                       color=(0,0,1))

#6.繪制城市名字
for city,index in cities.items():
    label = mlab.text(x[index],y[index],city,z=z[index],    #x,y,city是城市名稱,z坐標,width是文本寬度,name表示文本對象
                      width=0.016*len(city),name=city)
    label.property.shadow = True


#7.繪制地球上大洲的邊界
from mayavi.sources.builtin_surface import BuiltinSurface
#使用mlab的管線繪制表面函數對邊界進行繪制
continents_src = BuiltinSurface(source="earth",name="Continents")
#8.設置模型LOD的層級,實現近細遠粗
continents_src.data_source.on_ratio = 2 #2級lod
continents = mlab.pipeline.surface(continents_src,color=(0,0,0))

#9.赤道線numpy數組的構造過程
theta = np.linspace(0,2*np.pi,100)
x = np.cos(theta)
y = np.sin(theta)
z = np.zeros_like(theta)
#10.繪制赤道線
mlab.plot3d(x,y,z,color=(1,1,1),
            opacity=0.2,tube_radius=None)

#11.上面效果不是太好,添加鏡面反射等參數
#調整鏡面反射參數
sphere.actor.property.specular = 0.45
sphere.actor.property.specular_power = 5
#設置避免剔除,以更好的顯示透明效果
sphere.actor.property.backface_culling = True


mlab.view(100,60,4,[-0.05,0,0]) #設置相機的視角(可選)(方位角,高度,距離和焦點等)
mlab.show()

科學計算三維可視化---Mayavi可視化實例