基于Swin_Transformer的圖像超分辨率系統

1.研究背景與意義

項目參考AAAI Association for the Advancement of Artificial Intelligence

研究背景與意義

隨著科技的不斷發展,圖像超分辨率技術在計算機視覺領域中變得越來越重要。圖像超分辨率是指通過使用計算機算法將低分辨率圖像轉換為高分辨率圖像的過程。這項技術在許多領域都有廣泛的應用,包括醫學圖像處理、監控攝像頭、衛星圖像處理等。

在過去的幾十年里,圖像超分辨率技術已經取得了顯著的進展。早期的方法主要基于插值和濾波技術,但這些方法無法捕捉到圖像中的細節和紋理。隨著深度學習的興起,基于深度學習的圖像超分辨率方法開始受到關注。其中,基于卷積神經網絡(CNN)的方法取得了很大的成功。

然而,傳統的CNN方法在處理大尺寸圖像時存在一些問題。首先,它們需要大量的計算資源和存儲空間,限制了它們在實際應用中的可行性。其次,它們往往無法處理大尺寸圖像中的細節和紋理,導致生成的高分辨率圖像質量不佳。因此,尋找一種高效且準確的圖像超分辨率方法是非常重要的。

近年來,Swin Transformer作為一種新興的注意力機制模型,已經在自然語言處理和計算機視覺領域取得了顯著的成果。Swin Transformer采用了一種分層的注意力機制,能夠在處理大尺寸圖像時保持較高的效率和準確性。因此,將Swin Transformer應用于圖像超分辨率任務是非常有前景的研究方向。

基于Swin Transformer的圖像超分辨率系統具有以下幾個重要的意義:

首先,基于Swin Transformer的圖像超分辨率系統可以提供更高質量的高分辨率圖像。Swin Transformer的注意力機制能夠更好地捕捉到圖像中的細節和紋理,從而生成更加真實和清晰的圖像。這對于許多應用領域,如醫學圖像處理和衛星圖像處理,具有重要的意義。

其次,基于Swin Transformer的圖像超分辨率系統可以提高計算效率。傳統的CNN方法在處理大尺寸圖像時需要大量的計算資源和存儲空間,限制了它們在實際應用中的可行性。而Swin Transformer采用了一種分層的注意力機制,能夠在處理大尺寸圖像時保持較高的效率和準確性,從而降低了計算成本。

最后,基于Swin Transformer的圖像超分辨率系統可以為其他相關領域的研究提供借鑒和參考。Swin Transformer作為一種新興的注意力機制模型,已經在自然語言處理和計算機視覺領域取得了顯著的成果。將其應用于圖像超分辨率任務可以為其他領域的研究提供新的思路和方法。

綜上所述,基于Swin Transformer的圖像超分辨率系統具有重要的研究背景和意義。它可以提供更高質量的高分辨率圖像,提高計算效率,并為其他相關領域的研究提供借鑒和參考。隨著深度學習和注意力機制的不斷發展,相信基于Swin Transformer的圖像超分辨率系統將在未來取得更加廣泛的應用和研究進展。

2.圖片演示

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

3.視頻演示

基于Swin_Transformer的圖像超分辨率系統_嗶哩嗶哩_bilibili

4.圖像超分辨重建原理

為了對圖像超分辨率重建原理有更深入的理解,本小節將對高分辨率圖像到低分辨率的退化過程進行詳細介紹。受硬件設備的限制、環境因素的干擾和傳輸條件的限制,人們采集所得的實際圖像的分辨率往往很難達到預期,而這些低分辨率圖像通常由高分辨率圖像經過多種退化過程所產生,包括光線干擾、運動模糊、噪聲、壓縮等退化因素。由于圖像超分辨率重建是一個典型的逆向問題,其核心概念是建立對應的退化模型來學習從高分辨率圖像到低分辨率圖像的退化關系,進一步恢復低分辨率圖像的紋理細節,因此,建立合適的退化模型是解決超分辨率重建問題的關鍵。
在這里插入圖片描述

通過對上述圖像退化模型的分析,可知通常的圖像退化過程可以描述為高分辨率圖像歷經一系列的退化因素的影響,產生模糊甚至失真的低分辨率圖像。假設x為原始高分辨率圖像,J為退化后的低分辨率圖像,則圖像退化模型可以表示為:
在這里插入圖片描述

其中,H()表示整個退化過程,D()表示下采樣操作,B()表示模糊操作,L()表示光線干擾,n表示隨機噪聲,一般為高斯噪聲或泊松噪聲。圖像超分辨率重建的本質就是從歲反向求解x的過程,如式所示:
在這里插入圖片描述

即構造相應的圖像恢復函數H-(-),對低分辨率圖像y進行逆向推算,去除由于軟硬件技術、環境因素和人為因素所帶來的模糊、下采樣和噪聲等影響,盡可能恢復出原始高分辨率圖像x。

5.核心代碼講解

5.1 main_test_swin2sr.py

class Swin2SR:def __init__(self, args):self.args = argsself.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')self.model = self.define_model()self.model.eval()self.model = self.model.to(self.device)self.test_results = OrderedDict()self.test_results['psnr'] = []self.test_results['ssim'] = []self.test_results['psnr_y'] = []self.test_results['ssim_y'] = []self.test_results['psnrb'] = []self.test_results['psnrb_y'] = []self.psnr, self.ssim, self.psnr_y, self.ssim_y, self.psnrb, self.psnrb_y = 0, 0, 0, 0, 0, 0def define_model(self):# 001 classical image srif self.args.task == 'classical_sr':model = net(upscale=self.args.scale, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': self.args.scale})# 002 lightweight image srelif self.args.task == 'lightweight_sr':model = net(upscale=self.args.scale, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=48, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': self.args.scale})# 003 real image srelif self.args.task == 'real_sr':if self.args.large_model:model = net(upscale=self.args.scale, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=96, depths=[2, 2, 18, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': self.args.scale})else:model = net(upscale=self.args.scale, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=48, depths=[2, 2, 18, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': self.args.scale})# 004 grayscale denoisingelif self.args.task == 'gray_dn':model = net(upscale=1, in_chans=1, img_size=self.args.training_patch_size, window_size=8,num_classes=1, embed_dim=48, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': 1})# 005 color denoisingelif self.args.task == 'color_dn':model = net(upscale=1, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=48, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': 1})# 006 jpeg compression artifact reductionelif self.args.task == 'jpeg_car':model = net(upscale=1, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=48, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': 1})# 007 color jpeg compression artifact reductionelif self.args.task == 'color_jpeg_car':model = net(upscale=1, in_chans=3, img_size=self.args.training_patch_size, window_size=8,num_classes=3, embed_dim=48, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24],mlp_ratio=4, upsampler='pixelshuffle', upsampler_params={'scale': 1})else:raise NotImplementedError(f'Task [{self.args.task}] is not implemented.')return modeldef setup(self):folder, save_dir, border, window_size = self.args.folder_lq, './outputs/', 0, self.args.training_patch_sizereturn folder, save_dir, border, window_sizedef get_image_pair(self, path):imgname = os.path.splitext(os.path.basename(path))[0]img_lq = cv2.imread(path, cv2.IMREAD_UNCHANGED)img_gt = Noneif self.args.folder_gt is not None:img_gt = cv2.imread(os.path.join(self.args.folder_gt, f'{imgname}.png'), cv2.IMREAD_UNCHANGED)return imgname, img_lq, img_gtdef test(self, img_lq, model, args, window_size):_, _, h_old, w_old = img_lq.size()h_pad = (h_old // window_size + 1) * window_size - h_oldw_pad = (w_old // window_size + 1) * window_size - w_oldimg_lq = torch.cat([img_lq, torch.flip(img_lq, [2])], 2)[:, :, :h_old + h_pad, :]img_lq = torch.cat([img_lq, torch.flip(img_lq, [3])], 3)[:, :, :, :w_old + w_pad]output = model(img_lq)if args.task == 'compressed_sr':output = output[0][..., :h_old * args.scale, :w_old * args.scale]else:output = output[..., :h_old * args.scale, :w_old * args.scale]return outputdef evaluate(self, output, img_gt, border):output = output.data.squeeze().float().cpu().clamp_(0, 1).numpy()if output.ndim == 3:output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))  # CHW-RGB to HCW-BGRoutput = (output * 255.0).round().astype(np.uint8)  # float32 to uint8cv2.imwrite(f'{save_dir}/{imgname}_Swin2SR.png', output)if img_gt is not None:img_gt = (img_gt * 255.0).round().astype(np.uint8)  # float32 to uint8img_gt = img_gt[:h_old * args.scale, :w_old * args.scale, ...]  # crop gtimg_gt = np.squeeze(img_gt)psnr = util.calculate_psnr(output, img_gt, crop_border=border)ssim = util.calculate_ssim(output, img_gt, crop_border=border)self.test_results['psnr'].append(psnr)self.test_results['ssim'].append(ssim)if img_gt.ndim == 3:  # RGB imagepsnr_y = util.calculate_psnr(output, img_gt, crop_border=border, test_y_channel=True)ssim_y = util.calculate_ssim(output, img_gt, crop_border=border, test_y_channel=True)self.test_results['psnr_y'].append(psnr_y)self.test_results['ssim_y'].append(ssim_y)if args.task in ['jpeg_car', 'color_jpeg_car']:psnrb = util.calculate_psnrb(output, img_gt, crop_border=border, test_y_channel=False)self.test_results['psnrb'].append(psnrb)if args.task in ['color_jpeg_car']:psnrb_y = util.calculate_psnrb(output, img_gt, crop_border=border, test_y_channel=True)self.test_results['psnrb_y'].append(psnrb_y)print('Testing {:d} {:20s} - PSNR: {:.2f} dB; SSIM: {:.4f}; PSNRB: {:.2f} dB;'

該程序文件是一個用于圖像超分辨率重建的測試程序。程序首先通過命令行參數解析器解析輸入參數,包括任務類型、尺度因子、噪聲水平、JPEG壓縮因子等。然后加載模型并設置設備。接下來,程序設置文件夾和路徑,并創建一個用于保存結果的文件夾。然后,程序遍歷輸入文件夾中的所有圖像,讀取圖像并進行預處理。然后,程序使用模型對圖像進行推理,并將結果保存為圖像文件。最后,程序計算并打印出PSNR和SSIM等評估指標的平均值。

該程序文件依賴于其他模塊和函數,包括argparse、cv2、glob、numpy、collections、os、torch、requests等。其中,models.network_swin2sr模塊定義了Swin2SR模型,utils模塊包含了計算PSNR和SSIM的函數。

總體而言,該程序文件實現了圖像超分辨率重建的測試功能,包括加載模型、預處理圖像、進行推理、保存結果和計算評估指標等步驟。

5.2 predict.py

class Predictor(BasePredictor):def setup(self):"""Load the model into memory to make running multiple predictions efficient"""print("Loading pipeline...")self.device = "cuda:0"args = argparse.Namespace()args.scale = 4args.large_model = Falsetasks = ["classical_sr", "compressed_sr", "real_sr"]paths = ["weights/Swin2SR_ClassicalSR_X4_64.pth","weights/Swin2SR_CompressedSR_X4_48.pth","weights/Swin2SR_RealworldSR_X4_64_BSRGAN_PSNR.pth",]sizes = [64, 48, 128]self.models = {}for task, path, size in zip(tasks, paths, sizes):args.training_patch_size = sizeargs.task, args.model_path = task, pathself.models[task] = define_model(args)self.models[task].eval()self.models[task] = self.models[task].to(self.device)def predict(self,image: Path = Input(description="Input image"),task: str = Input(description="Choose a task",choices=["classical_sr", "real_sr", "compressed_sr"],default="real_sr",),) -> Path:"""Run a single prediction on the model"""model = self.models[task]window_size = 8scale = 4img_lq = cv2.imread(str(image), cv2.IMREAD_COLOR).astype(np.float32) / 255.0img_lq = np.transpose(img_lq if img_lq.shape[2] == 1 else img_lq[:, :, [2, 1, 0]], (2, 0, 1))  # HCW-BGR to CHW-RGBimg_lq = (torch.from_numpy(img_lq).float().unsqueeze(0).to(self.device))  # CHW-RGB to NCHW-RGB# inferencewith torch.no_grad():# pad input image to be a multiple of window_size_, _, h_old, w_old = img_lq.size()h_pad = (h_old // window_size + 1) * window_size - h_oldw_pad = (w_old // window_size + 1) * window_size - w_oldimg_lq = torch.cat([img_lq, torch.flip(img_lq, [2])], 2)[:, :, : h_old + h_pad, :]img_lq = torch.cat([img_lq, torch.flip(img_lq, [3])], 3)[:, :, :, : w_old + w_pad]output = model(img_lq)if task == "compressed_sr":output = output[0][..., : h_old * scale, : w_old * scale]else:output = output[..., : h_old * scale, : w_old * scale]# save imageoutput = output.data.squeeze().float().cpu().clamp_(0, 1).numpy()if output.ndim == 3:output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))  # CHW-RGB to HCW-BGRoutput = (output * 255.0).round().astype(np.uint8)  # float32 to uint8output_path = "/tmp/out.png"cv2.imwrite(output_path, output)return Path(output_path)

這個程序文件是一個用于圖像超分辨率預測的預測器。它使用了Swin2SR模型來進行預測。文件中定義了一個名為Predictor的類,繼承自BasePredictor類。在setup方法中,加載了模型并將其放入內存中以提高多次預測的效率。在predict方法中,通過傳入一個輸入圖像和一個任務類型,可以運行單個預測。預測過程中,首先將輸入圖像進行預處理,然后使用模型進行推理,最后將輸出圖像保存到指定路徑并返回。

5.3 ui.py
class Swin2SR:def __init__(self, args):self.args = argsself.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')self.model = self.define_model()self.model.eval()self.model = self.model.to(self.device)def define_model(self):if self.args.task == 'classical_sr':model = net(upscale=self.args.scale, in_chans=3, img_size=self.args.training_patch_size, window_size=8,img_range=1., depths=[6, 6, 6, 6, 6, 6], embed_dim=180, num_heads=[6, 6, 6, 6, 6, 6],mlp_ratio=2, upsampler='pixelshuffle', resi_connection='1conv')param_key_g = 'params'elif self.args.task in ['lightweight_sr']:model = net(upscale=self.args.scale, in_chans=3, img_size=64, window_size=8,img_range=1., depths=[6, 6, 6, 6], embed_dim=60, num_heads=[6, 6, 6, 6],mlp_ratio=2, upsampler='pixelshuffledirect', resi_connection='1conv')param_key_g = 'params'elif self.args.task == 'compressed_sr':model = net(upscale=self.args.scale, in_chans=3, img_size=self.args.training_patch_size, window_size=8,img_range=1., depths=[6, 6, 6, 6, 6, 6], embed_dim=180, num_heads=[6, 6, 6, 6, 6, 6],mlp_ratio=2, upsampler='pixelshuffle_aux', resi_connection='1conv')param_key_g = 'params'elif self.args.task == 'real_sr':if not self.args.large_model:model = net(upscale=self.args.scale, in_chans=3, img_size=64, window_size=8,img_range=1., depths=[6, 6, 6, 6, 6, 6], embed_dim=180, num_heads=[6, 6, 6, 6, 6, 6],mlp_ratio=2, upsampler='nearest+conv', resi_connection='1conv')else:model = net(upscale=self.args.scale, in_chans=3, img_size=64, window_size=8,img_range=1., depths=[6, 6, 6, 6, 6, 6, 6, 6, 6], embed_dim=240,num_heads=[8, 8, 8, 8, 8, 8, 8, 8, 8],mlp_ratio=2, upsampler='nearest+conv', resi_connection='3conv')param_key_g = 'params_ema'elif self.args.task == 'jpeg_car':model = net(upscale=1, in_chans=1, img_size=126, window_size=7,img_range=255., depths=[6, 6, 6, 6, 6, 6], embed_dim=180, num_heads=[6, 6, 6, 6, 6, 6],mlp_ratio=2, upsampler='', resi_connection='1conv')param_key_g = 'params'elif self.args.task == 'color_jpeg_car':model = net(upscale=1, in_chans=3, img_size=126, window_size=7,img_range=255., depths=[6, 6, 6, 6, 6, 6], embed_dim=180, num_heads=[6, 6, 6, 6, 6, 6],mlp_ratio=2, upsampler='', resi_connection='1conv')param_key_g = 'params'pretrained_model = torch.load(self.args.model_path)model.load_state_dict(pretrained_model[param_key_g] if param_key_g in pretrained_model.keys() else pretrained_model,strict=True)return modeldef setup(self):if self.args.task in ['classical_sr', 'lightweight_sr', 'compressed_sr']:save_dir = f'results/swin2sr_{self.args.task}_x{self.args.scale}'if self.args.save_img_only:folder = self.args.folder_lqelse:folder = self.args.folder_gtborder = self.args.scalewindow_size = 8

ui.py是一個用于圖像超分辨率的PyQt5界面程序。它導入了PyQt5和其他一些必要的庫,并定義了一些函數來加載模型、設置參數、獲取圖像對和進行測試。主要的函數是main()函數,它接受一個圖像路徑作為輸入,并根據指定的參數加載模型并對圖像進行超分辨率處理。處理結果將保存在指定的文件夾中。

5.4 models\network_swin2sr.py
class SwinTransformerBlock(nn.Module):r""" Swin Transformer Block.Args:dim (int): Number of input channels.input_resolution (tuple[int]): Input resulotion.num_heads (int): Number of attention heads.window_size (int): Window size.shift_size (int): Shift size for SW-MSA.mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: Truedrop (float, optional): Dropout rate. Default: 0.0attn_drop (float, optional): Attention dropout rate. Default: 0.0drop_path (float, optional): Stochastic depth rate. Default: 0.0act_layer (nn.Module, optional): Activation layer. Default: nn.GELUnorm_layer (nn.Module, optional): Normalization layer.  Default: nn.LayerNormpretrained_window_size (int): Window size in pre-training."""def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0,mlp_ratio=4., qkv_bias=True, drop=0., attn_drop=0., drop_path=0.,act_layer=nn.GELU, norm_layer=nn.LayerNorm, pretrained_window_size=0):super().__init__()self.dim = dimself.input_resolution = input_resolutionself.num_heads = num_headsself.window_size = window_sizeself.shift_size = shift_sizeself.mlp_ratio = mlp_ratioif min(self.input_resolution) <= self.window_size:# if window size is larger than input resolution, we don't partition windowsself.shift_size = 0self.window_size = min(self.input_resolution)assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size"self.norm1 = norm_layer(dim)self.attn = WindowAttention(dim, window_size=to_2tuple(self.window_size), num_heads=num_heads,qkv_bias=qkv_bias, attn_drop=attn_drop, proj_drop=drop,pretrained_window_size=to_2tuple(pretrained_window_size))self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()self.norm2 = norm_layer(dim)mlp_hidden_dim = int(dim * mlp_ratio)self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)if self.shift_size > 0:attn_mask = self.calculate_mask(self.input_resolution)else:attn_mask = Noneself.register_buffer("attn_mask", attn_mask)def calculate_mask(self, x_size):# calculate attention mask for SW-MSAH, W = x_sizeimg_mask = torch.zeros((1, H, W, 1))  # 1 H W 1h_slices = (slice(0, -self.window_size),slice(-self.window_size, -self.shift_size),slice(-self.shift_size, None))w_slices = (slice(0, -self.window_size),slice(-self.window_size, -self.shift_size),slice(-self.shift_size, None))cnt = 0for h in h_slices:for w in w_slices:img_mask[:, h, w, :] = cntcnt += 1mask_windows = window_partition(img_mask, self.window_size)  # nW, window_size, window_size, 1mask_windows = mask_windows.view(-1, self.window_size * self.window_size)attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0))return attn_maskdef forward(self, x):"""Args:x: input features with shape of (B, N, C)."""B, N, C = x.shapeshortcut = xx = self.norm1(x)x = x.view(B, N, C)if self.shift_size > 0:shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))else:shifted_x = xx = self.attn(x, mask=self.attn_mask)x = shortcut + self.drop_path(x)x = x + self.drop_path(self.mlp(self.norm2(x)))return x

這是一個實現Swin Transformer模型的Python程序文件。Swin Transformer是一種用于壓縮圖像超分辨率和恢復的模型,具體細節可以參考論文https://arxiv.org/abs/2209.11345。

程序文件中定義了一些輔助函數和模塊,包括Mlp、window_partition、window_reverse、WindowAttention和SwinTransformerBlock。

Mlp是一個多層感知機模塊,用于對輸入進行線性變換和激活函數處理。

window_partition和window_reverse函數用于將輸入圖像劃分為窗口,并將窗口恢復為原始圖像。

WindowAttention是一個基于窗口的多頭自注意力模塊,支持相對位置偏置。

SwinTransformerBlock是Swin Transformer的一個基本模塊,包括窗口注意力和多層感知機。

整個程序文件實現了Swin Transformer模型的核心組件,可以用于圖像超分辨率和恢復任務。

5.5 utils\plots.py
class ImageLoader:def __init__(self, debug=False, norm=True, resize=None):self.debug = debugself.norm = normself.resize = resizedef load_img(self, filename):img = cv2.imread(filename)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)if self.norm:   img = img / 255.img = img.astype(np.float32)if self.debug:print (img.shape, img.dtype, img.min(), img.max())if self.resize:img = cv2.resize(img, (self.resize[0], self.resize[1]))return imgdef plot_all(self, images, axis='off', figsize=(16, 8)):fig = plt.figure(figsize=figsize, dpi=80)nplots = len(images)for i in range(nplots):plt.subplot(1,nplots,i+1)plt.axis(axis)plt.imshow(images[i])plt.show()

這個程序文件是一個用于繪制圖像的工具文件,文件名為utils\plots.py。該文件包含了兩個函數load_img和plot_all。

load_img函數用于加載圖像文件。它接受一個文件名作為參數,并可選擇是否進行調試、歸一化和調整大小。函數首先使用OpenCV庫的imread函數讀取圖像文件,然后將圖像從BGR顏色空間轉換為RGB顏色空間。如果選擇進行歸一化,則將圖像的像素值除以255,并將其轉換為32位浮點數類型。如果選擇進行調試,則會打印圖像的形狀、數據類型、最小值和最大值。如果選擇調整大小,則會使用OpenCV庫的resize函數將圖像調整為指定的大小。最后,函數返回加載和處理后的圖像。

plot_all函數用于繪制多個圖像。它接受一個圖像列表作為參數,并可選擇繪制軸的樣式和圖像的大小。函數首先創建一個matplotlib的Figure對象,并設置其大小和分辨率。然后,根據圖像列表的長度,在Figure對象中創建相應數量的子圖。對于每個子圖,設置軸的樣式,并使用imshow函數顯示對應的圖像。最后,調用show函數顯示繪制的圖像。

這個程序文件提供了方便的函數來加載和繪制圖像,可以在圖像處理和分析的過程中使用。

5.6 utils\util_calculate_psnr_ssim.py
import cv2
import torch
import numpy as npclass ImageMetrics:def __init__(self, input_order='HWC'):self.input_order = input_orderdef calculate_psnr(self, img1, img2, crop_border, test_y_channel=False):assert img1.shape == img2.shape, (f'Image shapes are differnet: {img1.shape}, {img2.shape}.')if self.input_order not in ['HWC', 'CHW']:raise ValueError(f'Wrong input_order {self.input_order}. Supported input_orders are ' '"HWC" and "CHW"')img1 = self.reorder_image(img1)img2 = self.reorder_image(img2)img1 = img1.astype(np.float64)img2 = img2.astype(np.float64)if crop_border != 0:img1 = img1[crop_border:-crop_border, crop_border:-crop_border, ...]img2 = img2[crop_border:-crop_border, crop_border:-crop_border, ...]if test_y_channel:img1 = self.to_y_channel(img1)img2 = self.to_y_channel(img2)mse = np.mean((img1 - img2) ** 2)if mse == 0:return float('inf')return 20. * np.log10(255. / np.sqrt(mse))......

該程序文件是一個用于計算圖像質量評估指標的工具文件。主要包含以下幾個函數:

  1. calculate_psnr(img1, img2, crop_border, input_order=‘HWC’, test_y_channel=False):計算圖像的峰值信噪比(PSNR)指標。

  2. _ssim(img1, img2):計算圖像的結構相似性(SSIM)指標。

  3. calculate_ssim(img1, img2, crop_border, input_order=‘HWC’, test_y_channel=False):計算圖像的結構相似性(SSIM)指標。

  4. _blocking_effect_factor(im):計算圖像的塊效應因子。

  5. calculate_psnrb(img1, img2, crop_border, input_order=‘HWC’, test_y_channel=False):計算圖像的PSNR-B指標。

  6. reorder_image(img, input_order=‘HWC’):重新排列圖像的通道順序。

  7. to_y_channel(img):將圖像轉換為Y通道。

  8. bgr2ycbcr(img, y_only=False):將BGR圖像轉換為YCbCr圖像。

這些函數可以用于評估圖像處理算法的

6.系統整體結構

整體功能和構架概述:

該圖像超分辨率系統的整體功能是實現圖像的超分辨率重建。它使用了基于Swin Transformer的模型進行圖像超分辨率處理。系統包含了多個程序文件,每個文件負責不同的功能模塊。主要的程序文件包括:

  1. main_test_swin2sr.py:用于圖像超分辨率重建的測試程序。負責加載模型、預處理圖像、進行推理、保存結果和計算評估指標等步驟。

  2. predict.py:圖像超分辨率預測的預測器。使用Swin2SR模型進行預測,定義了Predictor類,負責加載模型并進行預測。

  3. ui.py:圖像超分辨率的PyQt5界面程序。通過界面輸入圖像路徑和參數,調用predict.py中的函數進行超分辨率處理。

  4. models\network_swin2sr.py:實現Swin Transformer模型的核心組件。定義了多個輔助函數和模塊,包括Mlp、WindowAttention和SwinTransformerBlock等。

  5. utils\plots.py:用于繪制圖像的工具文件。包含load_img和plot_all函數,用于加載和繪制圖像。

  6. utils\util_calculate_psnr_ssim.py:用于計算圖像質量評估指標的工具文件。包含多個函數,用于計算PSNR、SSIM和其他指標。

  7. utils_init_.py:空文件,用于標識utils文件夾為Python模塊。

下表整理了每個文件的功能:

文件路徑功能
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\main_test_swin2sr.py圖像超分辨率重建的測試程序,包括加載模型、預處理圖像、進行推理、保存結果和計算評估指標等步驟
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\predict.py圖像超分辨率預測的預測器,定義了Predictor類,負責加載模型并進行預測
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\ui.py圖像超分辨率的PyQt5界面程序,通過界面輸入圖像路徑和參數,調用predict.py中的函數進行超分辨率處理
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\models\network_swin2sr.py實現Swin Transformer模型的核心組件,包括輔助函數和模塊,如Mlp、WindowAttention和SwinTransformerBlock
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\utils\plots.py用于繪制圖像的工具文件,包含load_img和plot_all函數,用于加載和繪制圖像
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\utils\util_calculate_psnr_ssim.py用于計算圖像質量評估指標的工具文件,包含多個函數,用于計算PSNR、SSIM和其他指標
E:\視覺項目\shop\基于Swin_Transformer的圖像超分辨率系統\code\utils_init_.py空文件,用于標識utils文件夾為Python模塊

7.Swin_Transformer用于超分辨率重建

參考該博客提出的RefSR工作,主要觀點是將Transformer作為一個attention,這樣可以更好地將參考圖像(Ref)的紋理信息轉移到高質圖像(HR)中。做法還是比較有意思的,如下圖所示,將上采樣的LR圖像、依次向下/上采樣的Ref圖像、原始Ref圖像中提取的紋理特征分別作為Q、K、V。紋理Transformer包含了4個結構:1)DNN實現的可學習的紋理提取器(learnable texture extractor)2)相關性嵌入模塊( relevance embedding)3)用于紋理轉換的硬注意力模塊(hard-attention)4)用于紋理合成的軟注意力模塊(soft-attention)。此外整個紋理Transformer模塊可以跨尺度的方式進一步堆疊,這使得能夠從不同尺度(例如,從1x倍到4x倍放大率)恢復紋理。

在這里插入圖片描述

網絡的整體架構

如下圖所示,將多個紋理Transformer(即上圖)堆疊、上采下采融合來實現超分。
其中RBS為多個殘差Block,CSFI為跨尺度特征集成模塊(ross-scale feature integration )

紋理Transformer

在這里插入圖片描述

即圖,介紹一下他的四個組件。
1)DNN實現的可學習的紋理提取器。就是將圖像送入DNN,然后DNN可以訓練
2)相關性嵌入模塊。使用歸一化內積計算Q、K之間的相關性。獲得矩陣r i , j r_{i,j}r
3)硬注意力。通過h i = a r g m a x ( r i , j ) h_{i}=argmax(r_{i,j})h
4)軟注意力。獲得軟注意力圖s i = a r g m a x ( r i , j ) s_{i}=argmax(r_{i,j})s

再分析一下這個公式,當S大的時候,說明當前塊和T的相關性大,所以用更多的T的特征,如果S小,則使用更少的參考幀特征。
在這里插入圖片描述

損失函數

L1 loss + GAN loss + Percepture Loss

網絡結構

在這里插入圖片描述
1)Shallow Feature Extraction 為一層3x3卷積。
2)HQ Image Reconstruction在SR任務中采用sub-pixel Conv,就是unpixelShuffle。denoise和JPEG去偽影用一層卷積。
3)對STL,就是Transformer的Encoder結構。將輸入劃分為M ? M M*MM?M個塊X,然后每個X映射為QKV,通過多頭attention后將輸出concat。MLP通過兩層FC實現。作者還進行了劃窗來避免圖像塊之間的信息不融合問題。步長為M / 2 M/2M/2

EMHA

主要是在獲得QKV之后,將QKV特征分為s組,每組分別進行attention獲得輸出O,然后將輸出Concat,這樣可以將大矩陣相乘拆分為多個小矩陣相乘。這也是Transformer常見的減少參數操作。
在這里插入圖片描述

HFM

此外該博客的作者還用了一個High-frequencyFiltering Module (HFM)提取高頻信息,結構如下,僅供參考。

在這里插入圖片描述

Microsoft Bing Turing ISR(T-ISR)

Introducing Turing Image Super Resolution: AI powered image enhancements for Microsoft Edge and Bing Maps
這篇不算論文,是微軟介紹自家用于Microsoft Edge和Bing Maps上ISR的技術博客。但是效果非常Amazing啊,但缺點是有些地方沒有仔細介紹。

設計原則

1)人類視覺為基準(Human eyes as the north star)
廣泛使用的指標如PSNR,SSIM并不總是和人眼視覺的直觀感受匹配的,同時也需要GT圖。我們構建了一個并行評估工具匹配人眼判斷,并將這個工具作為north star metric來引導模型訓練。(可是作者沒介紹這個工具是啥55555)
2)噪聲建模(Noise modeling)
開始作者也是將HR圖像降質然后構建HR-LR圖相對訓練。但這樣有些case效果好,但是對真實的LR圖像不魯棒。因此隨機對輸入圖像用blurring, compression 和 gaussian noise進行破壞可以恢復細節。
3)Perceptual and GAN loss
僅pixel loss不夠,要引入感知和GAN loss,并用權重結合。
4)Transformers for vision
CNN和Transformer各有優缺點,因此未利用他們各自優點,將網絡分為Enhance和Zoom,前者使用Transformer,后者使用CNN。(其實這段也沒詳細介紹各自優缺點是什么。整體四準則很對我胃口啊,果然英雄所見略同hhhh)

DeepEnhance – Cleaning and Enhancing Images

在處理高度壓縮和從遠程衛星拍攝的航拍照片等very noise圖像時,Transformer清理噪聲做的很好。如人臉的噪聲和處理包含很多紋理的森林的特征就很不同。這是因為大數據集和Transformer卓越的遠程記憶能力。我們先使用了一個稀疏Transformer,將其放大以支持非常大的序列長度來“Enhance”圖像,產生干凈的,crisper和更具吸引力,尺寸相同的圖像。有些場景不需要放大圖像,那到這里就可以停止了。

在這里插入圖片描述

8.系統整合

下圖完整源碼&環境部署視頻教程&自定義UI界面

在這里插入圖片描述

參考博客《基于Swin_Transformer的圖像超分辨率系統》

9.參考文獻


[1]盤展鴻,朱鑒,遲小羽,等.基于特征融合和注意力機制的圖像超分辨率模型[J].計算機應用研究.2022,39(3).DOI:10.19734/j.issn.1001-3695.2021.07.0288 .

[2]鄧焱文.基于深度學習的超分辨率重建在人臉識別中的應用[D].2019.

[3]Yu-Qi Liu,Xin Du,Hui-Liang Shen,等.Estimating Generalized Gaussian Blur Kernels for Out-of-Focus Image Deblurring[J].IEEE Transactions on Circuits & Systems for Video Technology.2020,31(3).829-843.DOI:10.1109/TCSVT.2020.2990623 .

[4]Shengxiang Zhang,Gaobo Liang,Shuwan Pan,等.A Fast Medical Image Super Resolution Method Based on Deep Learning Network[J].IEEE Access.2018.712319-12327.DOI:10.1109/ACCESS.2018.2871626 .

[5]Huihui Song,Qingshan Liu,Guojie Wang,等.Spatiotemporal Satellite Image Fusion Using Deep Convolutional Neural Networks[J].IEEE journal of selected topics in applied earth observations & remote sensing.2018,11(3).821-829.DOI:10.1109/JSTARS.2018.2797894 .

[6]Park, S.,Serpedin, E.,Qaraqe, K..Gaussian Assumption: The Least Favorable but the Most Useful [Lecture Notes][J].IEEE Signal Processing Magazine.2013,30(3).183-186.

[7]Mittal, A.,Soundararajan, R.,Bovik, A.C..Making a “Completely Blind” Image Quality Analyzer[J].Signal Processing Letters, IEEE.2013,20(3).209-212.DOI:10.1109/LSP.2012.2227726 .

[8]Ogawa, T.,Haseyama, M..Missing Intensity Interpolation Using a Kernel PCA-Based POCS Algorithm and its Applications[J].IEEE Transactions on Image Processing.2011,20(2).

[9]Yang, J.Wright, J.Huang, T.Ma, Y..Image Super-Resolution Via Sparse Representation[J].IEEE Transactions on Image Processing.2010,19(11).2861-2873.

[10]Bovik A.C.,Zhou Wang,Simoncelli E.P.,等.Image quality assessment: from error visibility to structural similarity[J].IEEE Transactions on Image Processing.2004,13(4).

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209648.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209648.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209648.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI:91-基于深度學習的手寫數學表達式識別

?? 本文選自專欄:人工智能領域200例教程專欄 從基礎到實踐,深入學習。無論你是初學者還是經驗豐富的老手,對于本專欄案例和項目實踐都有參考學習意義。 ??? 每一個案例都附帶有在本地跑過的核心代碼,詳細講解供大家學習,希望可以幫到大家。歡迎訂閱支持,正在不斷更新…

51單片機的時鐘電路與時序以及 復位電路和電源模式

51單片機的時鐘電路與時序以及 復位電路和電源模式 本文主要涉及51單片機的時鐘電路以及相關時序的知識&#xff0c;也講解了了51單片機的復位電路以及電源模式。 文章目錄 51單片機的時鐘電路與時序以及 復位電路和電源模式一、時鐘電路與時序1、 時鐘電路設計1.1 內部時鐘方式…

用stl寫一個自動打分比賽的案例

我們要實現六名選手進行隨機平均分為兩組&#xff0c;先分別淘汰兩組中的最后一名&#xff0c; 再決出第一名。 抽象選手 class player { public:string name;int score; }; 一個選手有名字和分數 首先我們需要vector容器保存選手的編號&#xff0c;便于后續的操作。 再用…

導入PR的視頻畫面是黑屏的怎么辦?

在現代視頻編輯領域中&#xff0c;越來越多的人使用Adobe Premiere Pro來編輯和制作視頻&#xff0c;但是在某些情況下&#xff0c;用戶可能需要透明背景的視頻進行創作&#xff0c;那么如何創作透明背景的視頻呢&#xff1f; 要制作具有透明背景的視頻&#xff0c;我們需要使…

如何贏得并留住訂閱者:12 個必須嘗試的訂閱營銷策略

Netflix、Hubspot、Spotify 和 Slack 都是流行的基于訂閱的服務&#xff0c;您可能每天都會使用它們&#xff0c;無論是工作還是娛樂。這些例子表明&#xff0c;訂閱業務模式深受 SaaS 創業者的青睞。 這種模式的吸引力很容易理解&#xff0c;特別是考慮到訂閱市場預計到 2025…

C //例10.5 有一個磁盤文件,內有一些信息。要求第1次將它的內容顯示在屏幕上,第2次把它復制到另一文件上。

C程序設計 &#xff08;第四版&#xff09; 譚浩強 例10.5 例10.5 有一個磁盤文件&#xff0c;內有一些信息。要求第1次將它的內容顯示在屏幕上&#xff0c;第2次把它復制到另一文件上。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差異。 代碼塊 方法&a…

mysql支持的整數類型、各類型整數能夠表示的數值范圍

MySQL :: MySQL 8.2 Reference Manual :: 11.1.2 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT mysql支持的整數有&#xff1a;TINYINT、SMALLINT、MEDIUMINT、INT&#xff08;INT和INTEGER是同義詞&#xff09;、BIGINT&#xff0c;各…

【C#】序列化和反序列化,以及System.Text.Json和Newtonsoft.Json比較

給自己一個目標&#xff0c;然后堅持一段時間&#xff0c;總會有收獲和感悟&#xff01; 序列化和反序列化&#xff0c;在實際項目開發過程中用的最多。特別是有對接接口的小伙伴就深有體會。本篇文章就簡單聊聊這個知識點。 目錄 一、基本概念1.1、序列化1.2反序列化1.3、舉例…

AI 賦能 | 智能制造的 AI 算法開發和工程實現

談到智能制造、智慧工廠&#xff0c;愿景是美好的&#xff0c;借助計算機視覺技術和 AI 算法&#xff0c;為自動化生產線賦予環境感知的能力&#xff0c;從而改善工藝流程&#xff0c;提高生產效率。但是&#xff0c;隨著柔性化生產的需求增長&#xff0c;產線的布局調整和功能…

鎖的策略及synchronized詳解

加鎖過程中&#xff0c;處理沖突的過程中&#xff0c;涉及到的一些不同的處理方式。鎖的策略決定了線程如何獲取和釋放鎖以及在何種情況下阻塞和喚醒線程。 1. 常見的鎖策略 1.1 樂觀鎖和悲觀鎖 樂觀鎖&#xff1a;在加鎖之前&#xff0c;預估當前出現鎖沖突的概率不大&am…

Docker三 | 數據卷

目錄 Docker數據卷簡介 添加數據卷的命令 容器數據卷的繼承 Docker數據卷簡介 Docker容器產生的數據&#xff0c;如果不備份&#xff0c;當容器實例刪除后&#xff0c;容器中的數據也會消失&#xff0c;為了保存數據可以在Docker中使用數據卷。Docker數據卷是宿主機的一個可以…

vue3中子組件調用父組件的方法

<script lang"ts" setup>前提 父組件&#xff1a; 子組件&#xff1a; const emit defineEmits([closeson]) 在子組件的方法中使用&#xff1a; emit(closeson)

EP15:動態內存管理概述(c語言)malloc,calloc,realloc函數的介紹使用及柔性數組的介紹

如果學習方向是c方向那么c語言有三個板塊的知識是非常重要的. 1:指針 2:結構體 3;動態內存管理. 序言:在c語言中,什么是動態內存 C語言中的動態內存是指在程序運行時&#xff0c;根據需要動態地分配內存空間的一種內存管理方式。與靜態內存相比&#xff0c;動態內存的大小和生…

12.ROS導航模塊:gmapping、AMCL、map_server、move_base案例

目錄 1 導航概述 2 導航簡介 2.1 導航模塊簡介 1.全局地圖 2.自身定位 3.路徑規劃 4.運動控制 5.環境感知 2.2 導航坐標系odom、map 1.簡介 2.特點 3.坐標系變換 2.3 導航條件說明 1.硬件 2.軟件 3 導航實現 3.1 創建本篇博客的功能包 3.2 建圖--gmapping 3.…

JavaScript基礎知識整理(最全知識點, 精簡版,0基礎版)

文章目錄 一、輸入和輸出內容 1.1 輸出 1.1.1 在瀏覽器的控制臺輸出打印 1.1.2 直接在瀏覽器的頁面上輸出內容 1.1.3 頁面彈出警告對話框 1.2 輸入 二、變量 2.1 變量是什么 2.2 變量的聲明和賦值 2.3 變量的命名規范和規范 三、變量擴展&#xff08;數組&#xff09; 3.1 數組…

Cypress:前端自動化測試的終極利器

引言&#xff1a; 在現代軟件開發中&#xff0c;前端自動化測試已經成為了一個不可或缺的環節。它不僅可以提高開發效率&#xff0c;減少手動測試的工作量&#xff0c;還可以保證軟件的穩定性和質量。而在眾多的前端自動化測試工具中&#xff0c;Cypress無疑是其中的佼佼者。本…

openGauss學習筆記-144 openGauss 數據庫運維-例行維護-慢sql診斷

文章目錄 openGauss學習筆記-144 openGauss 數據庫運維-例行維護-慢sql診斷144.1 背景信息144.2 前提條件 openGauss學習筆記-144 openGauss 數據庫運維-例行維護-慢sql診斷 144.1 背景信息 在SQL語句執行性能不符合預期時&#xff0c;可以查看SQL語句執行信息&#xff0c;便…

文章解讀與仿真程序復現思路——中國電機工程學報EI\CSCD\北大核心《考慮垃圾處理與調峰需求的可持續化城市多能源系統規劃》

這個標題涵蓋了城市多能源系統規劃中的兩個重要方面&#xff1a;垃圾處理和調峰需求&#xff0c;并強調了規劃的可持續性。 考慮垃圾處理&#xff1a; 含義&#xff1a; 垃圾處理指的是城市廢棄物的管理和處置。這可能涉及到廢物分類、回收利用、焚燒或填埋等方法。重要性&…

GIS入門,Leaflet介紹,Leaflet可以做什么,網頁中如何使用Leaflet地圖,vue中如何使用Leaflet地圖

VueLeafLet教程推薦&#xff1a;《VueLeaflet入門》 Leaflet介紹 Leaflet是一個開源的JavaScript庫&#xff0c;用于創建交互式的地圖和地圖應用。Leaflet框架具有輕量級、靈活性強、易于使用和擴展等特點&#xff0c;支持各種地圖服務商&#xff08;如OpenStreetMap、Google…

前端知識筆記(三十八)———HTTPS:保護網絡通信安全的關鍵

當談到網絡通信和數據傳輸時&#xff0c;安全性是一個至關重要的問題。在互聯網上&#xff0c;有許多敏感信息需要通過網絡進行傳輸&#xff0c;例如個人身份信息、銀行賬戶信息和商業機密等。為了保護這些信息不被未經授權的人訪問和篡改&#xff0c;HTTPS&#xff08;超文本傳…