pytorch图像加噪

skimage中random_noise使用的一些问题:

random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)
    Function to add random noise of various types to a floating-point image.
    
    Parameters
    ----------
    image : ndarray 
        Input image data. Will be converted to float. #输入为ndarry,输出为float
    mode : str, optional
        One of the following strings, selecting the type of noise to add:
#mode名字:
        - 'gaussian'  Gaussian-distributed additive noise.
        - 'localvar'  Gaussian-distributed additive noise, with specified
                      local variance at each point of `image`.
        - 'poisson'   Poisson-distributed noise generated from the data.
        - 'salt'      Replaces random pixels with 1.
        - 'pepper'    Replaces random pixels with 0 (for unsigned images) or
                      -1 (for signed images).
        - 's&p'       Replaces random pixels with either 1 or `low_val`, where
                      `low_val` is 0 for unsigned images or -1 for signed
                      images.
        - 'speckle'   Multiplicative noise using out = image + n*image, where
                      n is uniform noise with specified mean & variance.
    seed : int, optional
        If provided, this will set the random seed before generating noise,
        for valid pseudo-random comparisons.

#范围限定(对我来说,用默认clip(True)即可,我认为) 
   clip : bool, optional
        If True (default), the output will be clipped after noise applied
        for modes `'speckle'`, `'poisson'`, and `'gaussian'`. This is
        needed to maintain the proper image data range. If False, clipping
        is not applied, and the output may extend beyond the range [-1, 1].
    mean : float, optional
        Mean of random distribution. Used in 'gaussian' and 'speckle'.
        Default : 0.

#随机添加噪声的强度(方差,guassian, 范围[0.1],默认0.01)
    var : float, optional
        Variance of random distribution. Used in 'gaussian' and 'speckle'.
        Note: variance = (standard deviation) ** 2. Default : 0.01
    local_vars : ndarray, optional
        Array of positive floats, same shape as `image`, defining the local
        variance at every image point. Used in 'localvar'.

#随机添加噪声的强度(像素点个数, 椒盐, 范围[0.1], 默认0.05)
    amount : float, optional
        Proportion of image pixels to replace with noise on range [0, 1].
        Used in 'salt', 'pepper', and 'salt & pepper'. Default : 0.05
    salt_vs_pepper : float, optional
        Proportion of salt vs. pepper noise for 's&p' on range [0, 1].
        Higher values represent more salt. Default : 0.5 (equal amounts)
    
    Returns
    -------
    out : ndarray
        Output floating-point image data on range [0, 1] or [-1, 1] if the
        input `image` was unsigned or signed, respectively.

自己修改的代码:

def read_image(data_path):  # 读取二进制文件并返回归一化后的图片
    with open(data_path, 'rb') as f:
        data1 = np.fromfile(f, dtype=np.uint8)
        image = np.reshape(data1, (-1, 3, 96, 96))
        images = np.transpose(image, (0, 3, 2, 1))#转换通道.转成RGB通道
    return images/255.0

data_path = "/content/drive/MyDrive/train_X.bin"  # 数据集路径,r表示防止转义
images = read_image(data_path)

def gaussian_noise(images, sigma):
    """sigma: 噪声标准差""" #默认0.01,范围[0,1]
    sigma2 = sigma**2 #/ (255 ** 2)   # 噪声方差
    images_noisy = np.zeros_like(images)
    for ii in range(images.shape[0]):
        image = images[ii]
        # 使用skimage中的函数增加噪音
        noise_im = random_noise(image, mode="gaussian", var=sigma2, clip=True)
        images_noisy[ii] = noise_im
    return images_noisy

images_noise = gaussian_noise(images, 0.1)
print("image_noise:", images_noise.min(), "~", images_noise.max())

def salt_speckle_noise(images, ratio):
    """amount: 噪声数量占比""" #默认0.05,范围[0,1]

    images_noisy = np.zeros_like(images)
    for ii in range(images.shape[0]):
        image = images[ii]
        # 使用skimage中的函数增加噪音
        noise_im = random_noise(image, mode="s&p", amount=ratio) #salt_vs_pepper椒、盐噪声比默认0.5,范围[0.1]
        images_noisy[ii] = noise_im
    return images_noisy

images_noise = salt_speckle_noise(images, 0.05)
print("image_noise:", images_noise.min(), "~", images_noise.max())

关于加噪的其他注意问题:

1.使用 skimage.util.random_noise(img, mode="salt")会导致使用opencv去降噪的函数会提示无法支持的格式 ! 

问题的所在

skimage.util.random_noise()

out : ndarray

Output floating-point image data on range [0, 1] or [-1, 1] if the
input `image` was unsigned or signed, respectively.

该加噪函数(方法)将图像转化[0,1]或者[-1,1],而且数据类型变成了float64类型,而opencv处理的图像格式一般是uint8类型的,因此还需要进行转化。

首先需将[0,1]转化为0-255,然后将浮点float64转为uint8的。因为代码跑在服务器上没有图像界面,因此需要用visdom做图片的显示。附代码:

import cv2
import visdom
import numpy as np
import matplotlib.pyplot as plt
from skimage.util.dtype import convert
import skimage.util
 
viz = visdom.Visdom(env='img')
img = cv2.imread('qiao.jpg', 1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
print(img.dtype)
#img=img.transpose(1,0,2)
# 使用一下函数进行加噪声会导致数据类型从uint8转为float64,而去噪的 函数只能处理8位的uint类型的图片
noise_img = skimage.util.random_noise(img, mode="salt")
# 将加了噪音的[0,1]之间转化为0-255
noise_img = noise_img*255
 
plt.figure(0)
noise_img = noise_img.astype(np.uint8)
viz.image(noise_img.transpose(2, 0, 1))
# denoise = cv2.GaussianBlur(noise_img, (5, 5), 1)
denoise = cv2.GaussianBlur(noise_img, ksize=(3, 3), sigmaX=0)
viz.image(denoise.transpose(2, 0, 1))
denoise_mean = cv2.medianBlur(noise_img, 5)
viz.image(denoise_mean.transpose(2, 0, 1))
denoise_mean = cv2.fastNlMeansDenoising(noise_img,h=30)
viz.text("均值滤波结果")
viz.image(denoise_mean.transpose(2, 0, 1))

### MobilenetV3 的代码实现 #### 使用 PyTorch 实现的 MobileNetV3 结构如下: ```python import torch.nn as nn import torch class h_sigmoid(nn.Module): def __init__(self, inplace=True): super(h_sigmoid, self).__init__() self.relu = nn.ReLU6(inplace=inplace) def forward(self, x): return self.relu(x + 3) / 6 class h_swish(nn.Module): def __init__(self, inplace=True): super(h_swish, self).__init__() self.sigmoid = h_sigmoid(inplace=inplace) def forward(self, x): return x * self.sigmoid(x) class SELayer(nn.Module): def __init__(self, channel, reduction=4): super(SELayer, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channel, channel // reduction), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel), h_sigmoid() ) def forward(self, x): b, c, _, _ = x.size() y = self.avg_pool(x).view(b, c) y = self.fc(y).view(b, c, 1, 1) return x * y def conv_3x3_bn(inp, oup, stride): return nn.Sequential( nn.Conv2d(inp, oup, 3, stride, 1, bias=False), nn.BatchNorm2d(oup), h_swish() ) def conv_1x1_bn(inp, oup): return nn.Sequential( nn.Conv2d(inp, oup, 1, 1, 0, bias=False), nn.BatchNorm2d(oup), h_swish() ) class InvertedResidual(nn.Module): def __init__(self, inp, hidden_dim, oup, kernel_size, stride, use_se, use_hs): super(InvertedResidual, self).__init__() assert stride in [1, 2] self.identity = stride == 1 and inp == oup if inp == hidden_dim: self.conv = nn.Sequential( # dw nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim, bias=False), nn.BatchNorm2d(hidden_dim), h_swish() if use_hs else nn.ReLU(inplace=True), # Squeeze-and-Excite SELayer(hidden_dim) if use_se else nn.Identity(), # pw-linear nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), nn.BatchNorm2d(oup), ) else: self.conv = nn.Sequential( # pw nn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False), nn.BatchNorm2d(hidden_dim), h_swish() if use_hs else nn.ReLU(inplace=True), # dw nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim, bias=False), nn.BatchNorm2d(hidden_dim), # Squeeze-and-Excite SELayer(hidden_dim) if use_se else nn.Identity(), h_swish() if use_hs else nn.ReLU(inplace=True), # pw-linear nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), nn.BatchNorm2d(oup), ) def forward(self, x): if self.identity: return x + self.conv(x) else: return self.conv(x) class MobileNetV3(nn.Module): def __init__(cfgs, mode='small', num_classes=1000, width_mult=1.): super(MobileNetV3, self).__init__() # setting of inverted residual blocks self.cfgs = cfgs assert mode in ['large', 'small'] input_channel = _make_divisible(16 * width_mult, 8) layers = [conv_3x3_bn(3, input_channel, 2)] block = InvertedResidual for k, t, c, use_se, use_hs, s in self.cfgs: output_channel = _make_divisible(c * width_mult, 8) exp_size = _make_divisible(input_channel * t, 8) layers.append(block(input_channel, exp_size, output_channel, k, s, use_se, use_hs)) input_channel = output_channel self.features = nn.Sequential(*layers) self.classifier = nn.Sequential( nn.Linear(exp_size, exp_size), h_swish(), nn.Linear(exp_size, num_classes), ) def forward(self, x): x = self.features(x) x = x.mean([2, 3]) x = self.classifier(x) return x ``` 此代码展示了如何构建一个完整的 MobileNetV3 模型结构,包括自定义激活函数 `h-swish` 和注意力机制模块 SE-Layer。通过调整配置文件中的超参数设置,可以轻松切换到不同的网络变体[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值