《SDNet: A Versatile Squeeze-and-Decomposition Network for Real-Time Image Fusion》阅读笔记

每一层的通道个数?
如何训练?每一类任务提供一组图片,使用这组图片进行训练

Abstract
提出了一种压缩分解网络(SDNet)
可以实时实现多模态和数字摄影图像融合
将多个融合问题转化为梯度和强度信息的提取和重建
设计了一个由强度项和梯度项组成的通用损失函数形式
梯度项
自适应决策,根据纹理丰富度来确定梯度分布,引导融合后的图像包含更丰富的纹理细节。
强度项
调整每个强度损失项的权重,以改变来自不同图像的强度信息的比例,使其能够适应多个图像融合任务。
压缩解压思想
考虑了:源图像->融合结果,融合结果->源图像
迫使结果包含更多细节
实验结果表明,我们的方法更好更快

1 Introduction
单个图像只能捕捉到部分细节
通常,图像融合场景可以根据源图像成像的差异分为两类:
多模态图像融合。单个对象多个传感器进行观测。
数码摄影的图像融合。单个传感器不同拍摄设置下的图像

解决图像融合问题的方法大致分为两类
传统方法:设计空间域或变换域的活动水平测量和融合规则来实现融合
深度学习:构造一个目标函数来约束融合的图像,使其具有期望的分布特征

传统方法需要手动设计融合规则
深度学习图像融合的障碍是缺少监督图像

我们的设计主要是从两个方面
一方面,将图像融合建模为强度和梯度信息的提取和重建。
图像中包含的信息可以分为梯度信息和强度信息,其中梯度信息表示纹理结构,而强度信息表示图像的整体亮度分布。
设计了一个损失函数,迫使网络提取梯度和强度信息,并通过两种不同的规则进行融合。
梯度信息
除了噪声外具有强梯度的区域有大量的纹理
自适应决策块,首先用滤波器来减少噪声,然后评价每个像素的梯度,从而指导融合图像
强度信息
调整权重比例选择了更有效的信息保存到融合结果中

另一方面,我们提出了一种快速的SDNet来实现更有效的图像融合。
之前的方法只考虑了从源图像到融合结果的挤压过程
设计了一个压缩和分解网络,它包含压缩和分解两部分。

SDNet优点:
不需要设计融合规则
不需要监督,是弱约束的无监督
控制特征数量,参数少、速度快

贡献:
新的融合模型
新的损失函数
自适应决策块(针对梯度损失项的) -> 降低噪声的影响,引导结果包含更多纹理
压缩分解网络 -> 使融合结果包含更多的场景细节。
实时实现多种融合任务

新贡献:
自适应决策块(约束梯度信息):不用手动设置、效果更好
不仅考虑了融合过程,还考虑了分解过程。

3 Method
3.1 Overall Framework
不同任务,有意义信息的标准不同

有意义的信息:
强度信息:像素强度,亮度分布,反映图像的对比度特征
梯度信息:像素间差异,纹理细节
通用损失函数
由梯度损失项和强度损失项组成
强度损失和梯度损失是图像融合任务中较常见
梯度信息重建:引入了一个作用于梯度损失项的自适应决策块
自适应决策块
高斯低通滤波 -> 去噪
梯度丰富度 -> 像素重要性
生成像素尺度决策图(用来引导融合图像纹理近似源像素)
融合图像与相应区域中最强纹理相一致
不同任务需要设置不同的强度损失目的权重比

压缩和分解的思想 -> 尽可能保留尽可能多的信息
SDNet=挤压网络+分解网络
SDNet与自动编码器网络:
不同:SDNet的中间结果是融合的图像,自动编码器网络的中间结果是编码向量
相同:都需要中间结果包含更多的内容

3.2 Loss Functions
SDNet损失函数包括两部分:
压缩融合损失L(sf)
分解一致性损失L(dc)
L=L(sf)+L(dc)

3.2.1 Squeeze Fusion Loss
挤压融合损失Lsf决定了提取的信息类型以及重建中各种类型信息之间的主要和次要关系。
梯度信息和强度信息 -> 梯度损失项和强度损失项
L(sf)=b*L(grad)+L(int)

梯度损失迫使融合的图像包含丰富的纹理细节。
我们在梯度损失项中引入一个自适应决策块,引导融合图像的纹理与源图像对应位置的最强纹理保持一致,定义为:

在Goshtasby(2005)中也提到了类似的选择决策的概念:
G中权值函数是在块尺度上,而所提出的自适应决策块是在像素尺度上
G中的权值函数是基于信息熵的,对噪声没有鲁棒性,噪声大会导致权重大
将G中的权值函数直接应用于源图像,本质上是线性映射。本文的是非线性映射。

因为不同的图像融合任务对融合图像的强度分布有不同的倾向要求。
我们采用比例设置策略来调整α,以满足不同类型的融合任务的强度分布要求。
α的比例设置策略与图像融合的类型有关。

挤压网络的目的是将源图像融合成一个包含更丰富的纹理内容的单个图像。
由于pseudo-siamese网络非常擅长处理差异较大的数据,因此我们参照pseudo-siamese网络设计了挤压网络,以实现各种图像融合任务。
同时,由于卷积过程中填充导致信息丢失,我们使用DenseNet等密集连接来减少信息丢失,最大限度地利用信息。
在每条路径中:
四个卷积层。
第一层使用5×5卷积核,后三层使用3×3卷积核
ReLU激活函数。
然后,我们融合了从这两条路径中提取的特征,并使用连接和卷积的策略来实现这一目的。
我们沿着通道将这两个特征映射连接起来。最后一个卷积层的核大小为1×1,激活函数为tanh。

4.1.2 Training Details
灰度图像之间:
所提出的模型可以直接用于融合源图像生成融合结果。
灰度图像和彩色图像:
首先将彩色图像从RGB转换为YCbCr颜色空间。
亮度通道:
由于Y通道(亮度通道)可以表示结构细节和亮度变化,因此我们致力于将彩色源图像的Y通道与灰度源图像进行融合。
然后,我们直接将彩色源图像的Cb通道和Cr通道与融合的Y通道相连接,并将这些分量转移到RGB空间,得到最终结果。
彩色图像之间:
我们将所有彩色源图像从RGB转换为YCbCr颜色空间
我们利用所提出的模型融合源图像的Y通道,并遵循等式用(12)来融合源图像的Cb或Cr通道

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的用PyTorch写SD点云深度学习代码的例子: ```python import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader import numpy as np # 定义数据集 class SDDataset(Dataset): def __init__(self, data_path): self.data = np.load(data_path) def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] # 定义模型 class SDNet(nn.Module): def __init__(self): super(SDNet, self).__init__() self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1) self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1) self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv3 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2) self.fc1 = nn.Linear(64 * 6 * 6, 512) self.fc2 = nn.Linear(512, 10) def forward(self, x): x = self.conv1(x) x = nn.functional.relu(x) x = self.pool1(x) x = self.conv2(x) x = nn.functional.relu(x) x = self.pool2(x) x = self.conv3(x) x = nn.functional.relu(x) x = self.pool3(x) x = x.view(-1, 64 * 6 * 6) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return x # 训练代码 def train(model, train_loader, criterion, optimizer, device): model.train() train_loss = 0 for batch_idx, data in enumerate(train_loader): inputs = data[:, :, :, :3] targets = data[:, :, :, 3] inputs = inputs.to(device) targets = targets.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() train_loss += loss.item() return train_loss / len(train_loader) # 测试代码 def test(model, test_loader, criterion, device): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data in test_loader: inputs = data[:, :, :, :3] targets = data[:, :, :, 3] inputs = inputs.to(device) targets = targets.to(device) outputs = model(inputs) test_loss += criterion(outputs, targets).item() preds = outputs.argmax(dim=1) correct += preds.eq(targets.view_as(preds)).sum().item() test_loss /= len(test_loader.dataset) accuracy = correct / len(test_loader.dataset) return test_loss, accuracy # 主函数 def main(): # 设置超参数 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") epochs = 10 batch_size = 64 learning_rate = 0.001 data_path = "sd_data.npy" # 加载数据集 dataset = SDDataset(data_path) train_dataset, test_dataset = torch.utils.data.random_split(dataset, [8000, 2000]) train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True) # 初始化模型、损失函数和优化器 model = SDNet().to(device) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) # 训练和测试模型 for epoch in range(1, epochs + 1): train_loss = train(model, train_loader, criterion, optimizer, device) test_loss, accuracy = test(model, test_loader, criterion, device) print("Epoch {}: Train Loss: {:.4f}, Test Loss: {:.4f}, Accuracy: {:.2f}%".format(epoch, train_loss, test_loss, accuracy * 100)) if __name__ == '__main__': main() ``` 上述代码中,我们定义了一个 `SDDataset` 类来加载 SD 点云数据集,定义了一个 `SDNet` 类来实现 SD 点云的深度学习模型。我们使用 PyTorch 自带的 DataLoader 类来加载训练和测试数据集,并使用 Adam 优化器来训练模型。最后,我们使用 `train` 函数来训练模型,使用 `test` 函数来测试模型,并在主函数中执行训练和测试过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值