【开发日志】2023.04 ZENO----Composite----CompNormalMap

news/2024/5/9 6:58:45/文章来源:https://blog.csdn.net/Angelloveyatou/article/details/130319455

CompNormalMap

将灰度图像转换为法线贴图

将灰度图像转换为法线贴图是一种常见的技术,用于在实时图形渲染中增加表面细节。下面是一个简单的方法来将灰度图像转换为法线贴图:

  1. 加载灰度图像,并将其转换为浮点数值范围[0, 1]。

  2. 对于每个像素,计算其相邻像素与其距离,并计算它们之间的斜率。这可以通过使用Sobel算子或其他边缘检测算法来完成。

  3. 将每个像素的斜率向量归一化为单位长度,并转换为范围[-1, 1]内的值。

  4. 将每个像素的斜率向量转换为法线向量。法线向量可以通过使用以下公式计算得出:$normal = (2R - 1, 2G - 1, B)$,其中R,G和B分别是像素的红、绿和蓝通道值。由于我们的灰度图像没有颜色信息,我们可以将R,G和B设置为0.5,以得到一个朝向Z轴正方向的法线。

  5. 存储每个像素的法线向量作为输出法线贴图。

需要注意的是,这个简单的方法只能生成表面细节的近似值,并且可能会在处理像素边缘和细节时出现不准确的结果。更复杂的技术可以使用高斯过滤和其他方法来平滑法线图并产生更精细的结果。

Input:

Output:

​​​​​​​

/* 将灰度图像转换为法线贴图 */struct CompNormalMap : INode {virtual void apply() override {auto image = get_input<PrimitiveObject>("image");auto &ud = image->userData();int w = ud.get2<int>("w");int h = ud.get2<int>("h");float gx = 0;float gy = 0;float gz = 1;float avr = 0;for (int i = 1; i < h-1; i++) {for (int j = 1; j < w - 1; j++) {int idx = i * w + j;avr = (image->verts[idx + 1][0] + image->verts[idx + 1][1] + image->verts[idx + 1][2]) / 3;image->verts[idx + 1] = {avr,avr,avr};}}for (int i = 1; i < h-1; i++) {for (int j = 1; j < w-1; j++) {int idx = i * w + j;// 计算梯度gx = -(image->verts[idx+1][0] - image->verts[idx-1][0]) / 2.0f;gy = -(image->verts[idx+w][0] - image->verts[idx-w][0]) / 2.0f;// 归一化法线向量float len = sqrt(gx * gx + gy * gy + gz * gz);gx /= len;gy /= len;gz /= len;// 计算光照值gx = 0.5f * (gx + 1.0f) ;gy = 0.5f * (gy + 1.0f) ;gz = 0.5f * (gz + 1.0f) ;image->verts[i * w + j][0] = gx;image->verts[i * w + j][1] = gy;image->verts[i * w + j][2] = gz;}}set_output("image", image);}
};
ZENDEFNODE(CompNormalMap, {{{"image"}},{{"image"}},{},{ "comp" },
});

cv

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{Mat grayImage = imread("gray_image.png", IMREAD_GRAYSCALE);if (grayImage.empty()){cerr << "Could not read input image" << endl;return -1;}Mat normalMap(grayImage.size(), CV_8UC3);for (int i = 1; i < grayImage.rows - 1; i++){for (int j = 1; j < grayImage.cols - 1; j++){double dx = grayImage.at<uchar>(i, j + 1) - grayImage.at<uchar>(i, j - 1);double dy = grayImage.at<uchar>(i + 1, j) - grayImage.at<uchar>(i - 1, j);Vec3b normal(dx, dy, 255);normalize(normal, normal);normalMap.at<Vec3b>(i, j) = normal * 127.5 + Vec3b(127.5, 127.5, 127.5);}}imwrite("normal_map.png", normalMap);return 0;
}

不调库

#include <iostream>
#include <fstream>
#include <cmath>using namespace std;int main() {// 读取灰度图ifstream input("input.bmp", ios::binary);if (!input) {cout << "无法打开文件" << endl;return 1;}char header[54];input.read(header, 54);int width = *(int*)(header + 18);int height = *(int*)(header + 22);int row_size = (width * 24 + 31) / 32 * 4;char* data = new char[row_size * height];input.read(data, row_size * height);input.close();// 计算法线图char* output = new char[row_size * height];for (int y = 1; y < height - 1; y++) {for (int x = 1; x < width - 1; x++) {// 计算梯度double dx = (data[(y + 1) * row_size + (x + 1) * 3] - data[(y - 1) * row_size + (x - 1) * 3]) / 255.0;double dy = (data[(y - 1) * row_size + (x + 1) * 3] - data[(y + 1) * row_size + (x - 1) * 3]) / 255.0;double dz = 1.0;// 归一化法线向量double length = sqrt(dx * dx + dy * dy + dz * dz);dx /= length;dy /= length;dz /= length;// 计算光照值double light = dx * 0.5 + dy * -0.5 + dz * 0.5 + 0.5;int value = int(light * 255);output[y * row_size + x * 3] = value;output[y * row_size + x * 3 + 1] = value;output[y * row_size + x * 3 + 2] = value;}}// 输出法线图ofstream of("output.bmp", ios::binary);of.write(header, 54);of.write(output, row_size * height);of.close();delete[] data;delete[] output;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IT_开发提测标准规范

背景 公司 IT 规模小&#xff0c;开发提测质量差&#xff0c;流程不规范&#xff0c;导致测试任务重&#xff0c;于是推行 &#xff1a;IT_开发提测标准规范&#xff0c;正文如下&#xff1b;拟定开发提测标准规范后&#xff0c;测试与项目经理内部评审后&#xff0c;发至IT群…

盘点几款还不错的企业网盘产品

企业网盘的出现&#xff0c;为企业提供文件安全管理&#xff0c;团队协作服务&#xff0c;解决了便捷性与安全性等问题&#xff0c;受到了企业的青睐。市面上的企业网盘工具也是五花八门&#xff0c;我们该如何选择适合自己团队的网盘工具呢&#xff1f; 本文盘点了几款还不错的…

反射-Class类分析

反射相关的主要类 java.lang.Class&#xff1a;代表一个类&#xff0c;Class对象表示某个类加载后在堆中的对象java.lang.reflect.Method&#xff1a;代表类的方法&#xff0c;Method对象表示某个类的方法java.lang.reflect.Field&#xff1a;代表类的成员变量&#xff0c;Fie…

20230422 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142. 环形链表 II

1、24. 两两交换链表中的节点 初始时&#xff0c;cur指向虚拟头结点&#xff0c;然后进行如下三步&#xff1a; 操作之后&#xff0c;链表如下&#xff1a; 看这个可能就更直观一些了&#xff1a; /*** Definition for singly-linked list.* public class ListNode {* i…

Android 日志框架使用

在实际开发中&#xff0c;经常会遇到需要打印日志并保存到文件中&#xff0c;便于后面取日志分析代码运行情况&#xff0c;当然如果只是打印日志不需要记录文件&#xff0c;使用android自带的log工具就完全够了&#xff0c; Log打印日志会记录到系统日志中&#xff0c;可以取出…

Rust之泛型、特性和生命期(一):基本概念

开发环境 Windows 10Rust 1.69.0 VS Code 1.77.3 项目工程 这里继续沿用上次工程rust-demo 泛型、特性和生命期 每种编程语言都有有效处理概念重复的工具。在Rust中&#xff0c;一个这样的工具就是泛型&#xff1a;具体类型或其他属性的抽象替身。我们可以表达泛型的行为或…

CorelDRAW 2023版本更新内容及安装详细教程

这里是CorelDRAW 2023版本更新内容及安装详细教程: CorelDRAW 2023是最新更新版本,在界面和功能上做了较大提升与优化: 1. 简洁界面:采用全新设计界面,简约而不简单。菜单和工具栏进行了整合与重组,更加直观。拥有自动标记和提示,易于上手使用。 2. 全新工作空间:提供“轻量…

基于51单片机的脉搏测量仪设计与实现

目录 前言 一、设计背景 二、系统功能 三、系统硬件设计 3.1 总体方案设计 3.2 信号采集电路设计 3.3 报警电路设计 3.4 下载电路 3.5 电源电路设计 3.6 OLED显示设计 3.7 键盘电路 四、系统软件设计 4.1 系统主程序设计 4.2 脉搏采集子程序设计 4.3 键盘程序设…

正式开赛|2023年“桂林银行杯”数据建模大赛暨全国大学生数学建模竞赛广西赛区热身赛

为学习贯彻党的二十大工作报告中关于加快发展数字经济、促进数字经济和实体经济深度融合的重要指示&#xff0c;不断推进数字化转型与金融科技创新&#xff0c;桂林银行联合全国大学生数学建模竞赛广西赛区组委会、广西应用数学中心&#xff08;广西大学&#xff09;共同主办20…

使用EasyExcel导出模板并设置级联下拉及其原理分析

一、概述 项目中有时会遇到需要导出一个Excel模板&#xff0c;然后在导出的Excel中填充数据&#xff0c;最终再调用接口批量把Excel中的数据导入到数据库当中的需求。 其中级联下拉选择&#xff0c;手机号校验&#xff0c;性别校验等都是比较常见的校验。 这里就已上面三种情…

王道计组(23版)3_存储系统

概述 RAM&#xff1a;随机存储器&#xff0c;任一个存储单元可以随机存取&#xff0c;易失。用作主存(DRAM)或Cache(SRAM) ROM&#xff1a;只读存储器&#xff0c;可随机读出&#xff0c;写入较慢&#xff0c;需刷新&#xff0c;非易失。Flash、SSD固态硬盘、U盘 _____SSD&…

RK3399平台开发系列讲解(PCI/PCI-E)PCIE相关配置说明

🚀返回专栏总目录 文章目录 一、DTS 配置二、menuconfig 配置三、cmdline 配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍在使用 RK3399 平台 PCIE 时候的配置。 一、DTS 配置 ep-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; 此项是设置 PCIe…

arthas的简单使用

目录 arthas是什么为什么要使用arthasarthas能做什么安装arthas前提准备arthas主要命令trace命令watch命令monitor命令jad命令dashboard命令Thread命令sc命令mc命令redefine命令 实战演练1.定位到需要修改的类2.将定位到的.class文件反编译成.java文件3.修改.java文件4.将修改后…

深入浅出DPDK-1.1主流包处理硬件平台

DPDK用软件的方式在通用多核处理器上演绎着数据包处理的新篇章&#xff0c;而对于数据包处理&#xff0c;多核处理器显然不是唯一的平台。支撑包处理的主流硬件平台大致可分为三个方向&#xff1a;硬件加速器、网络处理器、多核处理器。 根据处理内容、复杂度、成本、量产规模…

Scala循环中断

目录 1.使用抛出和捕获异常的方法跳出当前循环2.使用Scala中的Breaks类的break方法3.测试4.简化 使用 ._ 来引入全部内容 方便调用 在scala中无法直接使用break关键字跳出当前循环&#xff0c;但有其他方法 1.使用抛出和捕获异常的方法跳出当前循环 def main(args: Array[Str…

3105—IIS部署子站点

一、父站点 1—web.config配置 新增并设定location段落 <configuration><location path"." allowOverride"false" inheritInChildApplications"false"><system.webServer><handlers><add name"aspNetCore"…

Java -枚举的使用

一、背景及定义 枚举是在JDK1.5以后引入的。主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式&#xff1a; public static int final RED 1; public static int final GREEN 2; public static int final BLACK 3;但是常量…

使用 Flask 快速构建 基于langchain 和 chatGPT的 PDF摘要总结

简介 这里不对 langchain 和 chatGPT 进行介绍&#xff0c;仅对实现过程进行整理 环境 Python >3.8 Flask2.2.3 Jinja23.1.2 langchain0.0.143 openai0.27.4 实现 总结功能 使用 langchain 和 openai 接口实现总结功能 实现逻辑&#xff1a;通过text_splitter 将pdf 分…

图像分类识别(方向/重点指引)

1、继YOLO之后的高效目标检测算法&#xff1a; CenterNet 继YOLO之后的高效目标检测算法&#xff1a; CenterNet 2、百度飞浆面向 AI 行业应用场景的开源项目&#xff1a;GitHub - PaddlePaddle/PaddleX: PaddlePaddle End-to-End Development Toolkit&#xff08;『飞桨』…

APP渗透—绕过反代理、反证书检测

APP渗透—绕过反代理、反证书检测 1. 前言1.1. 无法获取数据包情况 2. 反代理2.1. 反代理情况2.1.1. 某牛牛反代理2.1.2. 某探反代理 2.2. 绕过反代理2.2.1. Proxifier设置2.2.1.1. 设置代理服务器2.2.1.2. 配置代理规则2.2.1.3. 检测状态 2.2.2. 抓包测试 2.3. 总结 3. 反证书…