💪 专业从事且热爱图像处理,图像处理专栏更新如下👇:
📝《图像去噪》
📝《超分辨率重建》
📝《语义分割》
📝《风格迁移》
📝《目标检测》
📝《图像增强》
📝《模型优化》
📝《模型实战部署》
📝《图像配准融合》
📝《数据集》
📝《高效助手》
📝《C++》
📝《Qt》
之前发布过一篇二阶降解模拟真实退化图像博文,现在在之前博文基础修改代码,实现一阶降解上采样2倍模拟退化真实噪声图像。
一、原理
图像降解原理看降解原理,在这篇博文中,已经详细介绍的降解原理。
二、包和环境问题
下面是需要的相关库:
在源码包中的degradations2.py脚本中有一些必需要调用的函数。
三、代码
这里代码给出上采样降解模拟退化和下采样降解模拟退化,如果不需要上采样或下采样,scale参数设置为1即可。
3.1 上采样降解退化
3.1.1 参数修改
下面修改锐化相关参数:
下面参数是调整上采样倍数和添加随机高斯噪声、泊松噪声强弱的变量。
下面参数修改图片的读入和输出保存路径:
3.1.2 主代码
由于代码过于冗长,这里给出主代码,配套教程的源码包获取方式已在文章结尾提供,扫码到「视觉研坊」中回复关键字:一阶降解模拟真实图像,会自动回复下载链接。下载解压后的样子见下:
主代码见下:
import cv2
import numpy as np
import torch
from torch.nn import functional as F
import random
import os
from degradations2 import *
from tqdm import tqdm
def degration_image(data):
"""Accept data from dataloader, and then add two-order degradations to obtain LQ images.
"""
# jpeger = DiffJPEG(differentiable=False) # 创建了一个DiffJPEG对象,用于模拟JPEG压缩伪影
usm_sharpener = USMSharp(radius=80, sigma=1.0)
gt_usm = usm_sharpener(data, weight=0.9, threshold=30) # 读入高分辨率图像,先对高分辨率图像进行USM锐化处理
# kernel1,kernel2,sinc_kernel = kernel_kernel() # 滤波器内核
kernel1, _, _ = kernel_kernel() # 滤波器内核 只需要一个卷积核
# ori_h, ori_w = data.size()[2:4] # 获取高质量图像的高度和宽度
## 降质参数调整
# the first degradation process # 第一个降级过程
# scale_scale = 1 # 下采样倍数
scale = 2 # 上采样倍数
# resize_prob = [0, 0, 1] # up, down, keep # 设置图像缩放的概率,分别对应上采样、下采样和保持原大小的概率。 保持原图大小,因为需要进
# resize_range = [1, 2] # 设置图像缩放的范围1到2倍之间。
gaussian_noise_prob = 0.6 # 设置添加高斯噪声的概率为0.2
noise_range = [1, 6] # 设置噪声强度的范围为1到10
poisson_scale_range = [0.05, 0.5] # 设置泊松噪声的强度范围为0.05到0.95
gray_noise_prob = 0.6 # 设置添加灰度噪声的概率为0.4
#################################################################################################################
# ----------------------- The first degradation process ----------------------- #
# blur
out = filter2D(gt_usm, kernel1) # 使用第一个卷积核对锐化后的高质量图像进行卷积
# mode = random.choice(['area', 'bilinear', 'bicubic'])
mode = random.choice(["nearest",'bilinear', 'bicubic',])
out = F.interpolate(out, scale_factor=scale, mode=mode) # 对图像进行缩放
# add noise
gray_noise_prob = gray_noise_prob
if np.random.uniform() < gaussian_noise_prob: # 这个if-else语句根据概率选择添加高斯噪声或泊松噪声
out = random_add_gaussian_noise_pt(out, sigma_range=noise_range, clip=True, rounds=False, gray_prob=gray_noise_prob)
else:
out = random_add_poisson_noise_pt(out,scale_range=poisson_scale_range,gray_prob=gray_noise_prob,clip=True,rounds=False)
lq = torch.clamp((out * 255.0).round(), 0, 255) / 255.
return lq
if __name__ == "__main__":
folder_path = "Images\Rui_640_little"
output_path = "Images\Rui_640_little_Degration_UP2_1"
# 获取文件夹中所有的文件
file_list = os.listdir(folder_path)
# 遍历文件列表
for file_name in tqdm(file_list,desc="Processing images"):
# 拼接文件路径
file_path = os.path.join(folder_path, file_name)
# 仅处理图像文件
if os.path.isfile(file_path) and file_name.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
# 读取图像路径
image = cv2.imread(file_path)
image = image.astype(np.float32) / 255
# BGR to RGB, HWC to CHW, numpy to tensor
image_tensor = img2tensor([image],bgr2rgb=True,float32=True)[0]
# 增加一个维度
image_tensor = image_tensor.unsqueeze(0)
# print(image_tensor.shape)
image_degratation = degration_image(image_tensor)
# 保存图像
output_lq = image_degratation.detach().squeeze().float().cpu().clamp_(0, 1).numpy() # 代码对处理后的图像进行一系列操作,包括删除尺寸为1的
output_lq = np.transpose(output_lq[[2, 1, 0], :, :], (1, 2, 0))
output_lq = (output_lq * 255.0).round().astype(np.uint8) # 这行代码将图像的像素值从[0, 1]范围变为[0, 255]范围,并四舍五入到最近的整数,然后
output_name = file_name
print(output_name)
cv2.imwrite(os.path.join(output_path, output_name), output_lq) # 将处理后的图像保存为BMP格式的文件。
下面是运行Degratation_Images_Tensor_Arg_UP.py脚本后正常输出过程:
3.2 下采样降解退化
3.1.1 参数修改
锐化参数修改同上。
下面是降解退化参数的修改:
下面是启用JPEG压缩功能:
下面是修改待处理图像路径和输出保存路径:
3.2.2 主代码
源码包中对应的脚本见下:
主代码见下:
import cv2
import numpy as np
import torch
from torch.nn import functional as F
import random
import os
# from Degration_images.diffjpeg import DiffJpeg
from diffjpeg import DiffJPEG
from degradations2 import *
from tqdm import tqdm
def degration_image(data):
"""Accept data from dataloader, and then add two-order degradations to obtain LQ images.
"""
jpeger = DiffJPEG(differentiable=False) # 创建了一个DiffJPEG对象,用于模拟JPEG压缩伪影
usm_sharpener = USMSharp(radius=80, sigma=1.0)
gt_usm = usm_sharpener(data, weight=0.9, threshold=30) # 读入高分辨率图像,先对高分辨率图像进行USM锐化处理
kernel1,kernel2,sinc_kernel = kernel_kernel() # 滤波器内核
ori_h, ori_w = data.size()[2:4] # 获取高质量图像的高度和宽度
## 降质参数调整
# the first degradation process # 第一个降级过程
scale_scale = 2 # 下采样倍数
resize_prob = [0.2, 0.5, 0.1] # up, down, keep # 设置图像缩放的概率,分别对应上采样、下采样和保持原大小的概率。
resize_range = [0.8, 1.2] # 设置图像缩放的范围,即图像大小可以在原始大小的80%到120%之间变化
gaussian_noise_prob = 0.3 # 设置添加高斯噪声的概率为0.4
noise_range = [1, 2] # 设置噪声强度的范围为1到10
poisson_scale_range = [0.05, 0.5] # 设置泊松噪声的强度范围为0.05到0.95
gray_noise_prob = 0.2 # 设置添加灰度噪声的概率为0.4
jpeg_range = [95, 98] # 设置JPEG压缩的质量范围为90到95 值越低说明压缩比越高,质量越差
#################################################################################################################
# ----------------------- The first degradation process ----------------------- #
# blur
out = filter2D(gt_usm, kernel1) # 使用第一个卷积核对锐化后的高质量图像进行卷积
# random resize
updown_type = random.choices(['up', 'down', 'keep'], resize_prob)[0] # 随机选择一个缩放类型
if updown_type == 'up': # 这个if-elif-else语句根据缩放类型选择缩放因子
scale = np.random.uniform(1, resize_range[1])
elif updown_type == 'down':
scale = np.random.uniform(resize_range[0], 1)
else:
scale = 1
mode = random.choice(['area', 'bilinear', 'bicubic'])
# out = F.interpolate(out, scale_factor=scale, mode=mode) # 对图像进行缩放
out = out.float() # 将out转换为浮点类型
out = F.interpolate(out, size = (int(ori_h / scale_scale * scale), int(ori_w / scale_scale * scale)), mode = mode)
# add noise
gray_noise_prob = gray_noise_prob
if np.random.uniform() < gaussian_noise_prob: # 这个if-else语句根据概率选择添加高斯噪声或泊松噪声
out = random_add_gaussian_noise_pt(out, sigma_range=noise_range, clip=True, rounds=False, gray_prob=gray_noise_prob)
else:
out = random_add_poisson_noise_pt(out,scale_range=poisson_scale_range,gray_prob=gray_noise_prob,clip=True,rounds=False)
# JPEG compression
# jpeg_p = out.new_zeros(out.size(0)).uniform_(*jpeg_range)
# # out = torch.clamp(out, 0,1) # clamp to [0, 1], otherwise JPEGer will result in unpleasant artifacts # 将图像的像素值限制在[0, 1]范围内
# out = jpeger(out, quality=jpeg_p) # 对图像进行JPEG压缩
lq = torch.clamp((out * 255.0).round(), 0, 255) / 255.
return lq
if __name__ == "__main__":
folder_path = '/visible_image/'
output_path = '/result_images/'
# 获取文件夹中所有的文件
file_list = os.listdir(folder_path)
# 遍历文件列表
for file_name in tqdm(file_list,desc="Processing images"):
# 拼接文件路径
file_path = os.path.join(folder_path, file_name)
# 仅处理图像文件
if os.path.isfile(file_path) and file_name.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
# 读取图像路径
image = cv2.imread(file_path)
image = image.astype(np.float32) / 255
# BGR to RGB, HWC to CHW, numpy to tensor
image_tensor = img2tensor([image],bgr2rgb=True,float32=True)[0]
# 增加一个维度
image_tensor = image_tensor.unsqueeze(0)
# print(image_tensor.shape)
image_degratation = degration_image(image_tensor)
# 保存图像
output_lq = image_degratation.detach().squeeze().float().cpu().clamp_(0, 1).numpy() # 代码对处理后的图像进行一系列操作,包括删除尺寸为1的维
output_lq = np.transpose(output_lq[[2, 1, 0], :, :], (1, 2, 0))
output_lq = (output_lq * 255.0).round().astype(np.uint8) # 这行代码将图像的像素值从[0, 1]范围变为[0, 255]范围,并四舍五入到最近的整数,然后转
output_name = file_name
print(output_name)
cv2.imwrite(os.path.join(output_path, output_name), output_lq) # 将处理后的图像保存为BMP格式的文件。
四、效果展示
下面对比结果中,左图为原图,右图在左图基础上一阶上采样2倍模拟的退化图像。
五、总结
以上就是一阶降解上采样2倍模拟退化真实噪声图像的详细过程,不管是上采样退化还是下采样退化,都可以在我提供源码基础上自习修改。还可以再添加一个降解过程,串成二阶降解模拟真实噪声图像。
感谢您阅读到最后!😊总结不易,多多支持呀🌹 点赞👍收藏⭐评论✍️,您的三连是我持续更新的动力💖
关注下面「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!