【开发日志】2023.05 ZENO----PrimitiveCurvature----曲率分析工具(几何体、图像、点云)

news2024/11/29 6:32:09

 Screen Space Ambient Occlusion - TDA362/DIT223 - Computer Graphics Labs (chalmers.se)https://www.cse.chalmers.se/edu/course/TDA362/tutorials/ssao.html

GAMES102在线课程-刘利刚 (ustc.edu.cn)http://staff.ustc.edu.cn/~lgliu/Courses/GAMES102_2020/default.html

曲线光顺 离散曲线 三角网格_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1NA411E7Yr/?p=7&vd_source=499555eb1d0a2dc69e44994166c1ede7曲面去噪 采样与剖分_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1NA411E7Yr/?p=10&vd_source=499555eb1d0a2dc69e44994166c1ede7

【3D实践】3D曲率原理及计算(3D-Mesh) - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/112294045

刘利刚《计算机图形学》2020 (ustc.edu.cn)http://staff.ustc.edu.cn/~lgliu/Courses/ComputerGraphics_2020_spring-summer/default.htm

struct MaskByCurvature: INode {
    void apply() override {
        auto prim = get_input<zeno::PrimitiveObject>("prim");
        auto minCur = get_input2<float>("min_curvature");
        auto maxCur = get_input2<float>("max_curvature");
        auto type = get_input2<std::string>("type");
        auto &height = prim->verts.attr<float>("height");
        auto &mask = prim->verts.attr<float>("mask");
        auto &cur = prim->verts.add_attr<float>("curevature");
        auto &gcur = prim->verts.add_attr<float>("gaussianCurvature");
        if(type == "gaussianCurvature"){
#pragma omp parallel for
            for(int i = 0;i < prim->size();i++){
                if (gcur[i] > minCur && gcur[i] < maxCur) {
                    mask[i] = 1;
                }
                else{
                    mask[i] = 0;
                }
            }
        }
        if(type == "curvature"){
#pragma omp parallel for
            for(int i = 0;i < prim->size();i++){
                if (cur[i] > minCur && cur[i] < maxCur) {
                    mask[i] = 1;
                }
                else{
                    mask[i] = 0;
                }
            }
        }
        set_output("prim", prim);
    }
};
ZENDEFNODE(MaskByCurvature, {
    {
        {"PrimitiveObject", "prim"},
        {"enum gaussianCurvature curvature", "type", "gaussianCurvature"},
        {"float", "min_curvature", "1"},
        {"float", "max_curvature", "10000"},
    },
    {
        {"PrimitiveObject", "prim"},

    },
    {},
    {"erode"},
});


几何体、图像、点云

#include <zeno/zeno.h>
#include <zeno/types/PrimitiveObject.h>
#include <zeno/types/UserData.h>
#include <zeno/types/ListObject.h>
#include <vector>
#include <Eigen/Core>
#include <Eigen/Eigenvalues>
#include <zeno/utils/log.h>


namespace zeno {

namespace {

// 计算点云的曲率
static void computeCurvature(std::shared_ptr<PrimitiveObject> & prim) {
    auto &points = prim->attr<vec3f>("pos");
    if(!prim->verts.has_attr("curvature")){
        prim->verts.add_attr<float>("curvature");
    }
    auto &cur = prim->verts.attr<float>("curvature");
    // 遍历点云中的每个点
    for (size_t i = 0; i < prim->size(); ++i) {
        auto & p  = points[i];
        auto & p1 = points[i + 1];
        auto & p2 = points[i + 2];

        // 计算曲面法线
        Eigen::Vector3d v1(p1[0] - p[0], p1[1] - p[1], p1[2] - p[2]);
        Eigen::Vector3d v2(p2[0] - p[0], p2[1] - p[1], p2[2] - p[2]);
        Eigen::Vector3d normal = v1.cross(v2).normalized();

        // 构造协方差矩阵
        Eigen::Matrix3d covariance;
        covariance.setZero();
        covariance += v1 * v1.transpose();
        covariance += v2 * v2.transpose();

        // 计算特征值和特征向量
        Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> solver(covariance);
        Eigen::Vector3d eigenvalues = solver.eigenvalues();

        // 计算曲率
        cur[i] = eigenvalues.minCoeff() / eigenvalues.sum();
        zeno::log_info("cur[{}]:{}",i ,cur[i]);
    }
}

// 计算几何体顶点的曲率
static void computeVertexCurvature(std::shared_ptr<PrimitiveObject> & prim) {
    auto &pos = prim->verts;
    if(!prim->verts.has_attr("curvature")){
        prim->verts.add_attr<float>("curvature");
    }
    auto &cur = prim->verts.attr<float>("curvature");
//    auto &face = prim->tris;
    // 遍历每个顶点
    for (size_t i = 0; i < prim->verts.size(); ++i) {
//        const Vertex3D& vertex = vertices[i];
//        std::vector<size_t> neighborFaces;
        // 构建顶点的邻域面
        std::vector<size_t> neighborFaces;
        for (int m = 0;m < prim->tris.size();m++) {
            if (prim->tris[m][0] == i || prim->tris[m][1] == i || prim->tris[m][2] == i) {
                neighborFaces.push_back(m);
            }
        }
        // 构建邻域面法线矩阵
        Eigen::MatrixXd normals(3, neighborFaces.size());
        for (size_t j = 0; j < neighborFaces.size(); ++j) {
            auto & face = prim->tris[neighborFaces[j]];
            auto & vert = prim->verts;
            auto & v1 = face[0];
            auto & v2 = face[1];
            auto & v3 = face[2];

            Eigen::Vector3d v12(vert[v2][0] - vert[v1][0], vert[v2][1] - vert[v1][1], vert[v2][2] - vert[v1][2]);
            Eigen::Vector3d v13(vert[v3][0] - vert[v1][0], vert[v3][1] - vert[v1][1], vert[v3][2] - vert[v1][2]);
            Eigen::Vector3d normal = v12.cross(v13).normalized();

            normals(0, j) = normal.x();
            normals(1, j) = normal.y();
            normals(2, j) = normal.z();
        }

        // 计算邻域面法线的协方差矩阵
        Eigen::MatrixXd covariance = (normals * normals.transpose()) / neighborFaces.size();

        // 计算特征值和特征向量
        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(covariance);
        Eigen::VectorXd eigenvalues = solver.eigenvalues();

        // 计算曲率
        double curvature = eigenvalues.minCoeff() / eigenvalues.sum();
//        cur.push_back(curvature);
        cur[i] = curvature;
    }
}
// 计算图像的梯度
void computeGradient(std::shared_ptr<PrimitiveObject> & image, std::vector<std::vector<float>>& gradientX, std::vector<std::vector<float>>& gradientY) {
    auto &ud = image->userData();
    int height  = ud.get2<int>("h");
    int width = ud.get2<int>("w");

    gradientX.resize(height, std::vector<float>(width));
    gradientY.resize(height, std::vector<float>(width));

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            if (x > 0 && x < width - 1) {
                gradientX[y][x] = (image->verts[y * width + x + 1][0] - image->verts[y * width + x  - 1])[0] / 2.0f;
            } else {
                gradientX[y][x] = 0.0f;
            }
            if (y > 0 && y < height - 1) {
                gradientY[y][x] = (image->verts[(y+1) * width + x][0] - image->verts[(y - 1) * width + x])[0] / 2.0f;
            } else {
                gradientY[y][x] = 0.0f;
            }
        }
    }
}
// 计算图像的曲率
void computeCurvature(std::shared_ptr<PrimitiveObject> & image, const std::vector<std::vector<float>>& gradientX,
                      const std::vector<std::vector<float>>& gradientY) {
    int height = gradientX.size();
    int width = gradientX[0].size();
    if(!image->verts.has_attr("curvature")){
        image->verts.add_attr<float>("curvature");
    }
    auto &cur = image->verts.attr<float>("curvature");
//    curvature.resize(height, std::vector<float>(width));

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            float dx = gradientX[y][x];
            float dy = gradientY[y][x];
            float dxx = 0.0f;
            float dyy = 0.0f;
            float dxy = 0.0f;

            if (x > 0 && x < width - 1) {
                dxx = gradientX[y][x + 1] - 2.0f * dx + gradientX[y][x - 1];
            }

            if (y > 0 && y < height - 1) {
                dyy = gradientY[y + 1][x] - 2.0f * dy + gradientY[y - 1][x];
            }

            if (x > 0 && x < width - 1 && y > 0 && y < height - 1) {
                dxy = (gradientX[y + 1][x + 1] - gradientX[y + 1][x - 1] - gradientX[y - 1][x + 1] + gradientX[y - 1][x - 1]) / 4.0f;
            }
            cur[y * width + x] = (dxx * dyy - dxy * dxy) / ((dxx + dyy) * (dxx + dyy) + 1e-6f);
//            curvature[y][x] = (dxx * dyy - dxy * dxy) / ((dxx + dyy) * (dxx + dyy) + 1e-6f);
        }
    }
}
struct PrimCurvature: INode {
    void apply() override {
        auto prim = get_input<zeno::PrimitiveObject>("prim");
        auto type = get_input2<std::string>("type");
        if(type == "object"){
            computeVertexCurvature(prim);
        }
        else if(type == "pointcloud"){
            computeCurvature(prim);
        }
        else if(type == "image"){
            auto &ud = prim->userData();
            int w = ud.get2<int>("w");
            int h = ud.get2<int>("h");
            std::vector<std::vector<float>> gx(h, std::vector<float>(w, 0));
            std::vector<std::vector<float>> gy(h, std::vector<float>(w, 0));
            computeGradient(prim,gx, gy);
            computeCurvature(prim,gx,gy);
        }
        set_output("prim", prim);
    }
};
ZENDEFNODE(PrimCurvature, {
    {
        {"PrimitiveObject", "prim"},
        {"enum object image pointcloud", "type", "object"},
    },
    {
        {"PrimitiveObject", "prim"},
    },
    {},
    {"primitive"},
});

}
}
struct PrimCurvature: INode {
    void apply() override {
        auto prim = get_input<zeno::PrimitiveObject>("prim");
        auto type = get_input2<std::string>("type");

        int n = prim->verts.size();  // Number of vertices
        int dim = 3; // Dimensionality (3D)
        Eigen::MatrixXd V(n, dim);
        for (int i = 0; i < n; ++i) {
            V.row(i) << prim->verts[i][0], prim->verts[i][1], prim->verts[i][2];
        }

        int m = prim->tris.size(); // Number of faces
        int vertices_per_face = 3; // Number of vertices per face
        Eigen::MatrixXi F(m, vertices_per_face);
        for (int i = 0; i < m; ++i) {
            // Assign vertex indices to each row of F
            F.row(i) << prim->tris[i][0], prim->tris[i][1], prim->tris[i][2];
        }
        if(type == "gaussianCurvature"){
            Eigen::VectorXd K;
            igl::gaussian_curvature(V, F, K);
            prim->verts.add_attr<float>("gaussianCurvature");
            for(int i = 0;i < prim->verts.size();i++){
//                prim->verts.attr<float>("gaussianCurvature")[i] = K[i];
                prim->verts.attr<float>("gaussianCurvature")[i] = K(i,0);
            }
        }
        else if(type == "curvature"){
            Eigen::MatrixXd H;
//            igl::curvature(V, F, H);
            prim->verts.add_attr<float>("curvature");
            for(int i = 0;i < prim->verts.size();i++){
                prim->verts.attr<float>("curvature")[i] = H(i,0);
            }
        }

        set_output("prim", prim);
    }
};
ZENDEFNODE(PrimCurvature, {
    {
        {"PrimitiveObject", "prim"},
        {"enum gaussianCurvature curvature", "type", "gaussianCurvature"},
    },
    {
        {"PrimitiveObject", "prim"},
    },
    {},
    {"primitive"},
});

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

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

相关文章

我给自己搭建的前端导航网站,你们都别用

欢迎关注我&#x1f970;&#x1f970;&#x1f970; 主页传送门&#xff0c;持续产出有思考的文档&#xff5e; &#x1f4a5; 想法来源 前段时间在工作的时候&#xff0c;因为遇到了一些之前没了解过的知识&#xff0c;所以化身百度cv工程师&#xff0c;上网冲浪寻找灵感&am…

第六十一天学习记录:C语言进阶:C语言预处理1

程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 第一种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境&#xff0c;它用于实际执行代码。 详解编译链接 翻译环境 ![在这里插入图片描述](https:/…

实战:单点登录的两种实现方式,附源码

最近工作有点忙&#xff0c;好久没更新文章了&#xff0c;正好这两天在整理单点登陆相关的文档&#xff0c;今天趁着小孩睡着了&#x1f92b;&#xff0c;赶紧码一篇实战文交差。 概念 单点登录&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一种身份验证服务&…

机器学习常识 13: PCA

摘要: 主成分分析 (principal component analysis, PCA) 是一种有理论依据的无监督特征提取的线性方法. 1. 特征选择与特征提取 特征选择是指从已有的特征里面选择出一个子集. 例如: 身高、体重、性别、年龄、体温、血相等等, 如果要一个人是否患流感&#xff0c;身高、体重等…

OpenMMLab-AI实战营第二期——1. 计算机视觉与OpenMMLab概述

文章目录 1. 课程内容概述1.1 Openmmlab框架1.2 课程其他说明 2. mmcv安装2.1 正确步骤2.2 debug2.3 错误探索 1. 课程内容概述 个人更关注语义分割和3D方面的内容&#xff0c;所以这里重点记录这两点相关的。 1.1 Openmmlab框架 具体的模块&#xff0c;详见&#xff1a;http…

wy的leetcode刷题记录_Day67

wy的leetcode刷题记录_Day67 声明 本文章的所有题目信息都来源于leetcode 如有侵权请联系我删掉! 时间&#xff1a;2023-6-1 前言 目录 wy的leetcode刷题记录_Day67声明前言1019. 链表中的下一个更大节点题目介绍思路代码收获 1019. 链表中的下一个更大节点 222. 完全二叉树…

UUOffice 工具箱,一款功能强大的 Excel 办公插件,好用推荐 ~

简介 UUOffice 工具箱,是一款功能强大的Office插件&#xff0c;功能强大&#xff0c;有着各种的单元格及文本的处理工具&#xff0c;自定义扩展函数&#xff0c;批注管理&#xff0c;图片导入导出&#xff0c;工作表汇总&#xff0c;联想输入等等超多实用工具&#xff0c;对日…

奇葩算法——猴子排序

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;猴子排序 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光的社区…

Docker下载遇到的报错以及解决记录

目录 一、docker介绍 1. Docker引擎 2. Docker镜像 3. Docker容器 4. Docker仓库 5. Docker网络 二、docker下载 1.首先再官方下载好docker 2.在我打开时出现了下面的错误&#xff1a; 然后我下载了一个wsl 然后就可以正常打开了 &#xff08;2&#xff09;如果自己的电…

「学习IT技术和编写高质量代码的经验和建议」

一、你在编写代码时&#xff0c;会特别注意哪些流程&#xff1f; 在编写代码的过程中&#xff0c;我通常会特别注意以下流程&#xff1a; 输入验证&#xff1a;确保输入的参数满足预期&#xff0c;防止出现非法输入导致的安全问题或异常错误。 异常处理&#xff1a;在代码中添…

迅为全国产ATX3A5000_7A2000主板-龙芯平台安装 开源loongnix系统

Loongnix下载 Loongnix桌面版镜像:有基于mate主题的版本和基于cartoon主题的版本。本章节的安装 步骤以cartoon主题的安装方式为例&#xff0c;mate主题的ISO安装步骤与cartoon主题的安装方式类 似。 1.1 引导和开始安装 主机启动后,BIOS从U盘引导启动系统&#xff0c;出现…

Vue组件化、通过自定义指令子组件向父组件传递、$nextTick

1.如何安装Vue脚手架&#xff1f; 第一步&#xff08;仅第一次执行&#xff09;&#xff1a;全局安装vue/clinpm install -g vue/cli 第二步&#xff1a;切换到你要创建项目的目录&#xff0c;然后使用命令创建项目vue create xxxx 第三步&#xff1a;启动项目npm run serve 2…

chatgpt赋能python:Python中的或且非

Python中的或且非 Python语言中的逻辑运算符包括&#xff1a;或、与、非&#xff0c;分别用 “|”、“&”、"~"符号表示。 或运算符&#xff08;|&#xff09; 当两个操作数中有一个为True时&#xff0c;结果为True。 例如&#xff1a; a 1 b 2 c 3 if a…

Qt概述和项目文件介绍

注意&#xff1a;学习本专栏的内容需要了解C相关知识&#xff0c;会涉及到C基础语法和相关特性&#xff0c;可以参考我的另一个专栏 c从零开始_小梁今天敲代码了吗的博客-CSDN博客 目录 一.什么是Qt 二.Qt的案例 三.项目文件介绍 一.什么是Qt 是一个跨平台的 C 应用程序…

YOLOV5 + PYQT5双目测距(二)

YOLOV5 PYQT5双目测距 1. 测距源码2. 测距原理3. PYQT环境配置4. 实验4.1 下载源码14.2 复制源码2文件夹4.3 创建py文件4.4 实验结果 1. 测距源码 详见文章 YOLOV5 双目测距&#xff08;python&#xff09; 2. 测距原理 如果想了解双目测距原理&#xff0c;请移步该文章 双…

chatgpt赋能python:Python中的行与列:从入门到精通

Python中的行与列&#xff1a;从入门到精通 Python是一种高级编程语言&#xff0c;广泛用于计算机编程领域。在Python中&#xff0c;行和列是编程过程中不可或缺的元素&#xff0c;因为它们代表着代码中最基本的构建块。本文将介绍Python中的行和列&#xff0c;并探讨它们在程…

【python】之loguru库,好用的日志管理库!

在 Python 中用到日志记录&#xff0c;那就不可避免地会用到内置的 logging标准库 。虽然logging 库采用的是模块化设计&#xff0c;你可以设置不同的 handler 来进行组合&#xff0c;但是在配置上通常较为繁琐&#xff1b;而且如果不是特别处理&#xff0c;在一些多线程或多进…

linux进程间通信(信号量)

信号量是一个特殊的变量&#xff0c;程序对其访问都是原子操作&#xff0c;且只允许对它进行等待&#xff08;即 P(信号变量))和发 送&#xff08;即 V(信号变量))信息操作。最简单的信号量是只能取 0 和 1 的变量&#xff0c;这也是信号量最常见的一种形式&#xff0c; 叫做二…

由于找不到iutils.dll而造成的错误,要怎么去解决?

在使用电脑或运行某些软件时&#xff0c;有时会遇到“找不到iutils.dll”的错误提示。这个错误通常表示缺少iutils.dll文件或者该文件已经损坏。如果你遇到了这个问题&#xff0c;不要担心&#xff0c;因为有很多方法可以解决这个问题。下面我们一起来看看找不到iutils.dll的问…

在spring容器启动后监听事件ApplicationReadyEvent

概述 经常会在业务中遇到需要在项目启动后刷新/预热一些数据的要求。 常见可以监听ApplicationReadyEvent和ContextRefreshedEvent. 但是因为常见的springboot项目都依赖的springmvc&#xff0c;所以实际上有2个容器&#xff0c;spring的ioc容器是springmvc的父容器。 而且C…