imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!)

这篇具有很好参考价值的文章主要介绍了imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

在深度学习和计算机视觉的世界里,数据是模型训练的基石,其质量与数量直接影响着模型的性能。然而,获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此,数据增强技术应运而生,成为了解决这一问题的关键所在。而imgaug,作为一个功能强大的图像增强库,为我们提供了简便且高效的方法来扩充数据集。本系列博客将带您深入了解如何运用imgaug进行图像增强,助您在深度学习的道路上更进一步。我们将从基础概念讲起,逐步引导您掌握各种变换方法,以及如何根据实际需求定制变换序列。让我们一起深入了解这个强大的工具,探索更多可能性,共同推动深度学习的发展。


前期回顾

专栏

  • 数据增强专栏(频繁更新,收藏加关注,数据增强不迷路~)

数据增强博客链接

链接 主要内容
imgaug库图像增强指南(23):从基础到进阶——全面掌握iaa.SaltAndPepper的使用方法 保姆级介绍如何使用 SaltAndPepper方法 为图像添加椒盐噪声
imgaug库图像增强指南(24):iaa.CoarseSaltAndPepper——粗粒度椒盐噪声的魔力(万字长文) 保姆级介绍如何使用 CoarseSaltAndPepper方法 为图像添加粗粒度的椒盐噪声图像块
imgaug库图像增强指南(25):从基础到进阶——全面掌握iaa.Salt的使用方法 保姆级介绍如何使用 Salt方法 为图像添加盐噪声
imgaug库图像增强指南(27):从基础到进阶——全面掌握iaa.Pepper的使用方法 保姆级介绍如何使用 Pepper方法 为图像添加胡椒噪声
imgaug库图像增强指南(28):从基础到进阶——全面掌握iaa.CoarsePepper的使用方法 保姆级介绍如何使用CoarsePepper方法为图像添加粗粒度的胡椒噪声图像块
imgaug库图像增强指南(29):iaa.Invert——RGB图像的颜色反转与细节探索 保姆级介绍如何使用Invert方法实现图像的颜色反转
imgaug库图像增强指南(31):iaa.JpegCompression——探索压缩与质量的微妙平衡 保姆级介绍如何使用JpegCompression方法压缩图像

在本博客中,我们将向您详细介绍imgaug库的数据增强方法 —— CoarseSalt方法


CoarseSalt方法

功能介绍

iaa.CoarseSaltimgaug库中的一个方法,用于在图像中添加粗粒度的盐噪声。以下是三个使用场景举例:

  1. 模拟真实世界的图像:在图像处理和计算机视觉应用中,经常需要使用真实世界的图像作为数据集。然而,收集这些图像可能是一项挑战,尤其是当涉及到特定的场景或条件时。使用iaa.CoarseSalt可以在图像中添加粗粒度的盐噪声,模拟现实世界中由于各种因素(如传感器噪声、环境条件等)导致的图像质量下降。通过这种方式,可以生成更多样化的训练数据集,提高模型的泛化能力。
  2. 数据增强:在机器学习和深度学习中,数据增强是一种常用的技术,用于通过变换原始图像来创建新的训练样本。iaa.CoarseSalt可以与其它数据增强方法结合使用,为训练数据集添加噪声,以增加模型的鲁棒性。通过在训练过程中暴露模型于带有噪声的图像,可以提高模型在实际应用中对噪声的适应性,从而减少噪声对模型性能的影响。
  3. 测试算法的鲁棒性:在评估机器学习算法的性能时,一个重要的考虑因素是算法的鲁棒性。鲁棒性是指算法在面对噪声、异常值和其他干扰时的健壮性。使用iaa.CoarseSalt可以模拟图像中的噪声,并观察算法在这些噪声下的表现。通过这种方式,可以对算法的鲁棒性进行评估和比较,并针对改进算法的鲁棒性进行优化。

语法

import imgaug.augmenters as iaa
aug = iaa.CoarseSalt(p=(0.02, 0.1), size_px=None, size_percent=None, per_channel=False, min_size=3, seed=None, name=None, random_state='deprecated', deterministic='deprecated')

以下是对iaa.CoarseSalt方法中各个参数的详细介绍:

  1. p

    • 类型:可以是浮点数|浮点数元组|浮点数列表。
    • 描述:将像素替换为盐噪声的概率。
      • p为浮点数,则表示将像素替换为盐噪声的概率;
      • p为元组(a, b),则将像素替换为盐噪声的概率为从区间[a, b]中采样的随机数;
      • p为列表,则将像素替换为盐噪声的概率为从列表中随机采样的浮点数;
  2. size_px:

    • 类型:可以是整数|整数元组|整数列表。
    • 描述:定义每个噪声方块的大小。
      • size_px为整数,例如size_px为3,且RGB图像的宽和高都为300。则每个噪声方块大小为(H/size_px, W/size_px), 即(100, 100) ==> 将RGB图像分成9宫格, 每个宫格形状(100, 100), 根据参数p的大小确定有多少个宫格会被替换为盐噪声方块;
      • size_px为元组(a, b),则每个噪声方块大小为(H/size, W/size), size为从区间[a, b]中采样的随机数;
      • size_px为列表,则每个噪声方块大小为(H/size, W/size), size为从列表中随机采样的数;
    • 注意:若size_pxNone,则size_percent参数必须设置。
  3. size_percent:

    • 类型:可以是浮点数|浮点数元组|浮点数列表。
    • 描述:定义每个噪声方块的大小。
      • size_percent为浮点数0.02,则每个噪声方块大小为(1/size_percent, 1/size_percent), 即(50, 50);
      • size_percent为元组(a, b),则每个噪声方块大小为(1/size, 1/size), size为从区间[a, b]中采样的随机数;
      • size_percent为列表,则每个噪声方块大小为(1/size, 1/size), size为从列表中随机采样的数;
    • 注意:若size_percentNone,则size_px参数必须设置。
  4. per_channel

    • 类型:布尔值(TrueFalse)|浮点数。
    • 描述
      • per_channelTrue,则RGB图像的每个像素位置所对应的三个通道像素值可能不会同时替换为盐噪声方块 ==> RGB图像会出现彩色失真;
      • per_channelFalse,则RGB图像的每个像素位置所对应的三个通道像素值会同时替换为盐噪声方块;
      • per_channel为区间[0,1]的浮点数,假设per_channel=0.6,那么对于60%的图像,per_channelTrue;对于剩余的40%的图像,per_channelFalse
  5. min_size

    • 类型:整数
    • 描述:考虑到错误地设置size_percentsize_px参数会导致整个图像都被替换成盐噪声,因此通过设置min_size来确保最大的噪声方块不至于太大。
  6. seed

    • 类型:整数|None
    • 描述:用于设置随机数生成器的种子。如果提供了种子,则结果将是可重复的。默认值为None,表示随机数生成器将使用随机种子。
  7. name

    • 类型:字符串或None
    • 描述:用于标识增强器的名称。如果提供了名称,则可以在日志和可视化中识别该增强器。默认值为None,表示增强器将没有名称。

示例代码

  1. 使用不同的p
import cv2
import imgaug.augmenters as iaa
import matplotlib.pyplot as plt

# 读取图像
img_path = r"D:\python_project\lena.png"
img = cv2.imread(img_path)
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 创建数据增强器
aug1 = iaa.CoarseSalt(p=0.2, size_px=3, size_percent=None, per_channel=False, min_size=3, seed=0)
aug2 = iaa.CoarseSalt(p=0.5, size_px=3, size_percent=None, per_channel=False, min_size=3, seed=0)
aug3 = iaa.CoarseSalt(p=0.8, size_px=3, size_percent=None, per_channel=False, min_size=3, seed=0)

# 对图像进行数据增强
Augmented_image1 = aug1(image=image)
Augmented_image2 = aug2(image=image)
Augmented_image3 = aug3(image=image)

# 展示原始图像和数据增强后的图像
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
axes[0][0].imshow(image)
axes[0][0].set_title("Original Image")
axes[0][1].imshow(Augmented_image1)
axes[0][1].set_title("Augmented Image1")
axes[1][0].imshow(Augmented_image2)
axes[1][0].set_title("Augmented Image2")
axes[1][1].imshow(Augmented_image3)
axes[1][1].set_title("Augmented Image3")
plt.show()

运行结果如下:

imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!),数据增强指南,机器学习,深度学习,python
图1 原图及数据增强结果可视化(使用不同的p参数)

可以从图1看到:

  • p参数设置的越接近1.0时,图像增强后的新图像将会出现更多的盐噪声方块。
  • 由于size_px为3,且RGB图像的宽和高都接近300,因此每个盐噪声方块的尺寸都接近(100, 100) ==> 先把RGB图像分为9宫格,即9个相同大小的区域,再根据p确定将多少个区域替换为盐噪声方块。
  1. 使用不同的size_px
import cv2
import imgaug.augmenters as iaa
import matplotlib.pyplot as plt

# 读取图像
img_path = r"D:\python_project\lena.png"
img = cv2.imread(img_path)
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 创建数据增强器
aug1 = iaa.CoarseSalt(p=0.5, size_px=3, size_percent=None, per_channel=False, min_size=3, seed=0)
aug2 = iaa.CoarseSalt(p=0.5, size_px=6, size_percent=None, per_channel=False, min_size=3, seed=0)
aug3 = iaa.CoarseSalt(p=0.5, size_px=10, size_percent=None, per_channel=False, min_size=3, seed=0)

# 对图像进行数据增强
Augmented_image1 = aug1(image=image)
Augmented_image2 = aug2(image=image)
Augmented_image3 = aug3(image=image)

# 展示原始图像和数据增强后的图像
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
axes[0][0].imshow(image)
axes[0][0].set_title("Original Image")
axes[0][1].imshow(Augmented_image1)
axes[0][1].set_title("Augmented Image1")
axes[1][0].imshow(Augmented_image2)
axes[1][0].set_title("Augmented Image2")
axes[1][1].imshow(Augmented_image3)
axes[1][1].set_title("Augmented Image3")
plt.show()

运行结果如下:

imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!),数据增强指南,机器学习,深度学习,python
图2 原图及数据增强结果可视化(使用不同的size_px参数)

可以从图2看到:

  • size_px参数设置的越大时,增强后的新图像的每个盐噪声方块的尺寸会越小。
    • size_px=3时,由于RGB图像的宽和高都接近300,因此每个盐噪声方块的尺寸都接近(100, 100) ==> 先把RGB图像分为9宫格,即9个相同大小的区域,再根据p确定将多少个区域替换为盐噪声方块。
    • size_px=6时,由于RGB图像的宽和高都接近300,因此每个盐噪声方块的尺寸都接近(50, 50) ==> 先把RGB图像分为36宫格,即36个相同大小的区域,再根据p确定将多少个区域替换为盐噪声方块。
    • size_px=10时,由于RGB图像的宽和高都接近300,因此每个盐噪声方块的尺寸都接近(30, 30) ==> 先把RGB图像分为100宫格,即100个相同大小的区域,再根据p确定将多少个区域替换为盐噪声方块。
  1. 使用不同的size_percent
import cv2
import imgaug.augmenters as iaa
import matplotlib.pyplot as plt

# 读取图像
img_path = r"D:\python_project\lena.png"
img = cv2.imread(img_path)
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 创建数据增强器
aug1 = iaa.CoarseSalt(p=0.5, size_px=None, size_percent=0.02, per_channel=False, min_size=3, seed=0)
aug2 = iaa.CoarseSalt(p=0.5, size_px=None, size_percent=0.05, per_channel=False, min_size=3, seed=0)
aug3 = iaa.CoarseSalt(p=0.5, size_px=None, size_percent=0.1, per_channel=False, min_size=3, seed=0)

# 对图像进行数据增强
Augmented_image1 = aug1(image=image)
Augmented_image2 = aug2(image=image)
Augmented_image3 = aug3(image=image)

# 展示原始图像和数据增强后的图像
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
axes[0][0].imshow(image)
axes[0][0].set_title("Original Image")
axes[0][1].imshow(Augmented_image1)
axes[0][1].set_title("Augmented Image1")
axes[1][0].imshow(Augmented_image2)
axes[1][0].set_title("Augmented Image2")
axes[1][1].imshow(Augmented_image3)
axes[1][1].set_title("Augmented Image3")
plt.show()

运行结果如下:

imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!),数据增强指南,机器学习,深度学习,python
图3 原图及数据增强结果可视化(使用不同的size_percent参数)

可以从图3看到:

  • size_percent参数设置的越大时,增强后的新图像的每个盐噪声方块的尺寸会越小(size_percent和噪声方块尺寸的关系见size_percent的参数描述)。
    • size_percent=0.02时,每个盐噪声方块的尺寸都接近(50, 50),根据p确定将多少个区域替换为盐噪声方块。
    • size_percent=0.05时,每个盐噪声方块的尺寸都接近(20, 20),根据p确定将多少个区域替换为盐噪声方块。
    • size_percent=0.1时,每个盐噪声方块的尺寸都接近(10, 10),根据p确定将多少个区域替换为盐噪声方块。
  1. per_channel设置为True
import cv2
import imgaug.augmenters as iaa
import matplotlib.pyplot as plt

# 读取图像
img_path = r"D:\python_project\lena.png"
img = cv2.imread(img_path)
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 创建数据增强器
aug1 = iaa.CoarseSalt(p=0.5, size_px=None, size_percent=0.02, per_channel=True, min_size=3, seed=0)
aug2 = iaa.CoarseSalt(p=0.5, size_px=None, size_percent=0.05, per_channel=True, min_size=3, seed=0)
aug3 = iaa.CoarseSalt(p=0.5, size_px=None, size_percent=0.1, per_channel=True, min_size=3, seed=0)

# 对图像进行数据增强
Augmented_image1 = aug1(image=image)
Augmented_image2 = aug2(image=image)
Augmented_image3 = aug3(image=image)

# 展示原始图像和数据增强后的图像
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
axes[0][0].imshow(image)
axes[0][0].set_title("Original Image")
axes[0][1].imshow(Augmented_image1)
axes[0][1].set_title("Augmented Image1")
axes[1][0].imshow(Augmented_image2)
axes[1][0].set_title("Augmented Image2")
axes[1][1].imshow(Augmented_image3)
axes[1][1].set_title("Augmented Image3")
plt.show()

运行结果如下:

imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!),数据增强指南,机器学习,深度学习,python
图4 原图及数据增强结果可视化(per_channel设置为True)

可以从图4看到:图像增强后的新图像将会出现彩色失真(不再是盐噪声)。
原因:当per_channel设置为True时,RGB的三个通道会独立进行处理,不一定能够同时替换为盐噪声块。

注意事项

  1. p的选择p参数决定了一副图像盐噪声的强度。较大的p值可能会导致新图像出现严重失真。需要根据具体场景选择合适的p
  2. size_px的选择size_px参数决定了盐噪声块的大小。错误地设置size_px值可能会导致原图完全被替换成盐噪声图像。需要根据具体场景选择合适的size_px
  3. size_percent的选择size_percent参数决定了盐噪声块的大小。错误地设置size_percent值也可能会导致原图完全被替换成盐噪声图像。需要根据具体场景选择合适的size_percent
  4. size_px和size_percent:若size_percentNone,则size_px参数必须设置;若size_pxNone,则size_percen参数必须设置;
  5. **随机性和可复现性(seed)**:如果需要可复现的结果,应该设置seed参数为一个固定的整数值。这将初始化随机数生成器,使得每次运行增强操作时都能得到相同的结果;
  6. 与其他增强操作的组合iaa.CoarseSalt可以与其他imgaug增强操作组合使用,以创建更复杂的增强管道。在组合多个增强操作时,应注意它们的顺序,因为不同的顺序可能会导致不同的最终效果。
  7. min_size的设置:合理地设置min_size可以预防因为错误地设置size_px参数或者size_percent参数导致原图被完全替换为盐噪声的问题。
  8. 谨慎设置per_channel参数:当per_channel设置为True时,RGB的三个通道会独立进行处理,导致出现彩色噪声块,并非常规的盐噪声块。

总结

iaa.CoarseSaltimgaug库中的一个图像增强方法,用于向图像中添加粗糙的盐噪声。相比于iaa.Salt,它的噪声颗粒更大,能够模拟更为粗糙的噪声模式。以下是该方法的总结:

  1. 作用:通过添加大范围的噪声块,模拟图像在恶劣条件下的噪声模式,或者用于创造特殊的艺术效果。

  2. 参数

    • p:定义了像素被替换为盐噪声(白色)的概率。
    • size_px:可用于定义噪声块的大小。
    • size_percent:可用于定义噪声块的大小。
    • per_channel:决定是否对每个通道独立地应用噪声。
    • min_size:定义噪声块的最小大小。
    • seed:用于设置随机数生成器的种子,以确保结果的可重复性。
    • name:增强器的名称。
  3. 用途

    • 增强大图像的视觉效果:在处理大图像时,通过添加大范围的噪声块来增强图像的细节和纹理。
    • 模拟恶劣天气条件下的图像:模拟由于恶劣天气(如雾、沙尘暴等)导致的较大范围的噪声干扰。
    • 创造艺术效果:通过控制噪声的大小和密度,在图像中创造特殊的艺术效果。

小结

imgaug是一个顶级的图像增强库,具备非常多的数据增强方法。它为你提供创造丰富多样的训练数据的机会,从而显著提升深度学习模型的性能。通过精心定制变换序列和参数,你能灵活应对各类应用场景,使我们在处理计算机视觉的数据增强问题时游刃有余。随着深度学习的持续发展,imgaug将在未来持续展现其不可或缺的价值。因此,明智之举是将imgaug纳入你的数据增强工具箱,为你的项目带来更多可能性。

参考链接


结尾

亲爱的读者,首先感谢抽出宝贵的时间来阅读我们的博客。我们真诚地欢迎您留下评论和意见,因为这对我们来说意义非凡。
俗话说,当局者迷,旁观者清。的客观视角对于我们发现博文的不足、提升内容质量起着不可替代的作用。
如果您觉得我们的博文给您带来了启发,那么,希望能为我们点个免费的赞/关注您的支持和鼓励是我们持续创作的动力
请放心,我们会持续努力创作,并不断优化博文质量,只为给带来更佳的阅读体验。
再次感谢的阅读,愿我们共同成长,共享智慧的果实!文章来源地址https://www.toymoban.com/news/detail-793362.html

到了这里,关于imgaug库指南(26):从入门到精通的【图像增强】之旅(万字长文!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Nuxt.JS实战指南:从入门到精通的练习之旅

    官网:https://www.nuxtjs.cn/ SEO:搜索引擎优化 1.1如何进行搜索引擎优化? 多页面 Title、描述、 网站内容 1.2-预渲染 1.2.1-预渲染图解 1.2.2-如何使用? (1)vue项目中安装prerender-spa-plugin npm install prerender-spa-plugin -S (2)vue.config.js进行配置 (3)修改Title、描述、:v

    2024年02月14日
    浏览(88)
  • C#串口通信从入门到精通(26)——多个串口多个线程发送数据和接收数据

    我们在开发串口程序的过程中有时候会遇到多个串口,并且多个串口也需要在多个线程进行操作,本文就来讲解如何实现多个串口在多线程下的安全发送与接收。 我们首先使用虚拟串口助手虚拟COM1、COM2这一对串口;COM3、COM4这一对串口,然后使用代码操作COM1,然后打开一个

    2024年02月11日
    浏览(63)
  • 物理世界的互动之旅:Matter.js入门指南

    戴尬猴,我是德育处主任 欢迎来到《物理世界的互动之旅:Matter.js入门指南》。 本文将带您探索 Matter.js ,一个强大而易于使用的 JavaScript 物理引擎库。 我将介绍 Matter.js 的基本概念,包括引擎、世界、物体和约束等。 本文还提供丰富的代码示例,帮助各位工友更好地理解

    2024年02月08日
    浏览(47)
  • 2023年的深度学习入门指南(26) - 在自己电脑上运行通义千问7b模型

    通过量化,通义千问4位量化的模型大小为5.86G,可以在3060等小于16G的家用GPU上也可以运行起来。 通义千问7b提供了4位量化好的Qwen/Qwen-7B-Chat-Int4模型,我们直接调用就好。 首先安装依赖包: 如果你是Linux环境的话,可以安装下Flash-Attention来加速: Windows下暂时还用不了,这个

    2024年02月10日
    浏览(49)
  • 【30天精通Zabbix:从入门到实战的全方位监控之旅】第1天:初探Zabbix:开源监控系统的王者

    🌟 热烈欢迎 踏上这30天Zabbix学习之旅的每一位朋友!能在这里和大家相聚,我真的感到非常开心与期待!🎉 🎈 今天,我们将共同启程,去探寻在开源监控领域中独领风骚的王者——Zabbix。不论您是维护系统稳定的管理员、还是日夜兼程保障运行的运维工程师,又或是对监

    2024年03月19日
    浏览(49)
  • 【SpringMVC】从入门到精通的全面指南

    目录 一、什么是SpringMVC 二、SpringMVC的请求流程 三、SpringMVC的优点 四、Spring MVC的主要组件 五、SpringMVC常用注解 六、入门案例演示 6.1.添加pom.xml 6.2.创建spring-mvc.xml 6.3.配置web.xml 6.4.SpringMVC配置Web 6.5.JSP页面编写  七、扩展 7.1.SpringMVC框架中乱码问题 7.1.静态资源处理 ​ Spring

    2024年02月09日
    浏览(43)
  • 前端学习路线指南:从入门到精通【①】

    作为一个前端开发者,学习前端技术是必不可少的。然而,由于前端领域的广阔和不断演进的技术栈,对于初学者来说可能会感到困惑。本篇文章将为你提供一个清晰的前端学习路线,帮助你系统地掌握前端开发技能,并成为一名优秀的前端工程师。 HTML和CSS基础 在开始前端

    2024年02月08日
    浏览(52)
  • 从入门到精通:Git版本控制系统完全指南

    💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】 🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】 💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 Git是一个强大的版本控制系统,它可以帮助开发者轻松地管理代码版本、协作开

    2023年04月09日
    浏览(52)
  • 一文读懂SpringMVC:从入门到精通的全面指南

    目录 一、什么是SpringMVC 二、SpringMVC的请求流程 三、SpringMVC的优点 四、Spring MVC的主要组件 五、SpringMVC常用注解 六、入门案例演示 6.1.添加pom.xml 6.2.创建spring-mvc.xml 6.3.配置web.xml 6.4.SpringMVC配置Web 6.5.JSP页面编写  七、扩展 7.1.SpringMVC框架中乱码问题 7.1.静态资源处理 ​ Spring

    2024年02月09日
    浏览(42)
  • Python单元测试之道:从入门到精通的全面指南

    在这篇文章中,我们会深入探讨Python单元测试的各个方面,包括它的基本概念、基础知识、实践方法、高级话题,如何在实际项目中进行单元测试,单元测试的最佳实践,以及一些有用的工具和资源 测试是软件开发中不可或缺的一部分,它能够帮助我们保证代码的质量,减少

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包