• 科学计算三维可视化---Mayavi可视化实例


    一: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/(需要翻墙)

    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("
    ")))[1:-1]:    #1:-1排除第一行只有一个
    
        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("
    ")))[1:-1]:    #1:-1排除第一行只有一个
    
        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()
  • 相关阅读:
    C++模板类报错:函数未定义
    linux top命令和sar命令
    XAMPP的服务在CentOS中无法启动
    XAMPP安装LAMP后无法使用数据库
    关于try catch语句中finally代码块有没有必要的思考
    eclipse卡死的两种解决办法
    VS2019 配置 OpenCV-4.4.0
    VS2019+OpenCV4配置报错:模块计算机类型x64与目标计算机类型x86冲突
    slide js用法 公告 广告 新闻滚动
    input type:text输入框点击输入,文字消失
  • 原文地址:https://www.cnblogs.com/ssyfj/p/9307817.html
Copyright © 2020-2023  润新知