NeRF源码解析

NeRF的源码结构如代码中的"源码结构.md"所示。

1、NeRF训练参数介绍

# 配置文件的路径
    parser.add_argument('--config', is_config_file=True,help='config file path')
    # 本次实验的名称,作为log中文件夹的名字
    parser.add_argument("--expname", type=str,help='experiment name')
    # 输出目录
    parser.add_argument("--basedir", type=str, default='./logs/',help='where to store ckpts and logs')
    # 指定数据集的目录
    parser.add_argument("--datadir", type=str, default='./data/llff/fern',help='input data directory')
    # training options
    # 全连接的层数
    parser.add_argument("--netdepth", type=int, default=8,help='layers in network')
    # 网络宽度
    parser.add_argument("--netwidth", type=int, default=256,help='channels per layer')
    # 精细网络的全连接层数
    # 默认精细网络的深度和宽度与粗糙网络是相同的
    parser.add_argument("--netdepth_fine", type=int, default=8,help='layers in fine network')
    parser.add_argument("--netwidth_fine", type=int, default=256,help='channels per layer in fine network')
    # 这里的batch size,指的是光线的数量,像素点的数量
    # N_rand 配置文件中是1024,光线的数量
    # 32*32*4=4096
    # 800*800/4096=156 400*400/1024=156
    parser.add_argument("--N_rand", type=int, default=32 * 32 * 4,help='batch size (number of random rays per gradient step)')
    # 学习率
    parser.add_argument("--lrate", type=float, default=5e-4,help='learning rate')
    # 学习率衰减
    parser.add_argument("--lrate_decay", type=int, default=250,help='exponential learning rate decay (in 1000 steps)')
    # 如果上述的N_rand > chunk就会分批处理
    parser.add_argument("--chunk", type=int, default=1024 * 32,help='number of rays processed in parallel, decrease if running out of memory')
    # 神经网络中处理的点的数量
    parser.add_argument("--netchunk", type=int, default=1024 * 64,help='number of pts sent through network in parallel, decrease if running out of memory')
    # rendering options 粗网络渲染时的采样点数量
    parser.add_argument("--N_samples", type=int, default=64,help='number of coarse samples per ray')
    # 精细网络采样点数量
    parser.add_argument("--N_importance", type=int, default=0,help='number of additional fine samples per ray')
    # 在采样点附近是否加入随机扰动
    parser.add_argument("--perturb", type=float, default=1.,help='set to 0\. for no jitter, 1\. for jitter')
    # L=10
    parser.add_argument("--multires", type=int, default=10,help='log2 of max freq for positional encoding (3D location)')
    # L=4
    parser.add_argument("--multires_views", type=int, default=4,help='log2 of max freq for positional encoding (2D direction)'

2、数据集加载

Blender结构的数据集的文件结构长这个样子→ :

json文件内容如下(相机坐标系转世界坐标系):

还有llff格式的数据,在该文件夹下,首先是一个images文件夹,并在该数据集的根目录下会有llff的相机位姿文件,里面是一个数组(20, 17),前面15维是位姿信息,后面2维是边界。其中处理过后,将其差分为poses的形状为(20, 3,5),bds(2, 20). 并且将相机坐标系转换为世界坐标系。

首先先处理数据集,大部分数据集都是blender的数据结构,该代码中提供了四种不同的数据集加载方式。在此函数中,主要包含了读取文件,图像归一化,提取位置信息,划分数据集、验证集、测试集,计算焦距,渲染的位置(这个是为了测试)。详细见代码。

3、位置编码介绍 pe

位置编码对应的代码位于“./run_nerf.py”的"create_nerf"中,利用"get_embedder"函数,此函数会返回一个lambda函数和神经网络的输入通道数量。

接下来就是生成NeRF神经网络了,并且会构建神经网络优化器。神经网络的结构如图所示:

4、将像素坐标系转换成世界坐标系的方法 get_rays

这部分主要是获得光线的原点和方向,还有坐标系的转换,然后随机选取N_rand条光线

然后,这里是将相机坐标系转换为世界坐标系,然后获得每一个光线的原点和方向。

def get_rays_np(H, W, K, c2w):
    # 与上面的方法相似,这个是使用的numpy,上面是使用的torch
    i, j = np.meshgrid(np.arange(W, dtype=np.float32), np.arange(H, dtype=np.float32), indexing='xy')
    dirs = np.stack([(i - K[0][2]) / K[0][0], -(j - K[1][2]) / K[1][1], -np.ones_like(i)], -1)
    # Rotate ray directions from camera frame to the world frame
    rays_d = np.sum(dirs[..., np.newaxis, :] * c2w[:3, :3],-1)  # dot product, equals to: [c2w.dot(dir) for dir in dirs]
    # Translate camera frame's origin to the world frame. It is the origin of all rays.
    rays_o = np.broadcast_to(c2w[:3, -1], np.shape(rays_d))
    return rays_o, rays_d 

5、主循环介绍

首选是一个与提渲染相关的"render"函数,这里面主要是对光线进行采样点的选择。也就是r(t) = o + td,采样过后经过神经网络计算,获得不透明度和三个颜色值。

6、体渲染 raw2outputs

神经网络的结果经过体渲染公式进行输出。

7、分层采样 sample_pdf

上面是粗糙网络的采样,后面就是通过精细网络进行分层采样。

源码解析视频讲解:NeRF源码解析_哔哩哔哩_bilibili

git代码仓库:https://github.com/xunull/read-nerf-pytorch

原始代码:https://github.com/yenchenlin/nerf-pytorch

官方代码:https://github.com/bmild/nerf

旋转矩阵: https://blog.csdn.net/csxiaoshui/article/details/65446125

相机标定: https://blog.csdn.net/Kalenee/article/details/99207102

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,343评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,508评论 3 400
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,182评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,374评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,372评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,926评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,333评论 3 426
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,285评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,813评论 1 321
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,887评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,016评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,677评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,350评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,843评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,960评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,493评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,038评论 2 361

推荐阅读更多精彩内容