nerf论文代码理解

news2024/11/23 17:50:59

        近年来,生成式AI(AGI)快速发展,各类生成式模型层出不群,但我更觉得具有物理意义的生成式AI将是未来革命性技术。因此也在抽空看看关于三维重建的知识,这篇文章就是记录我对nerf的理解。

一、论文理解

        首先,需要知道nerf的输入和输出是什么?

        做cv的朋友都肯定会觉得输入必然是图像,其实图像的输入只是为了后续的loss监督使用,网络的输入是5D向量,包含空间位置xyz和角度theta和phi。

        (1)是什么的空间位置xyz和角度theta和phi?

        粒子,nerf假设空间中的粒子是自发光的,所以图像的渲染是通过这些自发光粒子得到的。

        (2)网络的结构是什么样?

       (3)怎样得到这些粒子?

        根据像素位置转换到归一化相机坐标系,然后再转换到统一的世界坐标系,沿着射线在2~6的范围内均匀采样64个点作为粒子。世界坐标系的转换矩阵,也就是pose是通过SFM(运动结构恢复)得到的(经典的方法是COLMAP)

        (4e)xyz是怎么变为63维的? 

        通过傅里叶级数将输入的xyz变为高频信号,就像transfomer里面的位置编码一样。这样做的好处是能够区别像素间的差异,对于空间重建比较重要,相邻的两个像素,在空间中的距离也可能距离很大。论文中设的embedding的维度是10,所以10*2*3+3=63。其中2表示sin和cos,3是xyz。

        (5)在第5层为什么要加入原始信息?

        为了保持更为准确的空间位置。

        (6)输出的theta是什么?

        在对应的粒子采样点处光线被粒子阻碍的概率密度。

        (7)视角的输入维度为什么是3,又怎么变为27?

        实际网络的输入是向量,是单位向量表示方向。embedding的维度是4,所以3*2*4+3=27.

        (8)为什么视角输入只是在最后加入?

        概率密度只和位置相关,颜色和视角相关。

        (9)最后怎么样渲染得到图像?

        体渲染技术。

        (10)nerf的核心是什么?

        前处理得到网络输入,后处理体渲染技术,分层采样。

        (11)分层采样指的是?

        nerf的模型包括corse模型和fine模型,corse模型的采样是(2)中的均匀等距采样,fine模型会根据corse模型输出的weight,采样逆变换采样的方式重新采样得到128个粒子,使得采样更加关注空间中不为空的区域,128+64=192个粒子作为fine模型的输入。

        (12)还有其他细节嘛?

        为了节省显存,不会整张图对应的射线粒子都会一股脑进入网络,会随机采样1024个像素对应的射线粒子进入网络。

二、代码理解。

获取输入粒子的坐标和方向主要关注以下代码。

    def initialize(self):

        warange = torch.arange(self.width,  dtype=torch.float32, device=self.device)
        harange = torch.arange(self.height, dtype=torch.float32, device=self.device)
        y, x = torch.meshgrid(harange, warange)

        self.transformed_x = (x - self.width * 0.5) / self.focal
        self.transformed_y = (y - self.height * 0.5) / self.focal #normailization coord

        # pre center crop
        self.precrop_index = torch.arange(self.width * self.height).view(self.height, self.width)

        dH = int(self.height // 2 * self.precrop_frac)
        dW = int(self.width  // 2 * self.precrop_frac)
        self.precrop_index = self.precrop_index[
            self.height // 2 - dH:self.height // 2 + dH, 
            self.width  // 2 - dW:self.width  // 2 + dW
        ].reshape(-1)

        poses = torch.FloatTensor(self.poses, device=self.device) #torch.cuda.FloatTensor(self.poses, device=self.device)
        all_ray_dirs, all_ray_origins = [], []

        for i in range(len(self.images)):
            ray_dirs, ray_origins = self.make_rays(self.transformed_x, self.transformed_y, poses[i])
            all_ray_dirs.append(ray_dirs)
            all_ray_origins.append(ray_origins)

        self.all_ray_dirs    = torch.stack(all_ray_dirs, dim=0)
        self.all_ray_origins = torch.stack(all_ray_origins, dim=0)
        self.images          = torch.FloatTensor(self.images, device=self.device).view(self.num_image, -1, 3)#torch.cuda.FloatTensor(self.images, device=self.device).view(self.num_image, -1, 3)


    def make_rays(self, x, y, pose):

        # 100, 100, 3
        # 坐标系在-y,-z方向上
        directions    = torch.stack([x, -y, -torch.ones_like(x)], dim=-1)
        camera_matrix = pose[:3, :3]
        
        # 10000 x 3
        ray_dirs = directions.reshape(-1, 3) @ camera_matrix.T
        ray_origin = pose[:3, 3].view(1, 3).repeat(len(ray_dirs), 1)
        return ray_dirs, ray_origin # xyz theta phi

体渲染主要关注以下代码。

def predict_to_rgb(sigma, rgb, z_vals, raydirs, white_background=False):

    device         = sigma.device
    delta_prefix   = z_vals[..., 1:] - z_vals[..., :-1] #0.0635 sample point delta 
    delta_addition = torch.full((z_vals.size(0), 1), 1e10, device=device)
    delta = torch.cat([delta_prefix, delta_addition], dim=-1)
    delta = delta * torch.norm(raydirs[..., None, :], dim=-1)

    alpha    = 1.0 - torch.exp(-sigma * delta) # 1 - e**-sigma*delta
    exp_term = 1.0 - alpha
    epsilon  = 1e-10
    exp_addition = torch.ones(exp_term.size(0), 1, device=device)
    exp_term = torch.cat([exp_addition, exp_term + epsilon], dim=-1)
    transmittance = torch.cumprod(exp_term, axis=-1)[..., :-1] #(1-alpha0)

    weights       = alpha * transmittance
    rgb           = torch.sum(weights[..., None] * rgb, dim=-2)
    depth         = torch.sum(weights * z_vals, dim=-1)
    acc_map       = torch.sum(weights, -1)

    if white_background:
        rgb       = rgb + (1.0 - acc_map[..., None])
    return rgb, depth, acc_map, weights

体渲染的公式:

连续的:

离散的:

 

不想打字了,去上班挣窝囊费了.....

推荐代码:

shouxieai/nerf: nerf (github.com)

推荐教学视频(讲的真的很好):

【较真系列】讲人话-NeRF全解(原理+代码+公式)_哔哩哔哩_bilibili

推荐b站博主(有时候会去直播,但是看我直播的只有一个人机粉丝):

奈阿伊超

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

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

相关文章

车载冰箱的介绍

车载冰箱产业链的上游环节主要涉及制冷模块的研发与制造,这一环节根据所采用的制冷技术不同而展现出各自的特点。压缩机制冷模块和半 导体制冷模块是车载冰箱制冷系统的核心组成部分,它们在设计、材料选择和制造工艺上各有千秋。 车载冰箱的原理图 车载…

HTB-Three(云服务)

前言 各位师傅大家好,我是qmx_07,今天给大家讲解Three靶机 渗透过程 信息搜集 服务器开启了22 SSH 和 80 HTTP服务端口 扫描目录 服务器只有一个image图片文件,ssh 需要账号名密码 绑定域名 进行子域名扫描探测 疑似域名,尝…

中秋之美——html5+css+js制作中秋网页

中秋之美——html5cssjs制作中秋网页 一、前言二、功能展示三、系统实现四、其它五、源码下载 一、前言 八月十五,秋已过半,是为中秋。 “但愿人长久,千里共婵娟”,中秋时节,气温已凉未寒,天高气爽&#x…

支付平台构建支付接口供整个公司调用—支付代理商

一、支付平台一般需要对外开放用于满足一体化平台调用 支付平台提供支付接口具有以下必要性: 1. 拓展业务范围:使各类商家和服务提供商能够接入支付服务,从而扩大支付平台的用户群体和业务覆盖范围。 2. 提升用户体验:为不同的应…

音视频-图像篇(YUV和RGB)

文章目录 一、图像基础概念二、YUV与RGB1.YUV分类方式2.YUV“空间-间”的数据划分1)UV按照“空间-间”的划分方式,分为YUV444、YUV422、YUV4202)YUV“空间-内”的数据划分 3.RGB 三、比较JPG、PNG、GIF、BMP图片格式 一、图像基础概念 像素&…

Python OpenCV 入门指南

引言 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它包含了大量的用于实时图像分析和视频处理的功能。Python 作为一种流行的编程语言,以其易用性和灵活性成为了进行快速原型设计和开发的理想选择。结…

【python2C】排序算法

题&#xff1a;逆序对&#xff08;NXD&#xff09; 对于给定的一段正整数序列a&#xff0c;逆序对就是序列中 a[i]​>a[j]​ 且 i<j 的有序对。 输入格式 第一行&#xff0c;一个正整数 n&#xff0c;表示序列中有 n个数&#xff0c;n<5e5 第二行&#xff0c; n 个正整…

学习之git

github 创建远程仓库 代码推送 Push 代码拉取 Pull 代码克隆 Clone SSH免密登录 Idea集成GitHubGitee码云 码云创建远程仓库 Idea集成Gitee码云 码云连接Github进行代码的复制和迁移GitLab gitlab服务器的搭建和部署 Idea集成GitLabgit概述 一切皆本地 版本控制工具 集中…

读软件开发安全之道:概念、设计与实施15安全测试

1. 安全测试 1.1. 测试是开发可靠、安全代码中的关键一环 1.2. 测试安全漏洞的目的是主动检测 1.3. 模糊测试是一种强大的补充技术&#xff0c;可以帮助我们找到更深层次的问题 1.4. 针对当前漏洞创建的安全回归测试&#xff0c;目的是确保我们不会再犯相同的错误 1.5. 大…

LabVIEW焊缝视觉识别系统

随着自动化技术的发展&#xff0c;焊接工艺也在向智能化和自动化转型。介绍了一种基于LabVIEW开发的自动化焊接机器人视觉识别系统&#xff0c;用于提高焊接质量和效率&#xff0c;特别适用于复杂或危险环境下的操作。 项目背景 在传统焊接工艺中&#xff0c;焊接质量和效率受…

linux 文件管理命令

Ctrl h, 在对应的文件夹路径下显示文件内容 2.“~”、“/”、“./”分别代表什么&#xff1f; https://blog.csdn.net/shuaiqidexiaojiejie/article/details/132563658 2.1&#xff0c;“~”表示主目录&#xff0c;也就是当前登录用户的用户目录 cd ~, 表示返回到Home目录 2.2…

使用 GZCTF 结合 GitHub 仓库搭建独立容器与动态 Flag 的 CTF 靶场以及基于 Docker 的 Web 出题与部署

写在前面 关于 CTF 靶场的搭建&#xff08;使用 CTFd 或者 H1ve&#xff09;以及 AWD 攻防平台的搭建&#xff0c;勇师傅在前面博客已经详细写过&#xff0c;可以参考我的《网站搭建》专栏&#xff0c;前段时间玩那个 BaseCTF&#xff0c;发现它的界面看着挺不错的&#xff0c…

esp8266根据httpserver状态,调用网络唤醒,实现一键开机

esp8266根据httpserver状态&#xff0c;调用网络唤醒&#xff0c;实现一键开机 一.开发板程序二. 服务端三.服务端状态变更 一.开发板程序 #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiUdp.h> #include <ArduinoJson.h>/…

C语言深入理解指针1

1. 内存和地址 1.1内存 内存空间如何高效管理?把内存划分一个个的内存单元&#xff0c;每个内存单元的大小取一个字节一个比特位可以存储一个2进制的位1或者0&#xff0c;那么一个内存单元可以放8个比特位&#xff0c;每个内存单元都有一个编号&#xff0c;有了内存单元的编…

Golang | Leetcode Golang题解之第389题找不同

题目&#xff1a; 题解&#xff1a; func findTheDifference(s, t string) (diff byte) {for i : range s {diff ^ s[i] ^ t[i]}return diff ^ t[len(t)-1] }

自然美景短视频素材哪里找?9个美景视频素材库网站分享

你是否曾被窗外的落日余晖震撼&#xff0c;或是被雄伟的山脉和蔚蓝的大海深深吸引&#xff1f;想要分享这世界的美好&#xff0c;却苦于没有合适的视频素材&#xff1f;今天&#xff0c;就让我带你探索那些充满自然韵味的素材宝库&#xff0c;帮你捕捉和分享自然的美丽&#xf…

Linux下安装MySQL8.0

一、安装 1.下载安装包 先创建一个mysql目录&#xff0c;在将压缩包下载到此 # 下载tar包 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz等待下载成功 2.解压mysql8.0安装包 tar xvJf mysql-8.0.20-linux-glibc2.12-x86…

sqli-labs第五、六关详解

第五关不同于前面四关&#xff0c;涉及到盲注 首先看看是字符型注入还是数字型注入 用单引号闭合后&#xff0c;and 12无回显&#xff0c;说明字符型注入&#xff0c;接下来就要靠猜了&#xff0c;首先猜数据库长度是多少 长度为8的时候&#xff0c;正常回显&#xff0c;所以数…

DFS解决floodfill算法

文章目录 1. 图像渲染2. 岛屿数量3. 岛屿的最大面积4. 被围绕的区域5. 太平洋大西洋水流问题6. 扫雷游戏7. 机器人的运动范围 1. 图像渲染 算法原理&#xff1a; 这题不需要创建visit数组去记录使用过的节点&#xff0c;因为我每次dfs都尝试修改image数组的值&#xff0c;当下…

电阻器件的选型

电阻选型需要的注意点&#xff1a; 老化系数:电阻器在额定功率长期负荷下&#xff0c;阻值相对变化的百分数&#xff0c;它是表示电阻器寿命长短的参数。 噪声:包括热噪声和电流噪声两部分&#xff0c;电阻是一个耗能的器件&#xff0c;电阻器是消耗能量的。 电阻的选型需要关注…