【三维几何学习】使用VTK对网格输入特征进行可视化

news2025/8/6 13:13:43

使用VTK对网格输入特征进行可视化

  • 引言
  • 一、全部代码
  • 二、可视化

引言

在这里插入图片描述在这里插入图片描述
使用python调用VTK库对网格的输入特征进行可视化,方便后续实验与分析

  • 上图可视化的输入特征是热核特征HKS的第一个通道,也可对其他输入进行可视化
  • 数据集可参考1:三角网格(Triangular Mesh)分类数据集

一、全部代码

compute_hks_autoscale函数参考自2:DiffusionNet
VTK可视化代码参考3:VTK使用颜色映射标量数据

import numpy as np
import potpourri3d as pp3d
import scipy
import scipy.sparse.linalg
import vtkmodules.all as vtk
import torch
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"


class TriMesh:
    def __init__(self, file):
        # 属性
        self.file = file  # 文件完整路径
        self.filename = None  # 文件名称
        self.vs = []  # 坐标索引
        self.faces = []  # 顶点索引
        self.features = None  # 特征
        self.vs, self.faces = pp3d.read_mesh(file)
        self.faces_num = len(self.faces)

    def compute_hks_autoscale(self, eig_k, count=16):
        eps = 1e-8
        L = pp3d.cotan_laplacian(self.vs, self.faces, denom_eps=1e-10)
        massvec_np = pp3d.vertex_areas(self.vs, self.faces)
        massvec_np += eps * np.mean(massvec_np)
        L_eigsh = (L + scipy.sparse.identity(L.shape[0]) * eps).tocsc()
        massvec_eigsh = massvec_np
        Mmat = scipy.sparse.diags(massvec_eigsh)
        eigs_sigma = eps
        failcount = 0
        while True:
            try:
                # We would be happy here to lower tol or maxiter since we don't need these to be super precise, but for some reason those parameters seem to have no effect
                evals_np, evecs_np = scipy.sparse.linalg.eigsh(L_eigsh, k=eig_k, M=Mmat, sigma=eigs_sigma)

                # Clip off any eigenvalues that end up slightly negative due to numerical weirdness
                evals_np = np.clip(evals_np, a_min=0., a_max=float('inf'))

                break
            except Exception as e:
                print(e)
                if failcount > 3:
                    raise ValueError("failed to compute eigendecomp")
                failcount += 1
                print("--- decomp failed; adding eps ===> count: " + str(failcount))
                L_eigsh = L_eigsh + scipy.sparse.identity(L.shape[0]) * (eps * 10 ** failcount)
        evals = torch.from_numpy(evals_np)
        evecs = torch.from_numpy(evecs_np)
        # these scales roughly approximate those suggested in the hks paper
        scales = torch.logspace(-2, 0., steps=count, device=evals.device, dtype=evals.dtype)
        return self.compute_hks(evals, evecs, scales)

    def compute_hks(self, evals, evecs, scales):
        # expand batch
        if len(evals.shape) == 1:
            expand_batch = True
            evals = evals.unsqueeze(0)
            evecs = evecs.unsqueeze(0)
            scales = scales.unsqueeze(0)
        else:
            expand_batch = False

        # TODO could be a matmul
        power_coefs = torch.exp(-evals.unsqueeze(1) * scales.unsqueeze(-1)).unsqueeze(1)  # (B,1,S,K)
        terms = power_coefs * (evecs * evecs).unsqueeze(2)  # (B,V,S,K)

        out = torch.sum(terms, dim=-1)  # (B,V,S)

        if expand_batch:
            return out.squeeze(0)
        else:
            return out


def show_point_color(mesh: TriMesh, seg=[], Subdivision=False):

    # 1. 添加数据
    points = vtk.vtkPoints()
    pColor = vtk.vtkFloatArray()

    for v in mesh.vs:
        points.InsertNextPoint(v)
        pColor.InsertNextValue(v[0])
    if len(seg) > 0:
        pColor = vtk.vtkFloatArray()
        for s in seg:
            pColor.InsertNextValue(s)

    polys = vtk.vtkCellArray()
    for f in mesh.faces:
        polys.InsertNextCell(len(f), f)

    # 2. 创建PolyData
    cube = vtk.vtkPolyData()
    cube.SetPoints(points)
    cube.SetPolys(polys)
    cube.GetPointData().SetScalars(pColor)

    # 2.5细分
    if Subdivision:
        l = vtk.vtkLinearSubdivisionFilter()  # 先linear
        l.SetInputData(cube)
        l.SetNumberOfSubdivisions(1)
        l.Update()

        loop = vtk.vtkLoopSubdivisionFilter()  # 后loop
        loop.SetInputConnection(l.GetOutputPort())
        loop.SetNumberOfSubdivisions(5)
        loop.Update()

    # lut = vtk.vtkLookupTable()
    # lut.SetHueRange(0.125, 0.666)  # 映射的颜色变换参数(自己调颜色)

    mapper = vtk.vtkPolyDataMapper()
    mapper.ScalarVisibilityOn()
    mapper.SetColorModeToMapScalars()
    # mapper.SetLookupTable(lut)
    mapper.SetScalarRange(0, 1)

    if Subdivision:
        mapper.SetInputConnection(loop.GetOutputPort())
    else:
        mapper.SetInputData(cube)

    # 3.创建Actor
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    # actor.GetProperty().SetEdgeColor(0, 0, 0)
    # actor.GetProperty().SetEdgeVisibility(1)    # 显示边

    # 3.5 加入colormap
    scalarBar = vtk.vtkScalarBarActor()  # 设置color_bar
    scalarBar.SetLookupTable(mapper.GetLookupTable())
    scalarBar.SetTitle("")
    scalarBar.SetNumberOfLabels(10)  # 设置要显示的刻度标签数。自己设定色带的位置
    scalarBar.SetMaximumNumberOfColors(10)# # 设置标题和条形之间的边距
    # scalarBar.SetVerticalTitleSeparation(10)
    # # 设置标题颜色
    scalarBar.DrawTickLabelsOn()
    scalarBar.GetTitleTextProperty().SetColor(0, 0, 0)
    scalarBar.GetLabelTextProperty().SetColor(0, 0, 0)

    # 4.创建Renderer
    renderer = vtk.vtkRenderer()
    renderer.SetBackground(1, 1, 1)  # 背景白色
    renderer.AddActor(actor)  # 将actor加入
    renderer.ResetCamera()  # 调整显示
    renderer.AddActor2D(scalarBar)


    # 5.渲染窗口
    renWin = vtk.vtkRenderWindow()
    renWin.AddRenderer(renderer)
    renWin.Render()

    # 6.交互
    renWinInteractor = vtk.vtkRenderWindowInteractor()
    renWinInteractor.SetRenderWindow(renWin)
    renWinInteractor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
    renWinInteractor.Start()


if __name__ == '__main__':

    # 读取网格
    mesh = TriMesh('../../../datasets/shrec_10/alien/train/T5.obj')  # 1 13 15

    # 计算特征
    face_hks = mesh.compute_hks_autoscale(eig_k=4).numpy()

    # 某一通道的归一化
    face_hks = face_hks[:, 0] / np.max(face_hks[:, 0])

    # 可视化
    show_point_color(mesh, face_hks, False)

二、可视化

  1. eig_k=1,4, 16, 64的可视化 (cat/train/T98.obj)
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • eig_k=1毫无意义,就可视化而言eig_k=4效果是最好的
  1. 固定eig_k=4,取特征通道=0,4,8,12,14,15
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 特征通道取前几个即可,最后的几个维度对于形状特征区分度较低
  1. eig_k=4,32, 64, 128的可视化 (cubes/tree/train/tree_20.obj)
    在这里插入图片描述在这里插入图片描述在这里插入图片描述6
  • 对于Cubes这种内嵌式的模型,少量的eig_k并不能很好的体现内嵌模型的特征

  1. 三角网格(Triangular Mesh)分类数据集 ↩︎

  2. DiffusionNet ↩︎

  3. VTK使用颜色映射标量数据 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网上鲜花交易平台,可运行

文章目录项目介绍一、项目功能介绍1、用户模块主要功能包括:2、商家模块主要功能包括:3、管理员模块主要功能包括:二、部分页面展示1、用户模块部分功能页面展示2、商家模块部分功能页面展示3、管理员模块部分功能页面展示三、部分源码四、底…

LCMXO3L-640E-5MG121I【FPGA】LCMXO3L-640E-6MG121I采用65nm非易失性低功耗工艺设计

LCMXO3L-640E-5MG121I【FPGA】LCMXO3L-640E-6MG121I采用65nm非易失性低功耗工艺设计MachXO3设备系列是一个超低密度系列,支持最先进的可编程桥接和IO扩展。它具有突破性的IO密度和最低的每IO成本。设备IO功能集成了对最新行业标准IO的支持。121CSFBGA(明…

plg(Loki+Promtail+Grafana)监控nginx日志、messages日志监控平台

登录官网:loki官网Like Prometheus, but for logs. Contribute to grafana/loki development by creating an account on GitHub.https://github.com/grafana/loki/releases/ loki安装 ----root用户操作 ###创建用户 useradd loki passwd loki###创建安装目录 mkd…

蒙牛联合泛微采知连,实现研发知识管理数智化

蒙牛1999年成立于内蒙古自治区,总部位于呼和浩特,是全球乳业七强。蒙牛常温事业部坚持产品的创新研发和数智化转型,每年持续、稳定的新品推出,让业务快速增长、规模持续扩大。 (图片素材来自蒙牛官网) 构建…

基于单片机的波形发生器设计

单片机可以用来设计各种类型的波形发生器,下面是一种基于单片机的波形发生器设计方案。所需材料:单片机:可以选择常见的Atmel AVR单片机,如ATmega328P等。调制器:可以使用AD9833或AD9851等常用的调制器。时钟&#xff…

部署安装Nginx服务实例

其他服务: 搭建zabbix4.0监控服务实例 普罗米修斯监控mysql数据库实战 Linux安装MySQL数据库步骤 一. Nginx概念介绍 1.介绍Nginx程序 Nginx (engine x) 是一款开源且高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。主要特点是占用…

ElasticSearch - 分布式文档索引、搜索、更新和删除文档的过程

文章目录1. 分布式文档存储1. 路由一个文档到一个分片中2. 主分片和副本分片如何交互3. 新建、索引和删除文档4. 取回一个文档5. 局部更新文档2. ElasticSearch相关问题1. 路由计算方式?2. 分片控制3. 分布式文档写入(索引)的过程?4. 分布式文档搜索的过…

自动化实战以及自动化性能测试

web自动化测试实战编写web自动化测试用例;创建自动化项目,根据用例来实现脚本无头模式使用selenium4自动化测试工具和junit5单元测试框架结合,如何实现的,以及有什么两点使用了junit5中提供的注解;避免生成过多的对象&…

轻量简单的团队协作工具有哪些?远程办公必备软件排行榜

前段时间的疫情不断反复,让不少企业和团队都开启了居家办公,无论是线上协作还是团队会议,都要使用大量的办公远程软件,因为突如其来的场景大转变,所以无形中也给大家增加了不少烦恼。 经历过了就有经验了,…

Docker安装Jenkins练习纪录一

Docker安装Jenkins练习记录参考博客准备资源centos7下载vmware下载jdk8下载Maven 下载FinalShell下载开始练习一些小问题参考博客 https://blog.csdn.net/lzc2644481789/article/details/124888223 https://blog.csdn.net/qq_52423918/article/details/125169577 准备资源 cen…

2023年天津体育学院专升本专业课考试考生考前防疫及入场须知

天津体育学院2023年高职升本科专业考试考生考前须知 一、防疫要求 1.考生要强化自我健康“第一责任人”的意识和责任,自觉履行考前每日健康监测义务。须于考前7天(3月8日前)下载《天津体育学院2023年高职升本科专业考试考生健康安全承诺书》&…

【微信小程序开发全流程】篇章0:基于JavaScript开发的校园综合类微信小程序的概览

基于JavaScript开发的校园综合类微信小程序的概览 本文仅供学习,未经同意请勿转载 一些说明:上述项目来源于笔者我本科大三阶段2019年电子设计课程项目,在这个项目中,我主要是负责的部分有前端,前后端的对接&#xf…

深入理解机器学习——偏差(Bias)与方差(Variance)

分类目录:《深入理解机器学习》总目录 偏差(Bias)与方差(Variance)是解释学习算法泛化性能的一种重要工具。偏差方差分解试图对学习算法的期望泛化错误率进行拆解,我们知道,算法在不同训练集上学…

兴达易控Modbus转Profinet网关连接1200Profinet转modbus接三菱A800变频器案例

下面介绍A800 变频器通过兴达易控modbus转profinet网关,使1200plc无需编程实现Profinet转modbus协议转换,把modbus变频器轻松组网 网络拓扑如下图 打开博图组态加载GSD文件,modbus转profinet网关从站接口接入到1200PLC上 配置modbus转profine…

【MyBatis】篇二.MyBatis查询与特殊SQL

文章目录1、MyBatis获取参数值case1-单个字面量类型的参数case2-多个字面量类型的参数case3-map集合类型的参数case4-实体类类型的参数case5-使用Param注解命名参数总结2、MyBatis的各种查询功能case1-查询结果是一个实体类对象case2-查询结果是一个List集合case3-查询单个数据…

杂记——16.idea中导入maven项目

这篇文章我们来讲一下如何从Gitee上拉取项目,并将该项目导入到idea中 目录 1.拉取项目 2.idea导入项目 3.更改相关的配置 3.1更改maven仓库 3.2更改数据库的连接池 1.拉取项目 第一步:找到相关的项目地址 如图所示,在Gitee上找到相关的…

FPGA时序约束(二)利用Quartus18对Altera进行时序约束

系列文章目录 FPGA时序约束(一)基本概念入门及简单语法 文章目录系列文章目录前言Quartus时序约束不进行时序约束的后果时序约束方法TimeQuest Timing Analyzer 工具来对工程添加约束。创建网表读取SDC文件创建时钟(Create Clock&#xff09…

八股总结(三)操作系统内存管理、进程线程、进程同步与通信、中断与异常、常用命令

layout: post title: 八股总结(三)操作系统内存管理、进程线程、进程同步与通信、中断与异常、常用命令 description: 八股总结(三)操作系统内存管理、进程线程、进程同步与通信、中断与异常、常用命令 tag: 八股总结 文章目录操作…

基础SQL语法及使用案例

通用SQL语法 SQL语句可以单行或多行书写,以分号结尾。SQL语句可以使用空格/缩进来增强语句的可读性。MySOL数据库的SQL语句不区分大小写,关键字建议使用大写。注释: 单行注释:--注释内容 或 #注释内容(MySQL特有) 多行注释&#…

英伟达驱动爆雷?CPU占用率过高怎么办?

又有一新驱动导致CPU占用率过高? 上周英伟达发布531.18显卡驱动,为大家带来了视频超分辨率技术,并为新发布的热门游戏《原子之心》提供支持。 但在安装新驱动后没过不久就有玩家反映,在游戏结束后会出现CPU占用率突然飙升到10%以…