• 【Python&图像超分】Real-ESRGAN图像超分模型(超分辨率重建)详细安装和使用教程


    1 前言

            图像超分是一种图像处理技术,旨在提高图像的分辨率,使其具有更高的清晰度和细节。这一技术通常用于图像重建、图像恢复、图像增强等领域,可以帮助我们更好地理解和利用图像信息。图像超分技术可以通过多种方法实现,包括插值算法、深度学习等。其中,深度学习的方法在近年来得到了广泛的关注和应用。基于深度学习的图像超分技术,可以利用深度神经网络学习图像的高频部分,从而提高了图像的分辨率和清晰度

            目前应用较多的应用场景是图像及视频分辨率提高,比如可以提高以往影视作品或图像的分辨率,提高视觉感官效果;或是解决视频经有损压缩后导致视频效果退化问题。今天给大家介绍一下腾讯ARC实验室发布的一个图像超分辨率模型Real-ESRGAN:项目开源地址论文地址

    1.1 项目效果展示

    2 Python代码使用教程

    2.1 依赖库安装

    2.1.1 项目安装
    1. git clone https://github.com/xinntao/Real-ESRGAN.git
    2. cd Real-ESRGAN
    2.1.2 安装依赖
    1. # 安装 basicsr - https://github.com/xinntao/BasicSR
    2. # 我们使用BasicSR来训练以及推断
    3. pip install basicsr
    4. # facexlib和gfpgan是用来增强人脸的
    5. pip install facexlib
    6. pip install gfpgan
    7. pip install -r requirements.txt
    8. python setup.py develop

    2.2 模型介绍

            模型下载链接,里面有7个,有些我不知道是干啥用的,所以就没说。

    • realesrgan-x4plus(默认)
    • reaesrnet-x4plus
    • realesrgan-x4plus-anime(针对动漫插画图像优化,有更小的体积)
    • realesr-animevideov3 (针对动漫视频)

    2.3 代码使用

            将下载好的模型,放在项目文件中的weights文件夹中,然后打开inference_realesrgan.py和inference_realesrgan_video.py这两个文件就运行就行了,一个是图片超分,一个是视频超分。我这里将代码已经全部注释了,自己可以看看很好理解。

            默认模型是realesrgan-x4plus,需要超分的图片/视频放在项目文件夹的inputs中,输出在results中。

    1. import argparse
    2. import cv2
    3. import glob
    4. import os
    5. from basicsr.archs.rrdbnet_arch import RRDBNet
    6. from basicsr.utils.download_util import load_file_from_url
    7. from realesrgan import RealESRGANer
    8. from realesrgan.archs.srvgg_arch import SRVGGNetCompact
    9. def main():
    10. """Inference demo for Real-ESRGAN.
    11. """
    12. parser = argparse.ArgumentParser() # 创建一个命令行解析器对象,用于解析命令行参数
    13. parser.add_argument('-i', '--input', type=str, default='inputs', help='Input image or folder')
    14. # 添加一个命令行参数 -i, --input,类型为字符串,默认值为 'inputs',用于指定输入图像或文件夹
    15. parser.add_argument(
    16. '-n',
    17. '--model_name',
    18. type=str,
    19. default='RealESRGAN_x4plus',
    20. help=('Model names: RealESRGAN_x4plus | RealESRNet_x4plus | RealESRGAN_x4plus_anime_6B | RealESRGAN_x2plus | '
    21. 'realesr-animevideov3 | realesr-general-x4v3'))
    22. # 添加一个命令行参数 -n, --model_name,类型为字符串,默认值为 'RealESRGAN_x4plus',用于指定使用的模型名称
    23. parser.add_argument('-o', '--output', type=str, default='results', help='Output folder')
    24. # 添加一个命令行参数 -o, --output,类型为字符串,默认值为 'results',用于指定输出文件夹
    25. parser.add_argument(
    26. '-dn',
    27. '--denoise_strength',
    28. type=float,
    29. default=0.5,
    30. help=('Denoise strength. 0 for weak denoise (keep noise), 1 for strong denoise ability. '
    31. 'Only used for the realesr-general-x4v3 model'))
    32. # 添加一个命令行参数 -dn, --denoise_strength,类型为浮点数,默认值为 0.5,用于指定去噪强度
    33. parser.add_argument('-s', '--outscale', type=float, default=4, help='The final upsampling scale of the image')
    34. # 添加一个命令行参数 -s, --outscale,类型为浮点数,默认值为 4,用于指定最终的放大倍数
    35. parser.add_argument(
    36. '--model_path', type=str, default=None, help='[Option] Model path. Usually, you do not need to specify it')
    37. # 添加一个命令行参数 --model_path,类型为字符串,默认值为 None,用于指定模型路径。通常不需要指定。
    38. parser.add_argument('--suffix', type=str, default='out', help='Suffix of the restored image')
    39. # 添加一个命令行参数 --suffix,类型为字符串,默认值为 'out',用于指定输出图像的后缀
    40. parser.add_argument('-t', '--tile', type=int, default=0, help='Tile size, 0 for no tile during testing')
    41. # 添加一个命令行参数 -t, --tile,类型为整数,默认值为 0,用于指定瓦片大小。0 表示测试时没有瓦片。
    42. parser.add_argument('--tile_pad', type=int, default=10, help='Tile padding')
    43. # 添加一个命令行参数 --tile_pad,类型为整数,默认值为 10,用于指定瓦片填充大小
    44. parser.add_argument('--pre_pad', type=int, default=0, help='Pre padding size at each border')
    45. # 添加一个命令行参数 --pre_pad,类型为整数,默认值为 0,用于指定每个边界的预填充大小
    46. parser.add_argument('--face_enhance', action='store_true', help='Use GFPGAN to enhance face')
    47. # 添加一个命令行参数 --face_enhance,动作是存储为 True,用于指定是否使用 GFPGAN 来增强人脸
    48. parser.add_argument(
    49. '--fp32', action='store_true', help='Use fp32 precision during inference. Default: fp16 (half precision).')
    50. # 添加一个命令行参数 --fp32,动作是存储为 True,用于指定推理期间是否使用 fp32 精度。默认情况下使用 fp16(半精度)
    51. parser.add_argument(
    52. '--alpha_upsampler',
    53. type=str,
    54. default='realesrgan',
    55. help='The upsampler for the alpha channels. Options: realesrgan | bicubic')
    56. # 添加一个命令行参数 --alpha_upsampler,类型为字符串,默认值为 'realesrgan',用于指定 alpha 通道的上采样器。选项:realesrgan | bicubic
    57. parser.add_argument(
    58. '--ext',
    59. type=str,
    60. default='auto',
    61. help='Image extension. Options: auto | jpg | png, auto means using the same extension as inputs')
    62. # 添加一个参数,参数名为'--ext',类型为字符串,默认值为auto,这个参数主要用于指定输入图像的扩展名。
    63. parser.add_argument(
    64. '-g', '--gpu-id', type=int, default=None, help='gpu device to use (default=None) can be 0,1,2 for multi-gpu')
    65. # 添加一个参数,参数名为'-g'或'--gpu-id',类型为整数,默认值为None。这个参数主要用于指定使用的GPU设备。
    66. args = parser.parse_args()
    67. # 解析命令行参数,生成一个命名空间args
    68. # determine models according to model names
    69. args.model_name = args.model_name.split('.')[0]
    70. # 根据传入的命令行参数--model-name来选择模型,这里假设模型名称和使用的模型之间的关系已经预设好。
    71. if args.model_name == 'RealESRGAN_x4plus': # x4 RRDBNet model
    72. model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
    73. netscale = 4
    74. file_url = ['https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth']
    75. elif args.model_name == 'RealESRNet_x4plus': # x4 RRDBNet model
    76. model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
    77. netscale = 4
    78. file_url = ['https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.1/RealESRNet_x4plus.pth']
    79. elif args.model_name == 'RealESRGAN_x4plus_anime_6B': # x4 RRDBNet model with 6 blocks
    80. model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=6, num_grow_ch=32, scale=4)
    81. netscale = 4
    82. file_url = ['https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth']
    83. elif args.model_name == 'RealESRGAN_x2plus': # x2 RRDBNet model
    84. model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=2)
    85. netscale = 2
    86. file_url = ['https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.1/RealESRGAN_x2plus.pth']
    87. elif args.model_name == 'realesr-animevideov3': # x4 VGG-style model (XS size)
    88. model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=16, upscale=4, act_type='prelu')
    89. netscale = 4
    90. file_url = ['https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-animevideov3.pth']
    91. elif args.model_name == 'realesr-general-x4v3': # x4 VGG-style model (S size)
    92. model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu')
    93. netscale = 4
    94. file_url = [
    95. 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth',
    96. 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth'
    97. ]
    98. # determine model paths
    99. if args.model_path is not None:
    100. # 判断是否传入了模型路径,如果传入了则直接使用该路径,否则会结合模型名称生成一个默认的模型路径
    101. model_path = args.model_path
    102. else:
    103. model_path = os.path.join('weights', args.model_name + '.pth')
    104. if not os.path.isfile(model_path):
    105. ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
    106. for url in file_url:
    107. # model_path will be updated
    108. model_path = load_file_from_url(
    109. url=url, model_dir=os.path.join(ROOT_DIR, 'weights'), progress=True, file_name=None)
    110. # use dni to control the denoise strength
    111. dni_weight = None
    112. # dni_weight 为 None 表示不使用 DNI
    113. # 如果使用了 DNI,dni_weight 的值会是一个列表,列表的两个元素分别代表 DNI 网络和原始模型的权重
    114. if args.model_name == 'realesr-general-x4v3' and args.denoise_strength != 1:
    115. wdn_model_path = model_path.replace('realesr-general-x4v3', 'realesr-general-wdn-x4v3')
    116. model_path = [model_path, wdn_model_path]
    117. dni_weight = [args.denoise_strength, 1 - args.denoise_strength]
    118. # restorer
    119. upsampler = RealESRGANer(
    120. scale=netscale, # 放大倍率,即超分辨率的因子
    121. model_path=model_path, # 预训练模型的路径
    122. dni_weight=dni_weight, # DNI网络的权重,用于控制去噪强度(Denoising Network Integration)
    123. model=model, # 输入模型,一般是降噪后的图像
    124. tile=args.tile, # 分块大小,即将图像切割成多个小块进行超分辨率
    125. tile_pad=args.tile_pad, # 块与块之间的填充大小
    126. pre_pad=args.pre_pad, # 预处理时的填充大小
    127. half=not args.fp32, # 是否使用半精度浮点数进行计算,若args.fp32为True则使用半精度,否则使用全精度
    128. gpu_id=args.gpu_id) # GPU的ID,用于在多GPU环境下指定使用哪个GPU进行计算
    129. if args.face_enhance: # Use GFPGAN for face enhancement,如果需要使用 GFPGAN 进行人脸增强
    130. from gfpgan import GFPGANer # 导入 GFPGAN 人脸增强器的类
    131. face_enhancer = GFPGANer(
    132. model_path='https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth',
    133. upscale=args.outscale, # 放大倍率,即超分辨率的因子
    134. arch='clean', # GFPGAN的架构,这里选择的是'clean'版本
    135. channel_multiplier=2, # 通道的乘数,用于扩大模型的通道数
    136. bg_upsampler=upsampler) # 使用之前创建的RealESRGAN超分辨率增强器作为背景超分辨率增强器
    137. # args.output = r"G:\Anaconda\ProjectYOLO\yolov5-7.0\Real-ESRGAN-master\1/"
    138. os.makedirs(args.output, exist_ok=True) # 创建输出目录,如果已存在则不报错,继续执行后续代码
    139. if os.path.isfile(args.input):
    140. # 判断输入路径是否为一个文件
    141. paths = [args.input]
    142. # 如果是文件,直接将其路径加入到paths列表中
    143. else:
    144. paths = sorted(glob.glob(os.path.join(args.input, '*')))
    145. # 如果输入路径不是一个文件,那么它应该是一个包含图像的文件夹
    146. # 使用glob库获取输入路径下所有的文件路径,并将它们按字母顺序排序后加入到paths列表中
    147. for idx, path in enumerate(paths):
    148. # 遍历所有的文件路径
    149. imgname, extension = os.path.splitext(os.path.basename(path)) # 获取文件名和扩展名
    150. print('Testing', idx, imgname) # 打印正在处理的文件信息
    151. img = cv2.imread(path, cv2.IMREAD_UNCHANGED)
    152. # 使用OpenCV读取图片,参数cv2.IMREAD_UNCHANGED表示以最接近原始图像的颜色空间读取图像
    153. if len(img.shape) == 3 and img.shape[2] == 4:
    154. # 判断图像的维度,如果维度为3且第三个维度的大小为4,说明图像是RGBA格式的,否则不进行特殊处理
    155. img_mode = 'RGBA' # 记录图片模式为RGBA
    156. else:
    157. img_mode = None # 否则不记录图片模式
    158. try:
    159. if args.face_enhance:
    160. # 如果需要人脸增强,使用face_enhancer进行人脸增强处理,参数包括输入图像、是否进行人脸对齐、是否只处理中心的人脸部分以及是否将处理后的人脸粘贴回原图
    161. _, _, output = face_enhancer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True)
    162. else:
    163. # 否则,使用upsampler进行图像超分辨率增强,参数包括输入图像、放大倍数以及是否使用GPU加速
    164. output, _ = upsampler.enhance(img, outscale=args.outscale)
    165. except RuntimeError as error:
    166. # 如果在处理过程中出现RuntimeError异常,打印错误信息,并给出可能的解决方案
    167. print('Error', error)
    168. print('If you encounter CUDA out of memory, try to set --tile with a smaller number.')
    169. else:
    170. # 如果没有出现异常,执行else分支的代码
    171. # 如果用户没有指定输出文件的扩展名,则自动从输入文件的扩展名中获取输出文件的扩展名;否则使用用户指定的扩展名
    172. if args.ext == 'auto':
    173. extension = extension[1:]
    174. else:
    175. extension = args.ext
    176. if img_mode == 'RGBA': # RGBA images should be saved in png format
    177. # 如果图片的模式是RGBA,说明图片是RGBA格式的,需要将其保存为png格式的图片
    178. extension = 'png'
    179. if args.suffix == '':
    180. # 根据用户指定的后缀名构造保存路径
    181. save_path = os.path.join(args.output, f'{imgname}.{extension}')
    182. else:
    183. save_path = os.path.join(args.output, f'{imgname}_{args.suffix}.{extension}')
    184. # 使用OpenCV将处理后的图片保存到指定路径下,参数指定保存的文件格式和压缩质量等选项(这里没有指定压缩质量)
    185. cv2.imwrite(save_path, output)
    186. # 保存处理后的图片到指定路径下
    187. if __name__ == '__main__':
    188. main()

    2.4 命令行使用

    2.4.1 参数
    1. Usage: python inference_realesrgan.py -n RealESRGAN_x4plus -i infile -o outfile [options]...
    2. A common command: python inference_realesrgan.py -n RealESRGAN_x4plus -i infile --outscale 3.5 --face_enhance
    3. -h show this help
    4. -i --input Input image or folder. Default: inputs
    5. -o --output Output folder. Default: results
    6. -n --model_name Model name. Default: RealESRGAN_x4plus
    7. -s, --outscale The final upsampling scale of the image. Default: 4
    8. --suffix Suffix of the restored image. Default: out
    9. -t, --tile Tile size, 0 for no tile during testing. Default: 0
    10. --face_enhance Whether to use GFPGAN to enhance face. Default: False
    11. --fp32 Whether to use half precision during inference. Default: False
    12. --ext Image extension. Options: auto | jpg | png, auto means using the same extension as inputs. Default: auto
    2.4.2 参数使用
    python inference_realesrgan.py -n RealESRGAN_x4plus_anime_6B -i inputs

    3 桌面端轻应用

            作者提供了打包好的桌面端exe程序,无需配置PyTorch等依赖,Windows下载地址

            使用方法也很简单,图片放在realesrgan-ncnn-vulkan.exe同目录下,然后使用cmd命令行跳转至这个目录,输入下面的命令(自己修改)。

    ./realesrgan-ncnn-vulkan.exe -i 输入图像.jpg -o 输出图像.png -n 模型名字

            注意:可执行文件并没有支持 python 脚本 inference_realesrgan.py 中所有的功能,比如 outscale 选项) .

    1. Usage: realesrgan-ncnn-vulkan.exe -i infile -o outfile [options]...
    2. -h show this help
    3. -i input-path input image path (jpg/png/webp) or directory
    4. -o output-path output image path (jpg/png/webp) or directory
    5. -s scale upscale ratio (can be 2, 3, 4. default=4)
    6. -t tile-size tile size (>=32/0=auto, default=0) can be 0,0,0 for multi-gpu
    7. -m model-path folder path to the pre-trained models. default=models
    8. -n model-name model name (default=realesr-animevideov3, can be realesr-animevideov3 | realesrgan-x4plus | realesrgan-x4plus-anime | realesrnet-x4plus)
    9. -g gpu-id gpu device to use (default=auto) can be 0,1,2 for multi-gpu
    10. -j load:proc:save thread count for load/proc/save (default=1:2:2) can be 1:2,2,2:2 for multi-gpu
    11. -x enable tta mode"
    12. -f format output image format (jpg/png/webp, default=ext/png)
    13. -v verbose output

            由于这些exe文件会把图像分成几个板块,然后来分别进行处理,再合成导出,输出的图像可能会有一点割裂感(而且可能跟PyTorch的输出不太一样)。

    4 总结

            这个开源项目总体来说精度是不错的,图像的分辨率确实有明显的提升,可以将模糊的图片还原出更多的细节,但有时候的效果比较抽象。作者在项目中说会持续更新(PS:作者的重心好像是放在动漫图片超分方面),希望会越来越好。最后分享一下腾讯ARC的Web端使用demo

  • 相关阅读:
    一个简单而优雅的C++线程池
    云仓是什么?如何选择优质云仓?
    JAVA数据类型详解
    springboot 拦截器中使用@Value注解为null
    【OpenCV】Chapter2.图像的数值运算
    js 转成Number , Boolean类型
    【英语:基础高阶_学术写作训练】J2.写作中的常见逻辑误区
    平衡二叉树(AVL) 的认识与实现
    【Leetcode】2864. 最大二进制奇数
    Linux vi编辑器的使用
  • 原文地址:https://blog.csdn.net/m0_56729804/article/details/134398693