数据增强(Data Augmentation)

深度学习--数据增强总结 数据增强(Data Augmentation)是一种通过对现有数据进行多种转换和变换,从而生成更多样本的方法。其主要目的是通过增加数据量和多样性,帮助模型更好地泛化,减少过拟合现象。数据增强方法广泛应用于计算机视觉、自然语言处理、语音识别等领域。在深度学习中,由于模型通常需要大量的标注数据,数据增强成为提升模型性能的重要手段。 阅读详情


前言

最近写论文需要插入很多图片,为了蒙混过关,找了很多很多数据增强的手段,增强论文的丰富性,大家不要学我哈,反正我把技巧放这儿了!!!哈哈哈哈哈哈哈哈哈
在这里插入图片描述

1. Data Augmentation

1.1 数据增强的作用

大家都知道在深度学习网络训练中,模型的样本越充足训练出来的网络模型泛化性越强,鲁棒性越高。最好的例子就是SSD对大目标效果很好,对小目标效果很差,但当使用数据增强后,涨分立马上去了,原因就在于数据增强crop,可以让小目标变成大目标。

  1. 增加训练的数据量,提高模型的泛化能力
  2. 增加噪声数据,提升模型的鲁棒性
  3. 一定程度上能解决过拟合问题,样本过少容易出现过拟合
  4. 解决样本不平衡问题,例如某个类别过少,数据增强可以增强这个类别的数量。

1.2 图像增强小工具

我写了一款图像增强的小工具,大家可以查看连接下载使用
在这里插入图片描述

2. 数据增强的手段

数据增强的手段太多了,我就不一一解释了,直接总结吧

  1. 几何变换:反转/平移/旋转/缩放/裁剪
  2. 颜色变换:加噪声/亮度/饱和度/颜色反转/直方图均衡/色彩平衡/
  3. 基于GAN网络数据增强:用生成模型,生成不同风格的图像
  4. 高级增强:Cutout/Mixup/One-hot/Cutmix/AutoAugment/Sample pairing/FMix
  5. 网络中增强:RandAugment/Refinement/Mosaic/DropOut/DropOut/DropBlock

下面简单是介绍一些大家可能不太熟悉的概念:
Cutout:图像中挖掉一个矩形快补0
Mixup:image——两张图片线性叠加,label——one-hot形式进行相同的线性叠加
Cutmix:Cutout + Mixup,image——在图片中挖出来的矩形用另外一张图片填充,label——做同样的叠加
Sample pairing:image——两张图片直接做平均,label——选取其中一张
FMix:采用Fourier变换选取挖掉和补充的区域
推荐一下网站:
https://segmentfault.com/a/1190000022784467
https://jishuin.proginn.com/p/763bfbd29660
https://www.pythonf.cn/read/169722

3. 数据增强的代码

3.1 代码

如果大家想深入了解,建议大家跑跑代码

import os
import cv2
import numpy as np

class Resize(object):
    """
    调整大小
    """

    def __init__(self, output_size):
        self.output_size = output_size

    def __call__(self, X, Y):
        _X = cv2.resize(X, self.output_size, interpolation=cv2.INTER_NEAREST)
        w, h = self.output_size
        c = Y.shape[-1]
        # _Y = cv2.resize(Y, self.output_size)
        _Y = np.zeros((h, w, c))
        for i in range(Y.shape[-1]):
            _Y[..., i] = cv2.resize(Y[..., i], self.output_size, interpolation=cv2.INTER_NEAREST)
        return _X, _Y[...,0]

class Clip(object):
    """
    彩色截断
    """
    def __init__(self, mini, maxi=None):
        if maxi is None:
            self.mini, self.maxi = 0, mini
        else:
            self.mini, self.maxi = mini, maxi

    def __call__(self, X, Y):
        mini_mask = np.where(X < self.mini)
        maxi_mask = np.where(X > self.maxi)
        X[mini_mask] = self.mini
        X[maxi_mask] = self.maxi
        return X, Y

class Normalize(object):
    """
   最大最小值归一化
    """
    def __init__(self, axis=None):
        self.axis = axis

    def __call__(self, X, Y):
        mini = np.min(X, self.axis)
        maxi = np.max(X, self.axis)
        X = (X - mini) / (maxi - mini)
        X = 255 * X
        return X, Y

class Standardize(object):
    """
    标准归一化
    """

    def __init__(self, axis=None):
        self.axis = axis

    def __call__(self, X, Y):
        mean =  np.mean(X, self.axis)
        std = np.std(X, self.axis)
        X = (X - mean) / std
        X = 255 * X
        return X, Y

class Flip(object):
    """
    反转
    """
    def __call__(self, X, Y):
        for axis in [0, 1]:
            if np.random.rand(1) < 0.5:
                X = np.flip(X, axis)
                Y = np.flip(Y, axis)
        return X, Y

class Crop(object):
    def __init__(self, min_size_ratio, max_size_ratio=(1, 1)):
        self.min_size_ratio = np.array(list(min_size_ratio))
        self.max_size_ratio = np.array(list(max_size_ratio))

    def __call__(self, X, Y):
        size = np.array(X.shape[:2])
        mini = self.min_size_ratio * size
        maxi = self.max_size_ratio * size
        # random size
        h = np.random.randint(mini[0], maxi[0])
        w = np.random.randint(mini[1], maxi[1])
        # random place
        shift_h = np.random.randint(0, size[0] - h)
        shift_w = np.random.randint(0, size[1] - w)
        X = X[shift_h:shift_h+h, shift_w:shift_w+w]
        Y = Y[shift_h:shift_h+h, shift_w:shift_w+w]

        return X, Y

class CustomFilter(object):
    def __init__(self, kernel):
        self.kernel = kernel

    def __call__(self, X, Y):
        X = cv2.filter2D(X, -1, self.kernel)
        return X, Y

class Sharpen(object):
    """
    锐化
    """
    def __init__(self, max_center=4):
        self.max_center = max_center
        self.identity = np.array([[0, 0, 0],
                                  [0, 1, 0],
                                  [0, 0, 0]])
        self.sharpen = np.array([[ 0, -1,  0],
                                [-1,  4, -1],
                                [ 0, -1,  0]]) / 4

    def __call__(self, X, Y):

        sharp = self.sharpen * np.random.random() * self.max_center
        kernel = self.identity + sharp

        X = cv2.filter2D(X, -1, kernel)
        return X, Y

class GaussianBlur(object):
    """
    高斯滤波
    """
    def __init__(self, max_kernel=np.array([7, 7])):
        self.max_kernel = ((max_kernel + 1) // 2)

    def __call__(self, X, Y):
        kernel_size = (
            np.random.randint(1, self.max_kernel[0]) * 2 + 1,
            np.random.randint(1, self.max_kernel[1]) * 2 + 1,
        )
        X = cv2.GaussianBlur(X, kernel_size, 0)
        return X, Y

class Perspective(object):
    """
    透视
    """
    def __init__(self,
                 max_ratio_translation=(0.2, 0.2, 0),
                 max_rotation=(10, 10, 360),
                 max_scale=(0.1, 0.1, 0.2),
                 max_shearing=(15, 15, 5)):

        self.max_ratio_translation = np.array(max_ratio_translation)
        self.max_rotation = np.array(max_rotation)
        self.max_scale = np.array(max_scale)
        self.max_shearing = np.array(max_shearing)

    def __call__(self, X, Y):

        # get the height and the width of the image
        h, w = X.shape[:2]
        max_translation = self.max_ratio_translation * np.array([w, h, 1])
        # get the values on each axis
        t_x, t_y, t_z = np.random.uniform(-1, 1, 3) * max_translation
        r_x, r_y, r_z = np.random.uniform(-1, 1, 3) * self.max_rotation
        sc_x, sc_y, sc_z = np.random.uniform(-1, 1, 3) * self.max_scale + 1
        sh_x, sh_y, sh_z = np.random.uniform(-1, 1, 3) * self.max_shearing

        # convert degree angles to rad
        theta_rx = np.deg2rad(r_x)
        theta_ry = np.deg2rad(r_y)
        theta_rz = np.deg2rad(r_z)
        theta_shx = np.deg2rad(sh_x)
        theta_shy = np.deg2rad(sh_y)
        theta_shz = np.deg2rad(sh_z)


        # compute its diagonal
        diag = (h ** 2 + w ** 2) ** 0.5
        # compute the focal length
        f = diag
        if np.sin(theta_rz) != 0:
            f /= 2 * np.sin(theta_rz)

        # set the image from cartesian to projective dimension
        H_M = np.array([[1, 0, -w / 2],
                        [0, 1, -h / 2],
                        [0, 0,      1],
                        [0, 0,      1]])
        # set the image projective to carrtesian dimension
        Hp_M = np.array([[f, 0, w / 2, 0],
                         [0, f, h / 2, 0],
                         [0, 0,     1, 0]])

        # adjust the translation on z
        t_z = (f - t_z) / sc_z ** 2
        # translation matrix to translate the image
        T_M = np.array([[1, 0, 0, t_x],
                        [0, 1, 0, t_y],
                        [0, 0, 1, t_z],
                        [0, 0, 0,  1]])

        # calculate cos and sin of angles
        sin_rx, cos_rx = np.sin(theta_rx), np.cos(theta_rx)
        sin_ry, cos_ry = np.sin(theta_ry), np.cos(theta_ry)
        sin_rz, cos_rz = np.sin(theta_rz), np.cos(theta_rz)
        # get the rotation matrix on x axis
        R_Mx = np.array([[1,      0,       0, 0],
                         [0, cos_rx, -sin_rx, 0],
                         [0, sin_rx,  cos_rx, 0],
                         [0,      0,       0, 1]])
        # get the rotation matrix on y axis
        R_My = np.array([[cos_ry, 0, -sin_ry, 0],
                         [     0, 1,       0, 0],
                         [sin_ry, 0,  cos_ry, 0],
                         [     0, 0,       0, 1]])
        # get the rotation matrix on z axis
        R_Mz = np.array([[cos_rz, -sin_rz, 0, 0],
                         [sin_rz,  cos_rz, 0, 0],
                         [     0,       0, 1, 0],
                         [     0,       0, 0, 1]])
        # compute the full rotation matrix
        R_M = np.dot(np.dot(R_Mx, R_My), R_Mz)

        # get the scaling matrix
        Sc_M = np.array([[sc_x,     0,    0, 0],
                         [   0,  sc_y,    0, 0],
                         [   0,     0, sc_z, 0],
                         [   0,     0,    0, 1]])

        # get the tan of angles
        tan_shx = np.tan(theta_shx)
        tan_shy = np.tan(theta_shy)
        tan_shz = np.tan(theta_shz)
        # get the shearing matrix on x axis
        Sh_Mx = np.array([[      1, 0, 0, 0],
                          [tan_shy, 1, 0, 0],
                          [tan_shz, 0, 1, 0],
                          [      0, 0, 0, 1]])
        # get the shearing matrix on y axis
        Sh_My = np.array([[1, tan_shx, 0, 0],
                          [0,       1, 0, 0],
                          [0, tan_shz, 1, 0],
                          [0,       0, 0, 1]])
        # get the shearing matrix on z axis
        Sh_Mz = np.array([[1, 0, tan_shx, 0],
                          [0, 1, tan_shy, 0],
                          [0, 0,       1, 0],
                          [0, 0,       0, 1]])
        # compute the full shearing matrix
        Sh_M = np.dot(np.dot(Sh_Mx, Sh_My), Sh_Mz)

        Identity = np.array([[1, 0, 0, 0],
                             [0, 1, 0, 0],
                             [0, 0, 1, 0],
                             [0, 0, 0, 1]])

        # compute the full transform matrix
        M = Identity
        M = np.dot(Sh_M, M)
        M = np.dot(R_M,  M)
        M = np.dot(Sc_M, M)
        M = np.dot(T_M,  M)
        M = np.dot(Hp_M, np.dot(M, H_M))
        # apply the transformation
        X = cv2.warpPerspective(X, M, (w, h))
        Y = cv2.warpPerspective(Y, M, (w, h))
        return X, Y

class Cutout(object):
    """
    随机擦除
    """
    def __init__(self,
                 min_size_ratio,
                 max_size_ratio,
                 channel_wise=False,
                 crop_target=True,
                 max_crop=10,
                 replacement=0):
        self.min_size_ratio = np.array(list(min_size_ratio))
        self.max_size_ratio = np.array(list(max_size_ratio))
        self.channel_wise = channel_wise
        self.crop_target = crop_target
        self.max_crop = max_crop
        self.replacement = replacement

    def __call__(self, X, Y):
        size = np.array(X.shape[:2])
        mini = self.min_size_ratio * size
        maxi = self.max_size_ratio * size
        for _ in range(self.max_crop):
            # random size
            h = np.random.randint(mini[0], maxi[0])
            w = np.random.randint(mini[1], maxi[1])
            # random place
            shift_h = np.random.randint(0, size[0] - h)
            shift_w = np.random.randint(0, size[1] - w)
            if self.channel_wise:
                c = np.random.randint(0, X.shape[-1])
                X[shift_h:shift_h+h, shift_w:shift_w+w, c] = self.replacement
                if self.crop_target:
                    Y[shift_h:shift_h+h, shift_w:shift_w+w] = self.replacement
            else:
                X[shift_h:shift_h+h, shift_w:shift_w+w] = self.replacement
                if self.crop_target:
                    Y[shift_h:shift_h+h, shift_w:shift_w+w] = self.replacement
        return X, Y

class Leaf(object):
    def __init__(self):
        pass
    def __call__(self, X, Y):
        blur = cv2.GaussianBlur(X, (7, 7), 0)
        hsv_blur = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
        # lower mask (0-10)
        lower_red = np.array([0,130,130])
        upper_red = np.array([20,255,255])
        mask_0 = cv2.inRange(hsv_blur, lower_red, upper_red)

        # upper mask (170-180)
        lower_red = np.array([165,130,130])
        upper_red = np.array([185,255,255])
        mask_1 = cv2.inRange(hsv_blur, lower_red, upper_red)
        hsv_blur[np.where(mask_1)] = hsv_blur[np.where(mask_1)] - np.array([165, 0, 0])

        mask = mask_0 + mask_1
        # change color
        turn_color = np.random.randint(0, 255)
        hsv_blur[np.where(mask)] = hsv_blur[np.where(mask)] + np.array([turn_color, 0, 0])
        X_blur = cv2.cvtColor(hsv_blur, cv2.COLOR_HSV2BGR)
        X[np.where(mask)] = X_blur[np.where(mask)]
        return X, Y

class Brightness(object):
    """
    随机改变图像的亮度
    """
    def __init__(self, range_brightness=(-50, 50)):
        self.range_brightness = range_brightness

    def __call__(self, X, Y):
        brightness = np.random.randint(*self.range_brightness)
        X = X + brightness
        return X, Y

class Contrast(object):
    """
    改变图像的对比度
    """

    def __init__(self, range_contrast=(-50, 50)):
        self.range_contrast = range_contrast

    def __call__(self, X, Y):
        contrast = np.random.randint(*self.range_contrast)
        X = X * (contrast / 127 + 1) - contrast
        return X, Y

class UniformNoise(object):
    """
    均匀噪声
    """
    def __init__(self, low=-50, high=50):
        self.low = low
        self.high = high

    def __call__(self, X, Y):
        noise = np.random.uniform(self.low, self.high, X.shape)
        X = X + noise
        return X, Y

class GaussianNoise(object):
    def __init__(self, center=0, std=50):
        self.center = center
        self.std = std

    def __call__(self, X, Y):
        noise = np.random.normal(self.center, self.std, X.shape)
        X = X + noise
        return X, Y

class Vignetting(object):
    def __init__(self,
                 ratio_min_dist=0.2,
                 range_vignette=(0.2, 0.8),
                 random_sign=False):
        self.ratio_min_dist = ratio_min_dist
        self.range_vignette = np.array(range_vignette)
        self.random_sign = random_sign

    def __call__(self, X, Y):
        h, w = X.shape[:2]
        min_dist = np.array([h, w]) / 2 * np.random.random() * self.ratio_min_dist

        # create matrix of distance from the center on the two axis
        x, y = np.meshgrid(np.linspace(-w/2, w/2, w), np.linspace(-h/2, h/2, h))
        x, y = np.abs(x), np.abs(y)

        # create the vignette mask on the two axis
        x = (x - min_dist[0]) / (np.max(x) - min_dist[0])
        x = np.clip(x, 0, 1)
        y = (y - min_dist[1]) / (np.max(y) - min_dist[1])
        y = np.clip(y, 0, 1)

        # then get a random intensity of the vignette
        vignette = (x + y) / 2 * np.random.uniform(*self.range_vignette)
        vignette = np.tile(vignette[..., None], [1, 1, 3])

        sign = 2 * (np.random.random() < 0.5) * (self.random_sign) - 1
        X = X * (1 + sign * vignette)

        return X, Y

class LensDistortion(object):
    def __init__(self, d_coef=(0.15, 0.15, 0.1, 0.1, 0.05)):
        self.d_coef = np.array(d_coef)

    def __call__(self, X, Y):

        # get the height and the width of the image
        h, w = X.shape[:2]

        # compute its diagonal
        f = (h ** 2 + w ** 2) ** 0.5

        # set the image projective to carrtesian dimension
        K = np.array([[f, 0, w / 2],
                      [0, f, h / 2],
                      [0, 0,     1]])

        d_coef = self.d_coef * np.random.random(5) # value
        d_coef = d_coef * (2 * (np.random.random(5) < 0.5) - 1) # sign
        # Generate new camera matrix from parameters
        M, _ = cv2.getOptimalNewCameraMatrix(K, d_coef, (w, h), 0)

        # Generate look-up tables for remapping the camera image
        remap = cv2.initUndistortRectifyMap(K, d_coef, None, M, (w, h), 5)

        # Remap the original image to a new image
        X = cv2.remap(X, *remap, cv2.INTER_LINEAR)
        Y = cv2.remap(Y, *remap, cv2.INTER_LINEAR)
        return X, Y


def data_aug(img_path,  label_path, save_img, save_label):
    imgs = os.listdir(img_path)
    for im_name in imgs:
        name = im_name.split('.')[0]
        im_full_path = os.path.join(img_path, im_name)
        lab_full_path = os.path.join(label_path, im_name)

        
        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path)
        # save_img_path = os.path.join(save_img, name + '_Resize960.png')
        # save_lab_path = os.path.join(save_label, name + '_Resize960.png')
        # im_Resize, lab_Resize = Resize((960,960))(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im_Resize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab_Resize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path)
        # save_img_path = os.path.join(save_img, name + '_Resize384.png')
        # save_lab_path = os.path.join(save_label, name + '_Resize384.png')
        # im_Resize, lab_Resize = Resize((384,384))(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im_Resize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab_Resize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Clip.png')
        # save_lab_path = os.path.join(save_label, name + '_Clip.png')
        # im_Clip, lab_Clip = Clip(20,150)(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im_Clip, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab_Clip, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Normalize.png')
        # save_lab_path = os.path.join(save_label, name + '_Normalize.png')
        # im_Normalize, lab_Normalize = Normalize(1)(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im_Normalize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab_Normalize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Standardize.png')
        # save_lab_path = os.path.join(save_label, name + '_Standardize.png')
        # im_Standardize, lab_Standardize = Standardize(1)(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im_Standardize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab_Standardize, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path)
        # save_img_path = os.path.join(save_img, name + '_Flip.png')
        # save_lab_path = os.path.join(save_label, name + '_Flip.png')
        # im__Flip, lab__Flip= Flip()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Flip, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Flip, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Crop.png')
        # save_lab_path = os.path.join(save_label, name + '_Crop.png')
        # im__Crop, lab__Crop = Crop((0.5,0.5))(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Crop, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Crop, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_CustomFilter.png')
        # save_lab_path = os.path.join(save_label, name + '_CustomFilter.png')
        # lpls = np.array([[-1,1,-1],[1,8,-1],[-1,1,-1]])
        # im_CustomFilter, lab_CustomFilter = CustomFilter(lpls)(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im_CustomFilter, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab_CustomFilter, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Sharpen.png')
        # save_lab_path = os.path.join(save_label, name + '_Sharpen.png')
        # im__Sharpen, lab__Sharpen = Sharpen()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Sharpen, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Sharpen, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_GaussianBlur.png')
        # save_lab_path = os.path.join(save_label, name + '_GaussianBlur.png')
        # im__GaussianBlur, lab__GaussianBlur = GaussianBlur()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__GaussianBlur, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__GaussianBlur, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Perspective.png')
        # save_lab_path = os.path.join(save_label, name + '_Perspective.png')
        # im__Perspective, lab__Perspective = Perspective()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Perspective, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Perspective, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Cutout.png')
        # save_lab_path = os.path.join(save_label, name + '_Cutout.png')
        # im__Cutout, lab__Cutout = Cutout([0.01,0.05],[0.2,0.3])(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Cutout, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Cutout, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Leaf.png')
        # save_lab_path = os.path.join(save_label, name + '_Leaf.png')
        # im__Leaf, lab__Leaf = Leaf()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Leaf, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Leaf, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Brightness.png')
        # save_lab_path = os.path.join(save_label, name + '_Brightness.png')
        # im__Brightness, lab__Brightness = Brightness()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Brightness, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Brightness, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Contrast.png')
        # save_lab_path = os.path.join(save_label, name + '_Contrast.png')
        # im__Contrast, lab__Contrast = Contrast()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Contrast, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Contrast, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_UniformNoise.png')
        # save_lab_path = os.path.join(save_label, name + '_UniformNoise.png')
        # im__UniformNoise, lab__UniformNoise = UniformNoise()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__UniformNoise, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__UniformNoise, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_GaussianNoise.png')
        # save_lab_path = os.path.join(save_label, name + '_GaussianNoise.png')
        # im__GaussianNoise, lab__GaussianNoise = GaussianNoise()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__GaussianNoise, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__GaussianNoise, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        # im_arr = cv2.imread(im_full_path)
        # lab_arr = cv2.imread(lab_full_path,0)
        # save_img_path = os.path.join(save_img, name + '_Vignetting.png')
        # save_lab_path = os.path.join(save_label, name + '_Vignetting.png')
        # im__Vignetting, lab__Vignetting = Vignetting()(im_arr, lab_arr)
        # cv2.imwrite(save_img_path, im__Vignetting, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        # cv2.imwrite(save_lab_path, lab__Vignetting, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

        im_arr = cv2.imread(im_full_path)
        lab_arr = cv2.imread(lab_full_path,0)
        save_img_path = os.path.join(save_img, name + '_LensDistortion.png')
        save_lab_path = os.path.join(save_label, name + '_LensDistortion.png')
        im__LensDistortion, lab__LensDistortion = LensDistortion()(im_arr, lab_arr)
        cv2.imwrite(save_img_path, im__LensDistortion, [int(cv2.IMWRITE_PNG_COMPRESSION),0])
        cv2.imwrite(save_lab_path, lab__LensDistortion, [int(cv2.IMWRITE_PNG_COMPRESSION),0])

if __name__ == "__main__":
    img_path = './crop/1/'
    label_path = './crop/1/'

    save_img = './crop/1/'
    if not os.path.exists(save_img):
        os.makedirs(save_img)
    save_label = './crop/1/'
    if not os.path.exists(save_label):
        os.makedirs(save_label)

    data_aug(img_path, label_path, save_img, save_label)

3.2 结果

对了,建议大家用彩色图片,效果明显,我直接用我论文的图了。
在这里插入图片描述

a)Image;b)Resize;c)Clip;d)Normalize;f)Standardize;g)Flip;h)Crop i)Custom Filter;j)Sharpen;k)Gaussian Blur;l)Perspective;m)Cutout;n)Brightness;o)Contrast;p)Uniform Noise;q)Gaussian Noise

代码2

import torchvision.transforms as transforms

from PIL import Image

img = Image.open('tina.jpg')

'''
# CenterCrop
size = (224, 224)
transform = transforms.CenterCrop(size)
center_crop = transform(img)
center_crop.save('center_crop.jpg')
# ColorJitter
brightness = (1, 10)
contrast = (1, 10)
saturation = (1, 10)
hue = (0.2, 0.4)
transform = transforms.ColorJitter(brightness, contrast, saturation, hue)
color_jitter = transform(img)
color_jitter.save('color_jitter.jpg')
# FiveCrop
size = (224, 224)
transform = transforms.FiveCrop(size)
five_crop = transform(img)
for index, img in enumerate(five_crop):
    img.save(str(index) + '.jpg')
# Grayscale
transform = transforms.Grayscale()
grayscale = transform(img)
grayscale.save('grayscale.jpg')
# Compose, Pad
size = (224, 224)
padding = 16
fill = (0, 0, 255)
transform = transforms.Compose([
        transforms.CenterCrop(size),
        transforms.Pad(padding, fill)
])
pad = transform(img)
pad.save('pad.jpg')
# RandomAffine
degrees = (15, 30)
translate=(0, 0.2)
scale=(0.8, 1)
fillcolor = (0, 0, 255)
transform = transforms.RandomAffine(degrees=degrees, translate=translate, scale=scale, fillcolor=fillcolor)
random_affine = transform(img)
random_affine.save('random_affine.jpg')
# RandomApply
size = (224, 224)
padding = 16
fill = (0, 0, 255)
transform = transforms.RandomApply([transforms.CenterCrop(size), transforms.Pad(padding, fill)])
for i in range(3):
    random_apply = transform(img)
    random_apply.save(str(i) + '.jpg')
# RandomChoice
transform = transforms.RandomChoice([transforms.RandomAffine(degrees), 
                                     transforms.CenterCrop(size), 
                                     transforms.Pad(padding, fill)])
for i in range(3):
    random_order = transform(img)
    random_order.save(str(i) + '.jpg')
# RandomCrop
size = (224, 224)
transform = transforms.RandomCrop(size)
random_crop = transform(img)
random_crop.save('p.jpg')
# RandomGrayscale
p = 0.5
transform = transforms.RandomGrayscale(p)
for i in range(3):
    random_grayscale = transform(img)
    random_grayscale.save(str(i) + '.jpg')
# RandomHorizontalFlip
p = 0.5
transform = transforms.RandomHorizontalFlip(p)
for i in range(3):
    random_horizontal_filp = transform(img)
    random_horizontal_filp.save(str(i) + '.jpg')
# RandomOrder
size = (224, 224)
padding = 16
fill = (0, 0, 255)
degrees = (15, 30)
transform = transforms.RandomOrder([transforms.RandomAffine(degrees), 
                                    transforms.CenterCrop(size), 
                                    transforms.Pad(padding, fill)])
for i in range(3):
    random_order = transform(img)
    random_order.save(str(i) + '.jpg')
# RandomPerspective
distortion_scale = 1
p = 1
fill = (0, 0, 255)
transform = transforms.RandomPerspective(distortion_scale=distortion_scale, p=p, fill=fill)
random_perspective = transform(img)
random_perspective.save('random_perspective.jpg')
# RandomResizedCrop
size = (256, 256)
scale=(0.8, 1.0)
ratio=(0.75, 1.0)
transform = transforms.RandomResizedCrop(size=size, scale=scale, ratio=ratio)
random_resized_crop = transform(img)
random_resized_crop.save('random_resized_crop.jpg')
# RandomRotation
degrees = (15, 30)
fill = (0, 0, 255)
transform = transforms.RandomRotation(degrees=degrees, fill=fill)
random_rotation = transform(img)
random_rotation.save('random_rotation.jpg')
# RandomVerticalFlip
p = 1
transform = transforms.RandomVerticalFlip(p)
random_vertical_filp = transform(img)
random_vertical_filp.save('random_vertical_filp.jpg')
# Resize
size = (224, 224)
transform = transforms.Resize(size)
resize_img = transform(img)
resize_img.save('resize_img.jpg')
# ToPILImage
img = Image.open('tina.jpg')
transform = transforms.ToTensor()
img = transform(img)
print(img.size())
img_r = img[0, :, :]
img_g = img[1, :, :]
img_b = img[2, :, :]
print(type(img_r))
print(img_r.size())
transform = transforms.ToPILImage()
img_r = transform(img_r)
img_g = transform(img_g)
img_b = transform(img_b)
print(type(img_r))
img_r.save('img_r.jpg')
img_g.save('img_g.jpg')
img_b.save('img_b.jpg')
# ToTensor
img = Image.open('tina.jpg')
print(type(img))
print(img.size)
transform = transforms.ToTensor()
img = transform(img)
print(type(img))
print(img.size())
'''

# RandomErasing
p = 1.0
scale = (0.2, 0.3)
ratio = (0.5, 1.0)
value = (0, 0, 255)

transform = transforms.Compose([
                transforms.ToTensor(),
                transforms.RandomErasing(p=p, scale=scale, ratio=ratio, value=value),
                transforms.ToPILImage()
            ])
random_erasing = transform(img)
random_erasing.save('random_erasing.jpg')
数据增强(Data Augmentation)汇总 【写在开头】什么是数据增强? 数据增强是一种数据扩充技术,指的是利用有限的数据创造尽可能多的利用价值。因为虽然现在各种任务的公开数据集有很多,但是其实数据量也远远不够,而公司或者学术界去采集、制作这些数据的成本其实是很高的,像人工标注数据的任务量就很大,因此,只能通过一些方法去更好的利用现有的成本,数据增强便“粉墨登场”!以下列举几种数据增强方式及对应论文。 【一】传统数据增强 传统数据增强方式有随机翻转、旋转、裁剪、变形缩放、添加噪声、颜色扰动等等。 随机翻转 随机旋转 随.. 阅读详情

相关推荐

data augmentation 数据增强方法总结

1、问题描述 收集数据准备微调深度学习模型时,经常会遇到某些分类数据严重不足的情况,另外数据集过小容易造成模型的过拟合。 本文参考和中对于数据增强方法的一些tips,后续会附上自己实现的C++代码; 2、data augmentation常用方法 Color Jittering:对颜色的数据增强:图像亮度、饱和度、对比度变化(此处对色彩抖动的理解不知是否得当);PCA  J

u010555688的专栏 4万+

数据增强(Data Augmentation)常用方法汇总

1、数据增强的作用 1)避免过拟合。当数据集具有某种明显的特征,例如数据集中图片基本在同一个场景中拍摄,使用Cutout方法和风格迁移变化等相关方法可避免模型学到跟目标无关的信息。 2)提升模型鲁棒性,降低模型对图像的敏感度。当训练数据都属于比较理想的状态,碰到一些特殊情况,如遮挡,亮度,模糊等情况容易识别错误,对训练数据加上噪声,掩码等方法可提升模型鲁棒性。 3)增加训练数据,提高模型泛化能力。 4)避免样本不均衡。在工业缺陷检测方...

alex1801 9万+

Data Augmentation--数据增强解决你有限的数据集

参考来源–感兴趣请戳我戳我. author是Bharath Raj。 以下是翻译内容,有部分删减,感兴趣的可以读原文,该blog仅供学习。笔耕不易,互相交流。 can my “state-of-the-art” neural network perform well with the meagre amount of data I have? Yes.我们的优化目的,是当参数沿着正确的...

chang_rj的博客 6万+

数据增强的原理及实现(超详细)

在深度学习中,数据增强是通过一定的方式改变输入数据,以生成更多的训练样本,从而提高模型的泛化能力和效果。数据增强可以减少模型对某些特征的过度依赖,从而避免过拟合。

AI_dataloads的博客 1万+

深度学习之:数据增强 (Data Augmentation)

深度学习之:数据增强 (Data Augmentation) 内容持续更新中,欢迎各位在评论区补充和讨论! 在当前AI这个数据驱动的时代,没有数据几乎是万万不能的。 你的数据太少? 别怕,我们有数据增强技术!   当前流行的数据增强技 1.翻转(Flip) 可以对图片进行水平和垂直翻转。一些框架不提供垂直翻转功能。但是,一个垂直反转的图片等同于图片的180度旋转,然后再执行水平翻转...

The Best or Nothing. 2万+

【数据增强】Data Augmentation——一种简单有效扩充深度学习训练数据量的方式!

【数据增强】Data Augmentation,学习笔记!

985小水博的摸鱼日常 3590

【机器学习】数据增强(Data Augmentation)

文章目录一、引言 - 背景二、为什么需要数据增强?三、什么是数据增强?定义分类四、有监督的数据增强1. 单样本数据增强(1)几何变换类(2)颜色变换类2. 多样本数据增强(1) SMOTE(2) SamplePairing(3) mixup五、无监督的数据增强1. GAN2.Conditional GANs3. Autoaugmentation六、数据增强过程中需要注意的问题七、总结参考链接 一、引言 - 背景 很多实际的项目,我们都难以有充足的数据来完成任务,要保证完美的完成任务,有两件事情需要做好:.

weixin_44211968的博客 11万+

数据增强方法(Data Augmentation)是一种常用且有效的对训练样本进行预处理的方法,目的是通过对原始训练样本进行轻微的变换、扭曲或者添加噪声来扩充训练集,从而提高模型在实际应用中的泛化能力

数据增强(Data Augmentation)是一种常用且有效的对训练样本进行预处理的方法。它的目的是通过对原始训练样本进行轻微的变换、扭曲或者添加噪声,来扩充训练集,从而提高模型在实际应用中的泛化能力。传统的数据增强方法主要基于图像领域,图像增广技术比较成熟,应用也比较广泛,比如卷积神经网络(CNN)中的翻转、裁剪、旋转等数据增强操作。然而对于文本领域来说,这种方法就显得力不从心了。由于文本数据的复杂性、稀疏性以及相对平坦的分布特征,传统的数据增强方法并不能有效地扩充文本数据。

AI天才研究院 1726

Data Augmentation数据增强

数据增强是通过对原始数据进行合理变换来扩充训练集的技术,分为有监督和无监督两类。有监督增强包括单样本操作(如几何/颜色变换)和多样本混合(如SMOTE、mixup)。无监督增强包含随机生成(如GAN)和学习策略(如AutoAugment)。该技术能有效解决数据不足问题,防止模型学习不相关特征,提升泛化能力。例如在图像识别中,通过旋转、颜色调整等操作可增加数据多样性,而不改变图像本质特征。

Frost_Descent的博客 1279

数据增强Data Augmentation原理与代码实例讲解

数据增强Data Augmentation原理与代码实例讲解 1.背景介绍 在机器学习和深度学习领域,数据集的质量和数量对于模型的性能有着至关重要的影响。然而,获取高质量的标注数据通常是一项昂贵且耗时的过程。为了解决这一问题,数据增强(Data Augmentat

AI天才研究院 1518

win10+conda+pytorch-gpu安装

pytorch 官网上只有linux和Mac的程序包,没有windows系统的,但是windows系统还是可以用pytorch的。  github: https://github.com/peterjc123/pytorch-scripts 首先要安装anaconda: 推荐清华镜像 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ ...

一摩尔自由的博客 1万+

Pytorch关于图片数据增强Data Augmentation方法

关于数据增广的笔记

flyingluohaipeng的博客 595

基于MS5351的三通道可编程时钟发生器设计

时钟发生器是数字系统时序验证与信号完整性测试的核心基础设备,其原理基于锁相环(PLL)对参考晶振进行倍频与分频控制,通过寄存器配置实现多路独立频率输出。技术价值体现在高精度、低抖动、快速切换与工程可部署性之间取得平衡,尤其适用于FPGA/ASIC参考时钟调试、ADC/DAC采样时钟验证及嵌入式硬件时序裕量评估等场景。本方案采用MS5351三通道时钟芯片与ESP32主控协同架构,在保证LVCMOS输出质量与I²C可编程性的前提下,优化电源噪声抑制、晶体负载匹配和跨板信号完整性,兼顾成本、周期与实测稳定性,为实

weixin_31715353的博客 211

探索数据增强的未来:Differentiable Data Augmentation Library

探索数据增强的未来:Differentiable Data Augmentation Library 在深度学习领域,数据增强是提升模型性能的关键技术之一。然而,传统数据增强方法往往依赖于手工设计的规则,难以适应复杂多变的实际应用场景。为了解决这一问题,Differentiable Data Augmentation Library(以下简称DDA)应运而生,它通过可微分的数据增强操作,为研究人员...

gitblog_00004的博客 443

英特尔® NUC迷你电脑实现无人值守自动开机配置指南

本文详细介绍了如何配置英特尔® NUC迷你电脑实现无人值守自动开机功能。从BIOS设置到操作系统级配置,涵盖硬件兼容性确认、电源恢复功能设置及常见问题解决,帮助用户轻松实现设备断电后自动恢复运行,适用于家庭服务器、企业终端等多种场景。

weixin_42638178的博客 472

408——计算机组成原理(持续更新)

小数点前的0代表正数,1代表负数。

qq_55202378的博客 1722

【转】data augmentation 数据增强方法总结

转自:http://blog.youkuaiyun.com/u010555688/article/details/60757932 1、问题描述 收集数据准备微调深度学习模型时,经常会遇到某些分类数据严重不足的情况,另外数据集过小容易造成模型的过拟合。 本文参考一些网友对于数据增强方法的一些tips,后续会附上自己实现的C++代码; 2、data augmentation常用方法

lanyuxuan100的博客 4365

【车间调度】车间调度问题的分类

本系列为自己学习调度相关知识的记录,如有误请指出,也欢迎调度方向的小伙伴加我好友共同交流。 车间调度问题的分类 根据工件和车间构成不同,车间调度问题可分为以下几种 1.单机调度问题 在单机调度问题(S,SMP)中,加工系统只有一台机床,待加工的工件有且仅有一道工序,所有工件都在该机床上进行加工。此问题是最简单的调度问题,当生产车间出现瓶颈机床时的调度就可视为此调度问题。 ...

weixin_51656605的博客 7430

Dataset之DA:数据增强(Data Augmentation)的简介、方法、案例应用之详细攻略

Dataset之DA:数据增强(Data Augmentation)的简介、方法、案例应用之详细攻略 目录 DA的简介 DA的方法 DA的案例应用 DA的简介 数据集增强主要是为了减少网络的过拟合现象,通过对训练图片进行变换可以得到泛化能力更强的网络,更好的适应应用场景。 1、数据增强常用的方法—特殊四法之...

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 9804

无人机蜂群作战设计技术详解

构建防御网络,拦截敌方无人机或导弹;无人机蜂群作战设计技术是一种创新的军事应用概念,它基于生物仿生学原理,通过先进的通信技术、自主导航与决策算法,将大量小型、低成本、功能各异的无人机组织成一个高度协同的群体,以执行复杂多样的军事任务。无人机蜂群作战的概念源于自然界中蜜蜂、蚂蚁等生物群体的行为模式,这些生物群体通过简单的个体间的信息交互和分工协作,能够完成远远超出单一个体能力的复杂任务。其中,无人机群体是执行任务的主体,指挥控制系统负责任务分配和决策,通信数据链则保障无人机群体与指挥控制系统之间的信息交换。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 2215

安装 miniconda linux

安装 miniconda linux

jacke121的专栏 1万+

数据增强Data Augmentation

数据增强Data Augmentation数据增强的目的图像变换示例图像数据增强方式总结 数据增强的目的 增大训练数据量能持续提升模型的性能 获取更多数据 - 人工标注数据 合成更多数据 - 数据增强 对于图像数据,可通过图像变换来扩充数据量 图像平移 旋转 缩放 翻转 裁剪 添加图像噪声 通过GAN(生成对抗网络)生成图像来扩充数据量。 图像变换示例 shear:裁剪 scale:尺度变换 rotate:旋转 图像数据增强方式总结 英文名 中文名 Random Hori

LK007CX的博客 732

智能车图像处理21-进阶篇13--正入十字补线2

这篇文章主要的正入十字补线与1基本相同,主要防止图像中双十字的问题。

taiyuezyh的博客 2032

探索数据增强的艺术:Data_Augmentation_Zoo_for_Object_Detection

探索数据增强的艺术:Data_Augmentation_Zoo_for_Object_Detection 在这个高度竞争的计算机视觉领域,数据增强已经成为提升模型性能的关键一环。Data_Augmentation_Zoo_for_Object_Detection 是一个精心设计的开源项目,它聚合了一系列用于物体检测的数据增强策略,旨在帮助开发者和研究者提高模型对各种复杂情况的识别能力。 项目介绍 ...

gitblog_00055的博客 306

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

数据增强(Data Augmentation)

数据增强是通过对现有样本进行合理变形或加噪来扩充训练集,旨在解决数据不足导致的过拟合问题,并提升模型对真实场景噪声和变形的鲁棒性。核心方法包括:1)引入扭曲(如弹性形变),模拟真实形态变化;2)添加符合实际场景的噪声(如背景音或传感器噪声)。有效性关键在于增强必须匹配测试集的真实分布,盲目添加随机噪声可能适得其反。此外,需区分训练集(可加噪声)与测试集(保持原始状态)。高级技术如风格迁移和GAN可生成更逼真的样本。数据增强应基于误差分析,针对模型弱点进行迭代优化,这一方法论适用于计算机视觉、自然语言处理等多

StarPrayers.的博客 1014

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

DATA Augmentation 数据增强

最近遇到一个新的概念,data augmentation。翻译叫做数据增强 增强数据,简单来说,是增强数据在训练中的作用,这么理解应该比较符合我们的习惯。 比如说,我们有一个set的数据,但是这些数据对于实际的训练来说其实是不够的。但是我们只有这么多数据,要怎么办呢?只能在这个基础上进行操作,我们可以对基础数据进行一系列操作,例如:放大,翻转,加噪声等,就得到了更多的数据。同时也增强了数据的多

Duke__Lee的博客 7414

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: yolov5——训练策略
下一篇: 高分辨率图像剪切——目标检测
Charms@
博客等级 码龄6年 771粉丝 52原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值