首页 游戏 软件 资讯 排行榜 专题
首页
AI
EDSR图像超分重构

EDSR图像超分重构

热心网友
46
转载
2025-07-17
超分辨率重建通过软件方法从低分辨率图像恢复高分辨率图像,可降低硬件成本,满足多领域需求。常用PSNR、SSIM评价效果。EDSR是较优方法,去除BN层,性能提升,文中还涉及其数据集处理、网络结构及训练测试等内容,效果优于双线性插值。

edsr图像超分重构 - 游乐网

超分辨率重建

意义

客观世界的场景含有丰富多彩的信息,但是由于受到硬件设备的成像条件和成像方式的限制,难以获得原始场景中的所有信息。而且,硬件设备分辨率的限制会不可避免地使图像丢失某些高频细节信息。在当今信息迅猛发展的时代,在卫星遥感、医学影像、多媒体视频等领域中对图像质量的要求越来越高,人们不断寻求更高质量和更高分辨率的图像,来满足日益增长的需求。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

空间分辨率的大小是衡量图像质量的一个重要指标,也是将图像应用到实际生活中重要的参数之一。分辨率越高的图像含有的细节信息越多,图像清晰度越高,在实际应用中对各种目标的识别和判断也更加准确。

但是通过提高硬件性能从而提高图像的分辨率的成本高昂。因此,为了满足对图像分辨率的需求,又不增加硬件成本的前提下,依靠软件方法的图像超分辨率重建应运而生。

超分辨率图像重建是指从一系列有噪声、模糊及欠采样的低分辨率图像序列中恢复出一幅高分辨率图像的过程。可以针对现有成像系统普遍存在分辨率低的缺陷,运用某些算法,提高所获得低分辨率图像的质量。因此,超分辨率重建算法的研究具有广阔的发展空间。

方法的具体细节

评价指标

峰值信噪比

峰值信噪比(Peak Signal-to-Noise Ratio), 是信号的最大功率和信号噪声功率之比,来测量被压缩的重构图像的质量,通常以分贝来表示。PSNR指标值越高,说明图像质量越好。

SSIM计算公式如下:

PSNR=10lgMAXI2MSEPSNR=10∗lgMSEMAXI2

MSEMSE表示两个图像之间对应像素之间差值平方的均值。

MAXIMAXI 表示图像中像素的最大值。对于8bit图像,一般取255。

MSE=1MNi=1Nj=1M(fijfij)2MSE=M∗N1i=1∑Nj=1∑M(fij−fij′)2

fijfij表示图像XX在ijij处的像素值

fijfij′表示图像YY在ijij处的像素值

结构相似性评价

结构相似性评价(Structural Similarity Index), 是衡量两幅图像相似度的指标,取值范围为0到1。SSIM指标值越大,说明图像失真程度越小,图像质量越好。

SSIM计算公式如下:

L(X,Y)=2μXμY+C1μX2+μY2+C1L(X,Y)=μX2+μY2+C12μXμY+C1

C(X,Y)=2σXσY+C2σX2+σY2+C2C(X,Y)=σX2+σY2+C22σXσY+C2

S(X,Y)=σXY+C3σXσY+C3S(X,Y)=σXσY+C3σXY+C3

SSIM(X,Y)=L(X,Y)C(X,Y)S(X,Y)SSIM(X,Y)=L(X,Y)∗C(X,Y)∗S(X,Y)

这两种方式,一般情况下能较为准确地评价重建效果。但是毕竟人眼的感受是复杂丰富的,所以有时也会出现一定的偏差。

EDSR

EDSR图像超分重构 - 游乐网

SRResNet在SR的工作中引入了残差块,取得了更深层的网络,而EDSR是对SRResNet的一种提升,其最有意义的模型性能提升是去除掉了SRResNet多余的模块(BN层)

EDSR图像超分重构 - 游乐网

EDSR把批规范化处理(batch normalization, BN)操作给去掉了。

论文中说,原始的ResNet最一开始是被提出来解决高层的计算机视觉问题,比如分类和检测,直接把ResNet的结构应用到像超分辨率这样的低层计算机视觉问题,显然不是最优的。由于批规范化层消耗了与它前面的卷积层相同大小的内存,在去掉这一步操作后,相同的计算资源下,EDSR就可以堆叠更多的网络层或者使每层提取更多的特征,从而得到更好的性能表现。EDSR用L1损失函数来优化网络模型。

1.解压数据集

因为训练时间可能不是很长,所以这里用了BSD100,可以自行更换为DIV2K或者coco

In [1]
#  !unzip -o /home/aistudio/data/data121380/DIV2K_train_HR.zip -d train
登录后复制In [2]
# !unzip -o  /home/aistudio/data/data121283/Set5.zip -d test
登录后复制

2.定义dataset

In [3]
import osfrom paddle.io import Datasetfrom paddle.vision import transformsfrom PIL import Imageimport randomimport paddleimport PILimport numbersimport numpy as npfrom PIL import Imagefrom paddle.vision.transforms import BaseTransformfrom paddle.vision.transforms import functional as Fimport matplotlib.pyplot as pltclass SRDataset(Dataset):    def __init__(self, data_path, crop_size, scaling_factor):        """        :参数 data_path: 图片文件夹路径        :参数 crop_size: 高分辨率图像裁剪尺寸  (实际训练时不会用原图进行放大,而是截取原图的一个子块进行放大)        :参数 scaling_factor: 放大比例        """        self.data_path=data_path        self.crop_size = int(crop_size)        self.scaling_factor = int(scaling_factor)        self.images_path=[]        # 如果是训练,则所有图像必须保持固定的分辨率以此保证能够整除放大比例        # 如果是测试,则不需要对图像的长宽作限定        # 读取图像路径        for name in os.listdir(self.data_path):            self.images_path.append(os.path.join(self.data_path,name))        # 数据处理方式        self.pre_trans=transforms.Compose([                                # transforms.CenterCrop(self.crop_size),                                transforms.RandomCrop(self.crop_size),                                transforms.RandomHorizontalFlip(0.5),                                transforms.RandomVerticalFlip(0.5),                                # transforms.ColorJitter(brightness=0.3, contrast=0.3, hue=0.3),                                ])        self.input_transform = transforms.Compose([                                transforms.Resize(self.crop_size//self.scaling_factor),                                transforms.ToTensor(),                                transforms.Normalize(mean=[0.5],std=[0.5]),                                ])        self.target_transform = transforms.Compose([                                transforms.ToTensor(),                                transforms.Normalize(mean=[0.5],std=[0.5]),                                ])    def __getitem__(self, i):        # 读取图像        img = Image.open(self.images_path[i], mode='r')        img = img.convert('RGB')        img=self.pre_trans(img)        lr_img = self.input_transform(img)        hr_img = self.target_transform(img.copy())                return lr_img, hr_img    def __len__(self):        return len(self.images_path)
登录后复制
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/__init__.py:107: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working  from collections import MutableMapping/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/rcsetup.py:20: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working  from collections import Iterable, Mapping/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/colors.py:53: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working  from collections import Sized
登录后复制

测试dataset

In [4]
# 单元测试train_path='train/DIV2K_train_HR'test_path='test'ds=SRDataset(train_path,96,2)l,h=ds[1]# print(type(l))print(l.shape)print(h.shape)l=np.array(l)h=np.array(h)print(type(l))l=l.transpose(2,1,0)h=h.transpose(2,1,0)print(l.shape)print(h.shape)plt.subplot(1, 2, 1)plt.imshow(((l+1)/2))plt.title('l')plt.subplot(1, 2, 2)plt.imshow(((h+1)/2))plt.title('h')plt.show()
登录后复制
W1225 11:33:49.800403  8727 device_context.cc:404] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.0, Runtime API Version: 10.1W1225 11:33:49.804852  8727 device_context.cc:422] device: 0, cuDNN Version: 7.6./opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/tensor/creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations  if data.dtype == np.object:/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/cbook/__init__.py:2349: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working  if isinstance(obj, collections.Iterator):/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/cbook/__init__.py:2366: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working  return list(data) if isinstance(data, collections.MappingView) else data
登录后复制
[3, 48, 48][3, 96, 96](48, 48, 3)(96, 96, 3)
登录后复制
登录后复制

定义网络结构

较rsresnet少了归一化层,以及更深的残差块

In [5]
from paddle.nn import Layerfrom paddle import nnimport mathn_feat = 256kernel_size = 3# 残差块 尺寸不变class _Res_Block(nn.Layer):    def __init__(self):        super(_Res_Block, self).__init__()        self.res_conv = nn.Conv2D(n_feat, n_feat, kernel_size, padding=1)        self.relu = nn.ReLU()    def forward(self, x):        y = self.relu(self.res_conv(x))        y = self.res_conv(y)        y *= 0.1        # 残差加入        y = paddle.add(y, x)        return yclass EDSR(nn.Layer):    def __init__(self):        super(EDSR, self).__init__()        in_ch = 3        num_blocks = 32        self.conv1 = nn.Conv2D(in_ch, n_feat, kernel_size, padding=1)        # 扩大        self.conv_up = nn.Conv2D(n_feat, n_feat * 4, kernel_size, padding=1)        self.conv_out = nn.Conv2D(n_feat, in_ch, kernel_size, padding=1)        self.body = self.make_layer(_Res_Block, num_blocks)        # 上采样        self.upsample = nn.Sequential(self.conv_up, nn.PixelShuffle(2))    # 32个残差块    def make_layer(self, block, layers):        res_block = []        for _ in range(layers):            res_block.append(block())        return nn.Sequential(*res_block)    def forward(self, x):        out = self.conv1(x)        out = self.body(out)        out = self.upsample(out)        out = self.conv_out(out)        return out
登录后复制

看paddle能不能用gpu

In [6]
import paddleprint(paddle.device.get_device())
登录后复制
gpu:0
登录后复制In [7]
paddle.device.set_device('gpu:0')
登录后复制
CUDAPlace(0)
登录后复制

训练,一般4个小时就可以达到一个不错的效果,set5中psnr可以达到27左右,当然这时间还是太少了

In [ ]
import osfrom math import log10from paddle.io import DataLoaderimport paddle.fluid as fluidimport warningsfrom paddle.static import InputSpecif __name__ == '__main__':    warnings.filterwarnings("ignore", category=Warning)  # 过滤报警信息    train_path='train/DIV2K_train_HR'    test_path='test'    crop_size = 96      # 高分辨率图像裁剪尺寸    scaling_factor = 2  # 放大比例    # 学习参数    checkpoint = './work/edsr_paddle'   # 预训练模型路径,如果不存在则为None    batch_size = 30    # 批大小    start_epoch = 0     # 轮数起始位置    epochs = 10000        # 迭代轮数    workers = 4         # 工作线程数    lr = 1e-4           # 学习率    # 先前的psnr    pre_psnr=32.35    try:        model = paddle.jit.load(checkpoint)        print('加载先前模型成功')    except:        print('未加载原有模型训练')        model = EDSR()    # 初始化优化器    scheduler = paddle.optimizer.lr.StepDecay(learning_rate=lr, step_size=1, gamma=0.99, verbose=True)    optimizer = paddle.optimizer.Adam(learning_rate=scheduler,                                    parameters=model.parameters())    criterion = nn.MSELoss()    train_dataset = SRDataset(train_path, crop_size, scaling_factor)    test_dataset = SRDataset(test_path, crop_size, scaling_factor)    train_loader = DataLoader(train_dataset,        batch_size=batch_size,        shuffle=True,        num_workers=workers,        )    test_loader = DataLoader(test_dataset,        batch_size=batch_size,        shuffle=False,        num_workers=workers,        )    for epoch in range(start_epoch, epochs+1):        model.train()  # 训练模式:允许使用批样本归一化        train_loss=0        n_iter_train = len(train_loader)        train_psnr=0        # 按批处理        for i, (lr_imgs, hr_imgs) in enumerate(train_loader):            lr_imgs = lr_imgs            hr_imgs = hr_imgs            sr_imgs = model(lr_imgs)            loss = criterion(sr_imgs, hr_imgs)              optimizer.clear_grad()            loss.backward()            optimizer.step()            train_loss+=loss.item()            psnr = 10 * log10(1 / loss.item())            train_psnr+=psnr        epoch_loss_train=train_loss / n_iter_train        train_psnr=train_psnr/n_iter_train        print(f"Epoch {epoch}. Training loss: {epoch_loss_train} Train psnr {train_psnr}DB")        model.eval()  # 测试模式        test_loss=0        all_psnr = 0        n_iter_test = len(test_loader)        with paddle.no_grad():            for i, (lr_imgs, hr_imgs) in enumerate(test_loader):                lr_imgs = lr_imgs                hr_imgs = hr_imgs                sr_imgs = model(lr_imgs)                loss = criterion(sr_imgs, hr_imgs)                psnr = 10 * log10(1 / loss.item())                all_psnr+=psnr                test_loss+=loss.item()                epoch_loss_test=test_loss/n_iter_test        epoch_psnr=all_psnr / n_iter_test        print(f"Epoch {epoch}. Testing loss: {epoch_loss_test} Test psnr{epoch_psnr} dB")        if epoch_psnr>pre_psnr:            paddle.jit.save(model, checkpoint,input_spec=[InputSpec(shape=[1,3,48,48], dtype='float32')])            pre_psnr=epoch_psnr            print('模型更新成功')        scheduler.step()
登录后复制
加载先前模型成功Epoch 0: StepDecay set learning rate to 0.0001.
登录后复制

测试,需要自己上传一张低分辨率的图片

In [ ]
import paddlefrom paddle.vision import transformsimport PIL.Image as Imageimport numpy as npimgO=Image.open('img_003_SRF_2_LR.webp',mode="r")  #选择自己图片的路径img=transforms.ToTensor()(imgO).unsqueeze(0)#导入模型net=paddle.jit.load("./work/edsr_paddle")source = net(img)[0, :, :, :]source = source.cpu().detach().numpy()  # 转为numpysource = source.transpose((1, 2, 0))  # 切换形状source = np.clip(source, 0, 1)  # 修正图片img = Image.fromarray(np.uint8(source * 255))plt.figure(figsize=(9,9))plt.subplot(1, 2, 1)plt.imshow(imgO)plt.title('input')plt.subplot(1, 2, 2)plt.imshow(img)plt.title('output')plt.show()img.save('./sr.webp')
登录后复制

EDSR_X2效果

双线性插值放大效果

EDSR图像超分重构 - 游乐网

EDSR_X2放大效果

EDSR图像超分重构 - 游乐网

双线性插值放大效果

EDSR图像超分重构 - 游乐网

EDSR_X2放大效果

EDSR图像超分重构 - 游乐网

In [ ]

登录后复制
来源:https://www.php.cn/faq/1412640.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

Pywinrm,一个 Python 管理利器!
科技数码
Pywinrm,一个 Python 管理利器!

Pywinrm 通过Windows远程管理(WinRM)协议,让Python能够像操作本地一样执行远程Windows命令,真正打通了跨平台管理的最后一公里。 在混合IT环境中,Linux机器管理Wi

热心网友
04.07
全网炸了!5亿人用的Axios竟被投毒,你的密钥还保得住吗?
科技数码
全网炸了!5亿人用的Axios竟被投毒,你的密钥还保得住吗?

早些时候,聊过 Python 领域那场惊心动魄的供应链攻击。当时我就感叹,虽然我们 JavaScript 开发者对这类套路烂熟于心,但亲眼目睹这种规模的“投毒”还是头一次。 早些时候,聊过 Pyth

热心网友
04.07
Toga,一个超精简的 Python 项目!
科技数码
Toga,一个超精简的 Python 项目!

Toga 是 BeeWare 家族的核心成员,号称“写一次,跑遍所有平台”,而且用的是系统原生控件,不是那种一看就是网页套壳的界面 。 写了这么多年 Python,你是不是也想过:要是能一套代码跑

热心网友
04.07
Python 异常处理:别再用裸奔的 try 了
科技数码
Python 异常处理:别再用裸奔的 try 了

异常处理的核心:让错误在正确的地方被有效处理。正确的地方,就是别在底层就把异常吞了,也别在顶层还抛裸奔的 Exception。 异常处理写得好,半夜不用起来改 bug。1 你是不是也这么干过?tr

热心网友
04.07
OpenClaw如何自定义SKILL
AI
OpenClaw如何自定义SKILL

1 Skills机制概述 提起OpenClaw的Skills机制,不少人可能会把它想象成传统意义上的可执行插件。其实,它的内涵要更精妙一些。 简单说,Skills本质上是一套基于提示驱动的能力扩展机制。它并不是一个可以独立“跑”起来的程序模块,而是通过一份结构化描述文件(核心就是那个SKILL m

热心网友
04.07

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

美国SEC主席Paul Atkins证实:加密货币安全港提案已送交白宫审查
web3.0
美国SEC主席Paul Atkins证实:加密货币安全港提案已送交白宫审查

加密货币行业翘首以盼的监管里程碑,终于有了实质性进展。美国证券交易委员会(SEC)主席保罗·阿特金斯(Paul Atkins)近日证实,那份允许加密项目在早期获得注册豁免权的“安全港”框架提案,已经正式送抵白宫,进入了最终审查阶段。 在范德堡大学与区块链协会联合举办的数字资产峰会上,阿特金斯透露了这

热心网友
04.08
微策略Strategy报告:第一季录得144.6亿美元浮亏 再斥资约3.3亿美元买进4871枚比特币
web3.0
微策略Strategy报告:第一季录得144.6亿美元浮亏 再斥资约3.3亿美元买进4871枚比特币

微策略Strategy报告:第一季录得144 6亿美元浮亏 再斥资约3 3亿美元买进4871枚比特币 市场震荡的威力有多大?看看Strategy的最新季报就明白了。根据其最新向美国证管会(SEC)提交的8-K报告,受市场剧烈波动影响,这家公司所持的比特币在第一季度录得了一笔惊人的数字——144 6亿

热心网友
04.08
稳定币发行商Tether再扩Web3版图!Paolo Ardoino:正开发去中心化搜索引擎Hypersearch
web3.0
稳定币发行商Tether再扩Web3版图!Paolo Ardoino:正开发去中心化搜索引擎Hypersearch

稳定币巨头Tether的动向,向来是加密世界的风向标。这不,它向Web3基础设施的版图扩张,又迈出了关键一步。公司执行长Paolo Ardoino在社交平台X上透露,其工程团队正在全力“烹制”一个新项目——去中心化搜索引擎 “Hypersearch”。这个消息一出,立刻引发了行业的广泛猜想。 采用D

热心网友
04.08
Base链首个原生DeFi借贷协议Seamless Protocol倒闭 将于2026年6月30日下线
web3.0
Base链首个原生DeFi借贷协议Seamless Protocol倒闭 将于2026年6月30日下线

基地位于Coinbase旗下以太坊Layer2网络Base的Seamless Protocol,日前正式宣告了服务的终结。这个曾经吸引了超过20万用户的原生DeFi借贷协议,在运营不到三年后,终究没能跑赢时间。它主打的核心产品是Integrated Leverage Markets(ILMs)——一

热心网友
04.08
PAAL代币如何参与治理?社区投票能决定哪些事项?
web3.0
PAAL代币如何参与治理?社区投票能决定哪些事项?

PAAL代币揭秘:深度解析Web3社区治理的核心钥匙 在去中心化自治组织的浪潮中,谁真正掌握了项目的话语权?PAAL代币提供了一套系统化的答案。它不仅是生态内流转的价值媒介,更是开启链上治理大门的核心凭证。通过持有并质押PAAL代币,用户能够对协议升级、资金分配乃至战略方向等关键事务投出决定性的一票

热心网友
04.08