一、论文概述
生成模型(如Stable Diffusion)已能从文本提示生成逼真图像,但生成360度全景图像仍面临挑战,主要因为缺乏配对的文本-全景数据和全景图像与透视图像之间的域差异。本文提出了PanFusion,一个双分支扩散模型,利用Stable Diffusion模型的自然图像生成知识,并将其与全景分支注册,以生成360度图像。通过独特的跨注意力机制(EPPA),最小化在协作去噪过程中的失真。实验验证了PanFusion在生成质量和一致性上超越现有方法,并能通过全景分支集成额外的约束(如房间布局)以定制全景输出。

二、方法框架
1.双分支扩散模型
PanFusion包含两个分支,一个全景分支(Panorama Branch)和一个透视分支(Perspective Branch),两者都基于Stable Diffusion(SD)的UNet结构。全景分支:负责创建一个连贯的全景“画布”,并注册透视信息以得到无需拼接的全景输出。透视分支:利用SD在透视图像生成方面的能力,提供指导以减轻透视投影下的失真。
2.EPPA机制
Equirectangular-Perspective Projection Attention (EPPA) 机制:在两个分支之间传递信息,增强全景和透视视图之间的协同作用。布局生成条件:PanFusion还可以根据给定的房间布局生成全景图像,这对于全景新视角合成和室内3D场景生成非常有用。
3.输入与输出
输入:文本提示:用户输入的描述性文本,用于指导全景图像的生成。输出:360度全景图像:根据输入的文本提示生成的全景图像,具有360度水平视场和180度垂直视场。
三、具体步骤
1.文本编码
输入:用户输入的文本提示,例如:“A living room with a ceiling fan.”
编码过程:文本提示首先被编码为模型可以理解的形式。这通常涉及到使用一个预训练的语言模型(如BERT或其变体)来将文本转换为高维向量表示,这个向量捕捉了文本的语义信息。在PanFusion中,这一步骤可能涉及到使用BLIP 2模型(一种视觉-语言预训练模型)来生成每个图像的短描述,作为文本提示的编码。
2. 双分支初始化
全景分支(Panorama Branch):初始化全景潜在映射TzT 作为高斯噪声。
透视分支(Perspective Branch):将全景潜在映射TzT 投影到多个透视视图中,初始化透视潜在映射TziT。这里使用最近邻插值进行投影,以减少插值过程中的失真。
3. 迭代去噪
去噪过程:PanFusion模型使用一个迭代去噪过程来逐步从噪声中恢复出清晰的图像。这个过程涉及到在潜在空间中应用一个UNet模型,该模型被训练来预测在每个时间步 t 的噪声 ϵ 和条件ξ(y) 下的潜在映射 zt。
训练目标:训练目标是最小化真实噪声ϵ 和模型预测噪声ϵϕ(zt,t,ξ(y)) 之间的差异。
4. Equirectangular-Perspective Projection Attention (EPPA) 模块
EPPA模块:EPPA模块在全景分支和透视分支之间传递信息。它包含两个关键组件:球面位置编码(SPE)和EPP注意力掩码。
球面位置编码(SPE):为全景特征图计算SPE,然后将其投影到每个透视特征图上,使得不同格式中的对应像素共享相同的SPE向量。
EPP注意力掩码:通过增强亲和力矩阵 A 来鼓励注意力机制关注对应像素周围的信息。
5. 布局条件生成
布局条件:如果提供了房间布局条件,将其渲染为距离图,并使用ControlNet来控制全景分支的生成,从而生成遵循精确空间条件的图像。
6. 解码和输出
解码:最终的全景潜在映射通过预训练的Stable Diffusion解码器D解码成图像空间,产生最终的全景图像。
7. 训练和优化
损失函数:在训练过程中,PanFusion结合全景分支和透视分支的损失函数来优化模型参数。这包括对全景分支和透视分支的预测噪声进行监督,以确保生成的全景图像在质量和一致性上优于现有方法。
四、个人理解
1.全局全景分支
全局全景分支(Panorama Branch)负责生成全局的全景布局,提供一个连贯的全景“画布”。它工作在全景图像的分辨率下,考虑到全景图像的宽高比(2:1)和球面投影(ERP)几何特性,能够捕捉全局结构和空间一致性,减少全景图像中的重复元素和不一致性问题。
import torch
import torch.nn as nn
import torch.nn.functional as F
class PanoramaBranch(nn.Module):
def __init__(self):
super(PanoramaBranch, self).__init__()
# 假设使用一个简单的UNet结构作为全景分支的示例
self.encoder = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.Conv2d(64, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.decoder = nn.Sequential(
nn.ConvTranspose2d(64, 64, kernel_size=2, stride=2),
nn.ReLU(),
nn.Conv2d(64, 3, kernel_size=3, padding=1),
nn.Tanh()
)
def forward(self, x):
# 编码器
encoded = self.encoder(x)
# 解码器
decoded = self.decoder(encoded)
return decoded
# 假设输入的全景图像分辨率为1024x512
input_image = torch.randn(1, 3, 512, 1024) # BCHW
pano_branch = PanoramaBranch()
pano_output = pano_branch(input_image)
2.局部透视分支
局部透视分支(Perspective Branch)利用Stable Diffusion模型在透视图像生成方面的能力,专注于生成细节丰富的多视角透视图像。它在较低分辨率下工作,通过采样多个相机视角来覆盖整个全景图像,每个视角都对应一个局部的透视图。能够利用SD模型在细节生成方面的优势,同时提供对局部视角的指导,以减轻透视投影下的失真。
class PerspectiveBranch(nn.Module):
def __init__(self):
super(PerspectiveBranch, self).__init__()
# 假设使用一个简化的Stable Diffusion模型作为透视分支的示例
self.model = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.Conv2d(64, 64, kernel_size=3, padding=1),
nn.ReLU()
)
def forward(self, x):
# 透视图像生成
perspective_output = self.model(x)
return perspective_output
# 假设输入的透视图像分辨率为256x256
input_perspective = torch.randn(1, 3, 256, 256) # BCHW
pers_branch = PerspectiveBranch()
pers_output = pers_branch(input_perspective)
3.EPPA模块
EPPA模块通过球面位置编码(SPE)和EPP注意力掩码在全景和透视特征图之间建立联系,从而在两个分支之间传递指导信息。这种信息传递是双向的,全景分支可以向透视分支提供全局上下文信息,而透视分支可以向全景分支提供细节信息,共同优化生成过程。
class EPPAModule(nn.Module):
def __init__(self, channel_dim):
super(EPPAModule, self).__init__()
self.query_linear = nn.Linear(channel_dim, channel_dim)
self.key_linear = nn.Linear(channel_dim, channel_dim)
self.value_linear = nn.Linear(channel_dim, channel_dim)
def forward(self, pano_feat, pers_feat):
# 计算查询(Q)、键(K)和值(V)
Q = self.query_linear(pano_feat).unsqueeze(1)
K = self.key_linear(pers_feat).unsqueeze(0)
V = self.value_linear(pers_feat)
# 计算注意力分数
scores = torch.matmul(Q, K.transpose(-1, -2))
scores = F.softmax(scores, dim=-1)
# 计算输出
output = torch.matmul(scores, V).squeeze(1)
return output
# 假设channel_dim为64
channel_dim = 64
eppa_module = EPPAModule(channel_dim)
# 假设pano_feat和pers_feat是输入的特征图
pano_feat = torch.randn(1, channel_dim, 16, 32) # 全景特征图
pers_feat = torch.randn(1, channel_dim, 8, 16) # 透视特征图
eppa_output = eppa_module(pano_feat, pers_feat)
五、代码分析
EPPA(Equirectangular-Perspective Projection Attention)机制是PanFusion模型中用于在全景分支和透视分支之间传递信息的关键组件。它通过球面位置编码(Spherical Positional Encoding, SPE)和EPP注意力掩码来实现。以下是EPPA机制的简化示例代码,以及对每个步骤的详细解释:
1. 球面位置编码(SPE)
球面位置编码将全景特征图中的极坐标位置映射到高维空间,以便在全景分支和透视分支之间传递位置信息。
import torch
import torch.nn.functional as F
def spherical_positional_encoding(pos_enc_dim, pos):
"""
pos_enc_dim: 编码维度
pos: 极坐标位置 (θ, φ)
"""
th, ph = pos
enc = torch.cat([torch.sin(2 * torch.pi * th / pos_enc_dim), torch.cos(2 * torch.pi * th / pos_enc_dim)], dim=-1)
enc = torch.cat([enc, torch.sin(2 * torch.pi * ph / pos_enc_dim), torch.cos(2 * torch.pi * ph / pos_enc_dim)], dim=-1)
return enc
# 假设pos_enc_dim为64,pos为极坐标位置
pos_enc_dim = 64
pos = torch.tensor([0.5, 0.3]) # 示例极坐标位置
spe = spherical_positional_encoding(pos_enc_dim, pos)
2. EPP注意力掩码
EPP注意力掩码用于增强全景特征图和透视特征图之间的对应关系,通过高斯核平滑二进制掩码来实现。
def gaussian_kernel(size, sigma=1.0):
"""生成高斯核"""
x = torch.arange(size, dtype=torch.float32)
x -= size // 2
x = x / sigma
x = torch.exp(-x ** 2 / (2 * sigma ** 2))
return x / x.sum()
def create_epp_attention_mask(pano_size, pers_size, fov):
"""
pano_size: 全景特征图大小
pers_size: 透视特征图大小
fov: 视场角
"""
# 创建全景和透视特征图的坐标网格
pano_coords = torch.stack(torch.meshgrid(torch.linspace(-1, 1, pano_size[0]), torch.linspace(-1, 1, pano_size[1])), dim=-1)
pers_coords = torch.stack(torch.meshgrid(torch.linspace(-1, 1, pers_size[0]), torch.linspace(-1, 1, pers_size[1])), dim=-1)
# 计算全景和透视特征图之间的对应关系
mask = torch.zeros(pano_size[0], pano_size[1], pers_size[0], pers_size[1])
for i in range(pers_size[0]):
for j in range(pers_size[1]):
# 将透视坐标转换为全景坐标
pano_x, pano_y = (i / (pers_size[0] - 1) * 2 - 1) * fov, (j / (pers_size[1] - 1) * 2 - 1) * fov
pano_x, pano_y = pano_x * pano_size[0] / 2, pano_y * pano_size[1] / 2
# 计算高斯掩码
kernel = gaussian_kernel(pano_size[0], sigma=pano_size[0] / 6)
mask[:, :, i, j] = kernel[int(pano_y):int(pano_y + 1), int(pano_x):int(pano_x + 1)].sum(dim=-1).sum(dim=-1)
return mask
pano_size = (512, 1024) # 全景特征图大小
pers_size = (256, 256) # 透视特征图大小
fov = 90 # 视场角
epp_mask = create_epp_attention_mask(pano_size, pers_size, fov)
3. EPP注意力模块
EPP注意力模块结合了SPE和EPP注意力掩码,以实现全景分支和透视分支之间的信息传递。
class EPPAttention(torch.nn.Module):
def __init__(self, channel_dim, pos_enc_dim):
super(EPPAttention, self).__init__()
self.query_linear = torch.nn.Linear(channel_dim, channel_dim)
self.key_linear = torch.nn.Linear(channel_dim, channel_dim)
self.value_linear = torch.nn.Linear(channel_dim, channel_dim)
self.pos_enc_dim = pos_enc_dim
def forward(self, pano_feat, pers_feat, epp_mask):
"""
pano_feat: 全景特征图
pers_feat: 透视特征图
epp_mask: EPP注意力掩码
"""
# 计算查询(Q)、键(K)和值(V)
Q = self.query_linear(pano_feat).view(-1, pano_feat.size(1), pano_feat.size(2) * pano_feat.size(3))
K = self.key_linear(pers_feat).view(-1, pers_feat.size(1), pers_feat.size(2) * pers_feat.size(3))
V = self.value_linear(pers_feat).view(-1, pers_feat.size(1), pers_feat.size(2) * pers_feat.size(3))
# 计算注意力分数
scores = torch.matmul(Q, K.transpose(-1, -2))
scores = scores / math.sqrt(self.pos_enc_dim)
scores = scores + epp_mask
# 应用softmax函数
attn = F.softmax(scores, dim=-1)
# 计算输出
output = torch.matmul(attn, V)
output = output.view(-1, pano_feat.size(1), pano_feat.size(2), pano_feat.size(3))
return output
# 假设channel_dim为128,pos_enc_dim为64
channel_dim = 128
pos_enc_dim = 64
epp_attn = EPPAttention(channel_dim, pos_enc_dim)
# 假设pano_feat和pers_feat是输入的特征图
pano_feat = torch.randn(1, channel_dim, 512, 1024) # 全景特征图
pers_feat = torch.randn(1, channel_dim, 256, 256) # 透视特征图
output = epp_attn(pano_feat, pers_feat, epp_mask)
以上代码展示了EPPA机制的核心组成部分,包括球面位置编码、EPP注意力掩码和EPP注意力模块。这些组件共同实现了全景分支和透视分支之间的有效信息传递,从而提高了全景图像的生成质量和一致性。
文章来源于互联网:《PanFusion:Taming Stable Diffusion for Text to 360 Panorama Image Generation》学习——双分支全景图像扩散生成
相关推荐: 最新AI写作系统ChatGPT源码/支持GPT4.0+GPT联网提问/支持ai绘画Midjourney+Prompt应用+MJ以图生图+思维导图生成
一、智能创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里…
5bei.cn大模型教程网










